Back to Blog

CI/CD and GitHub Actions: Secrets and Supply-Chain Controls

September 13, 2026 8 min read
CI/CD and GitHub Actions: Secrets and Supply-Chain Controls
Last updated:

Source review: 13 September 2026. The procedures and tables below are proposed assessment practices. References support the technical behavior and source recommendations; they do not imply that a source mandates this exact scope or record format.

CI/CD systems turn source-code changes into deployed software, which makes them a high-value trust boundary. A workflow can read source, download dependencies, use cloud credentials, sign artifacts, publish packages, and deploy services. In GitHub Actions, the question is not merely whether a repository is private. It is which event can trigger which workflow, what code the runner executes, which identity is available, and where the resulting artifact is trusted. 1

Hardening should preserve a usable delivery process. The controls below focus on reducing unnecessary authority, making trusted inputs explicit, and ensuring that a compromised pull request or dependency cannot silently become a production deployment. They are defensive review priorities, not instructions for misuse. 1

Inventory workflows as privileged automation

Start with an inventory of repositories, workflow files, reusable workflows, composite actions, self-hosted runners, environments, secrets, variables, deployment targets, package registries, cloud roles, signing keys, and external actions. Add the workflow trigger and effective permissions to the inventory. A release workflow invoked manually has a different risk profile from one triggered by a pull request, issue comment, repository dispatch, or a change in another repository. 1

For each workflow, identify the code that can influence execution. This includes the checked-out repository revision, pull-request content, scripts, configuration files, dependency manifests, build containers, and referenced actions. A workflow that exposes a deployment credential must not execute untrusted contribution code in the same trust context. Review reusable workflows too; calling a centrally maintained workflow can concentrate risk as well as improve consistency. 1

Create an owner and review cadence for each workflow. Disabled or experimental files deserve attention because they can be re-enabled later with old permissions or unpinned actions. A concise inventory makes it possible to find workflows that retain broad write permissions after their original purpose has changed. 1

Use short-lived, scoped credentials

Prefer workload identities and short-lived tokens over long-lived cloud access keys stored as repository secrets. Configure the workflow identity to receive only the permissions needed for its single job. In GitHub Actions, set the default GITHUB_TOKEN permissions to read-only where possible and grant specific write permissions at workflow or job level only when required. 1

Separate build, publish, and deploy roles. A test job should not receive the same credentials as a production release job. Protect production environments with required reviewers, branch or tag restrictions, and a clear deployment owner. Where supported, use federated identity between GitHub Actions and the cloud provider so a job obtains a short-lived credential subject to repository, branch, environment, and workflow conditions. 1 2 3

Repository, organization, and environment secrets should be reviewed for ownership, scope, last use, rotation process, and replacement path. Do not place production secrets in broadly accessible repository settings just because a workflow might need them. Use environment-scoped secrets and protected deployment environments for credentials that must reach production. Masking in logs is useful but is not an authorization control; a workflow that can read a secret should be treated as able to misuse it. 1

Deployment-identity control record

Follow one deployment path from an approved source revision to the target role or service identity. The table below is a review record, not a production configuration. It deliberately omits live role names, cloud-account identifiers, and trust values. 1

Control point Required decision or evidence Failure the control is intended to limit
Trigger and trusted reference Record the event, branch or tag rule, approving path, and the exact source revision used for deployment A release job runs code that did not pass the intended review path
Workflow token Set minimal GITHUB_TOKEN permissions and record any job-level elevation with its purpose A routine job can write repository state or alter release settings unnecessarily
Federated deployment identity Restrict OIDC trust using the issuer, audience, and claims appropriate to the cloud provider, repository, reference, and protected environment A different repository or workflow assumes the deployment role
Protected environment Record required reviewers, branch or tag restrictions, and the deployment owner A workflow reaches production without the agreed approval boundary
Artifact hand-off Link the deployable artifact to the approved source revision and controlled build A deployment substitutes an unreviewed or unrelated artifact
Replacement and recovery Document how to disable the workflow, revoke access, rotate any residual credential, and verify the new identity path An exposed or over-privileged identity remains usable after response begins

OIDC can remove the need to store a long-lived cloud secret in GitHub, but it does not remove the need to verify every trust condition and the effective permissions of the assumed cloud role. 1 2 3

Treat third-party actions and dependencies as code

Every external action is code executed in the build environment. Pin actions to reviewed full-length commit SHAs rather than moving tags, and maintain an allowlist or documented approval process for permitted publishers. Pinning narrows change risk but does not prove the action is safe, so review the action’s permissions, network behavior, maintenance status, and the data it receives. 1

The same discipline applies to package dependencies, build images, setup scripts, and release tools. Use lockfiles where the ecosystem supports them, preserve dependency review in pull requests, and require human review for changes that affect release configuration or dependency sources. Generate and retain software bills of materials and build metadata when appropriate for the product’s distribution model. 1

Provenance is most valuable when a consumer can verify it. Define which build environment, source revision, approval path, and signing identity are trusted for a release. Keep signing keys or signing authority separate from ordinary test jobs. If the organization signs artifacts, the release policy should prevent arbitrary workflow changes from invoking the signer. 1

Design safe pull-request automation

Pull requests are collaboration inputs, not automatically trusted code. Review the trigger semantics for every workflow that runs in response to pull requests or comments. Use a restricted workflow context for untrusted contributions and do not make repository or deployment secrets available to it. Checks that need privileged access should operate on reviewed, trusted code or in an isolated process with narrowly scoped data. 1

Avoid patterns that combine untrusted checkout content with a privileged token or an environment that can deploy. The danger may be indirect: a build command, test configuration, package script, or generated configuration file can influence the runner. Model the job as a machine executing repository-controlled instructions, because that is what it is. 1

Use branch protection and required review for workflow files, deployment manifests, reusable workflows, and infrastructure code. CODEOWNERS identifies the relevant reviewers; their approval is enforced only when branch protection requires code-owner review. Protect the CODEOWNERS file and the applicable protection rules, and give the review group enough independence to catch mistakes. Ensure that merge queues, release branches, and automated dependency updates follow the same control model. 1 4

Secure runners and artifacts

GitHub-hosted runners reduce operational maintenance, while self-hosted runners may be necessary for private network access, specialized hardware, or licensing. Self-hosted runners require stronger lifecycle controls: isolate them by trust level, prevent a low-trust repository from reaching a production-capable runner, apply operating-system updates, restrict outbound access where feasible, and remove workspace and credential material between jobs. 1

Runner labels schedule jobs on matching runners; they are not access boundaries. Enforce access through repository identity, runner registration and identity, runner-group access policies, and the permissions available to the runner. Review who can add a runner, assign it to repositories, change labels, and edit its network access. Do not assume a runner is clean because the last workflow succeeded. Treat it as an execution environment with software, caches, and data that need a documented reset model. 1 5 6

Artifacts must also have defined integrity and retention rules. Limit who can upload, download, promote, or deploy them. Use separate artifact names and repositories for untrusted build outputs and release candidates. A deployment should consume an artifact that can be traced to an approved source revision and controlled build process, rather than rebuilding arbitrary source at deployment time. 1

Monitoring, review, and response

Send GitHub audit events and workflow logs to the organization’s monitoring platform where feasible. Review changes to workflow files, secrets, environments, runner groups, organization policies, repository permissions, and third-party action references. Alerting should prioritize changes that expand execution authority, such as a new deployment environment approver, broader token permissions, a new self-hosted runner, or a modified protected branch rule. 1

Keep an incident procedure for suspected CI/CD credential exposure or unauthorized workflow change. It should identify how to disable a workflow, revoke or rotate affected credentials, quarantine a runner, identify artifacts produced in the affected window, and communicate with deployment owners. Run a controlled exercise so that these actions do not need to be invented during a release outage. 1

Remediation sequence

First map workflows and remove unused secrets, permissions, runners, and action references. Next set restrictive default token permissions, move production access into protected environments, and replace long-lived cloud keys with constrained short-lived identity where supported. Pin and review external actions, protect workflow and deployment files, and split untrusted pull-request checks from privileged release work. 1

Then establish artifact provenance, runner isolation, central logging, and a recovery procedure. A retest should verify effective permissions for each trigger, confirm that protected jobs cannot consume unreviewed code, and trace a release artifact from source revision to deployment approval. 1

FAQ

Does a private repository make its workflows safe?

No. Private repositories can still receive compromised accounts, unsafe dependencies, incorrect permissions, and insider mistakes. The workflow’s trigger and credentials determine its practical authority. 1

Is secret masking sufficient protection?

No. Masking reduces accidental display in logs. It does not prevent code that receives the secret from sending it elsewhere or using it for an unauthorized action. 1

Must every action be maintained in-house?

No. External actions can be appropriate when their source, maintenance, version pinning, permissions, and update process are understood and reviewed. 1

Internal links: Cloud expertise · AWS context · Container context · Preparation resource


Vid Grosek

Vid Grosek

Ethical Hacker & Penetration Tester

I help Slovenian companies discover security vulnerabilities before attackers do. With 18+ years of experience in cybersecurity.

All Posts

Comments

No comments yet. Be the first!

Leave a Comment

Enjoyed this article?

Subscribe to the newsletter for monthly security insights.

Subscribe