GitHub Actions security¶
CI should verify project health without granting unnecessary write access.
Baseline posture¶
- Default workflow permissions are read-only.
- Checkout does not persist credentials unless a job needs to push.
- The pull request labeler uses
pull_request_targetwithout checkout and only receives the permission needed to add existing pull request labels. - Workflow actions use carefully versioned refs and Dependabot updates. The
.github/zizmor.ymlpolicy records this choice and disables only zizmor's SHA-pinning audit until the project adopts full action SHA pinning. - Scheduled audits are separated from normal pull request validation.
- Documentation deployment uses the
github-pagesenvironment withpages: writeand OIDC only in the deployment job. - Package publishing uses the
pypienvironment and PyPI Trusted Publishing instead of long-lived publishing tokens. - Release artifacts are attested with GitHub artifact attestations before they are published.
- Docker images are built in a dedicated workflow, scanned with Trivy, and only
pushed from non-pull-request events with
packages: write. - Artifacts should be limited to build outputs such as distributions, container images, SBOM files, and attestation metadata.
Pull requests¶
Avoid workflows that run untrusted pull request code with repository write tokens. If a workflow needs elevated permissions, isolate it from arbitrary code execution and document why the permission is needed.
Maintenance¶
Run actionlint and zizmor locally with:
make workflow-lint
Keep action versions current as part of dependency maintenance.