A deploy key in a repository secret is a credential with no expiry, no audience restriction and no record of which run used it.
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: arn:aws:iam::...:role/deploy
aws-region: eu-west-2
# the trust policy is where the actual security is:
# sub: repo:org/name:ref:refs/heads/main
# a workflow on a branch cannot assume the role.
The token exchange is the easy half; the trust policy condition is the half worth reviewing carefully, because a subject claim of repo:org/name:* means any branch and any pull request can assume the role, which is barely better than the stored key. Scoping to the default branch, and to an environment where a reviewer is required, is what makes the difference real.