Instiq
Chapter 5 · Secure and Optimize Automation·v1.0.0·Updated 6/15/2026·~17 min

What's changed: New GH-200 Chapter 5 (security best practices = script-injection mitigation, GITHUB_TOKEN least privilege vs PAT, OIDC cloud federation, SHA pinning/trustworthy actions/usage policies, attestations/provenance (SLSA), environment approval gates; performance/cost optimization = actions/cache, retention (REST API), matrix size/max-parallel, concurrency+cancel-in-progress, paths/branches filters, if conditions, runner sizing)

5.1Security Best Practices

Key points

Understand mitigating script injection, the GITHUB_TOKEN lifecycle and least privilege vs PATs, OIDC for cloud federation (eliminating long-lived secrets), pinning third-party actions to SHAs and choosing trustworthy actions with usage policies, artifact attestations/provenance, and environment approval gates.

CI/CD touches source code, secrets, and production, making it a frequent attack target. GH-200’s final domain tests designing workflows securely. The guiding principles are least privilege, run only trusted code, and hold no long-lived secrets.

5.1.1Mitigating script injection

Script injection happens when untrusted input like a PR title, issue body, or branch name is embedded directly into a run: shell command—an attacker putting a malicious command in ${{ github.event.issue.title }} would have it executed on the runner. Mitigations: don’t expand untrusted values directly in run: (put them in an intermediate environment variable and use them quoted as "$VAR"), validate/sanitize inputs, grant least privilege, and prefer vetted actions over inline scripts where possible.

5.1.2GITHUB_TOKEN least privilege vs PAT

The GITHUB_TOKEN issued per run is ephemeral and scoped, expiring when the job ends. Use the permissions: key to set least privilege (e.g., contents: read) and elevate only jobs needing writes. By contrast, a personal PAT is long-lived and often broadly scoped, so avoid routine use in workflows; when required, store it in a secret with the minimum scope. The rule: "GITHUB_TOKEN first; only when insufficient, a least-scope alternative credential."

5.1.3Cloud federation with OIDC

When deploying to AWS, Azure, GCP, etc., storing long-lived cloud credentials in secrets is leak-prone. Instead, OIDC (OpenID Connect) has the workflow obtain a short-lived token (id-token permission) per run that the cloud trusts to issue temporary credentials. This eliminates long-lived secrets and lets you scope trust finely by repo/branch/environment. The standard pattern is granting permissions: id-token: write and configuring a trust policy on the cloud side.

5.1.4Trustworthy actions and provenance

Third-party actions are part of the supply chain. Choose trustworthy (verified) actions, pin to a commit SHA, and govern with org usage policies (allow/deny lists) (Chapter 4). Additionally, generate and verify artifact attestations / provenance to prove "which workflow/commit produced an artifact," strengthening supply-chain integrity under frameworks like SLSA. Verifying attestations at deploy time prevents tampered artifacts from slipping in.

5.1.5Environment approval gates

Protect changes to production with environment protection rules—approval by required reviewers, a wait timer, branch restrictions on deployable branches, and environment-scoped secrets (seen in Chapter 1). This enforces "production deploys only after human approval," preventing mis-deploys and unauthorized changes. Approval gates combine with least privilege, OIDC, and SHA pinning to form defense in depth.

Exam point

Common: (1) Script injection = don’t inline untrusted input into run: → put it in an env var and quote it, validate, least privilege, vetted actions. (2) GITHUB_TOKEN is ephemeral/scoped → least privilege via permissions; avoid long-lived PATs. (3) Cloud federation via OIDC (id-token: write) eliminates long-lived secrets. (4) Third-party = SHA pinning + usage policies; artifacts = attestations/provenance (SLSA). (5) Production = environment approval gates (required reviewers).

Warning

Watch out: (1) Expanding ${{ github.event.* }} directly into run: is dangerous—route via an env var and quote it. (2) Omitting permissions may grant a broad default—scope explicitly. (3) OIDC exists to "hold no long-lived secrets"—don’t confuse it with the old way of putting PATs/access keys in secrets. (4) pull_request_target runs in the base context with stronger permissions—dangerous combined with untrusted fork code. (5) SHA pinning is moot if the action itself is malicious—choose trustworthy publishers.

Diagram of least privilege, OIDC, SHA pinning/attestations, and approval gates.
Layer multiple measures

5.1.6Section summary

  • Script-injection mitigation = route untrusted input via env var + quoting, validate, least privilege, vetted actions
  • GITHUB_TOKEN least privilege via permissions (ephemeral/scoped); avoid long-lived PATs
  • Cloud federation via OIDC (id-token: write) eliminates long-lived secrets and scopes trust finely
  • Third-party via SHA pinning + usage policies; artifacts via attestations/provenance; production via approval gates

Sign in to track progress — Log in.

Quick check

(just a quick review)

Q1. A workflow embeds the PR title directly into a run: shell command. What is the main risk and the fix?

Q2. You must deploy to AWS from a workflow without storing long-lived access keys in secrets. What is recommended?

Q3. Which is the safest design for a workflow’s GITHUB_TOKEN permissions?

Q4. You want to verify at deploy time that a built artifact came from a legitimate workflow and commit. What do you use?

Q5. Which mechanism enforces that production deploys run only after approval by specific reviewers?

Q6. Which combination is correct for using third-party actions safely?

Check your understandingPractice questions for Chapter 5: Secure and Optimize Automation

Keep track of your progress

The full study guide is free to read. Sign up free to practice with the question bank, track what you have read, review your mistakes, and highlight passages.