Token Permissions and Least Privilege
Applicable Scenarios: The default token (ATOMGIT_TOKEN) for pipelines has repository-level read and write permissions. However, under the principle of least privilege, the token should be restricted to only the minimum permissions required by the job to prevent privilege escalation.
Configuration Description
ATOMGIT_TOKEN Auto-generation
Every time a pipeline runs, AtomGit Action auto-generates the ATOMGIT_TOKEN, which is used for:
- Cloning the code repository
- Pushing build artifacts
- Creating PRs, issue comments
- Managing project resources
The scope of ATOMGIT_TOKEN permissions is controlled by the workflow's permissions field.
Detailed Explanation of the permissions Field
Top-level permissions (default at workflow level):
# Token Permissions and Least Privilege
name: CI Pipeline
permissions:
project: read # Read project information
pr: write # Write operations on PR (create, comment, merge)
issue: read # Read issues
note: write # Write operations on comments/Notes
repository: write # Write operations on the repository (push)
hook: none # No access to Webhooks
Permission Type Mapping
| Permission Domain | read | write | none | Description |
|---|---|---|---|---|
| project | Read project information | Modify project settings | No access | Project metadata operations |
| pr | Read PR | Create/Comment/Merge PR | No access | Pull Request operations |
| issue | Read Issue | Create/Comment Issue | No access | Issue operations |
| note | Read comments | Create comments | No access | General comment operations |
| repository | Clone/Read | Push/Modify repository | No access | Code repository operations |
| hook | Read Webhook | Manage Webhook | No access | Webhook management |
Practical Implementation of the Least Privilege Principle
Principle: Each job should only declare the permissions it needs, without excess.
Example 1: Lint Job That Only Reads the Repository
permissions:
repository: read # Only need to clone code
pr: none # No PR operations
issue: none # No Issue operations
note: none # No comments
project: none # No project information reading
hook: none # No Webhook operations
stages:
- name: lint
jobs:
- name: code-lint
runs-on: {ubuntu-24,x64,slim}
steps:
- run: npm run lint
Example 2: Test Job That Needs to Comment on a PR
permissions:
repository: read # Clone code
pr: write # Comment on the PR with test results
issue: none
note: none
project: none
hook: none
stages:
- name: test
jobs:
- name: report-results
runs-on: {ubuntu-24,x64,small}
steps:
- run: |
pytest
curl -X POST "https://atomgit.com/api/v5/repos/${{ atomgit.repository }}/pulls/${{ atomgit.event.pr.number }}/comments" \
-H "Authorization: token $ATOMGIT_TOKEN" \
-d '{"body": "All tests passed ✅"}'
Relationship Between permissions and ATOMGIT_TOKEN
permissions Configuration | Actual Permissions of ATOMGIT_TOKEN |
|---|---|
permissions not declared | Use the permissions defined in the repository settings |
permissions declared at top level | All jobs inherit the top-level permissions unless overridden at job level |
permissions: {} (empty) | ATOMGIT_TOKEN only has the minimal default permission (repository: read) |
Critical Security Note: When the
pull_requestevent comes from a forked repository,ATOMGIT_TOKENonly hasreadpermissions regardless of howpermissionsare declared. This is a security isolation mechanism of AtomGit Action. If write permissions are needed, use thepull_request_targetevent.