CI tokens get the permissions the job uses, and nothing else
The default GITHUB_TOKEN can write to the repository, and a test job doesn't need that.
permissions:
contents: read
jobs:
release:
permissions:
contents: write
id-token: writeRead at the top level, write only on the job that publishes. Then a compromised dependency in the test job can't push a tag.
securityci