Skip to content

GH-200 · Domain 5: Secure and optimize automation · 14% of the exam

Task 5.1: Implement security best practices

Approval gates, trustworthy actions, script injection, GITHUB_TOKEN permissions, OIDC federation to cloud providers, SHA pinning and artifact attestations.

Study it

  • Script injection, least-privilege tokens, pinning and attestations

    Lesson coming

  • OIDC federation to cloud providers instead of stored cloud keys

    Partly covered by: Shared Responsibility & IAM

Sample questions

Try each one before opening the answer. Every option is explained, with the GitHub documentation page that proves it.

Question 1 · choose 1

A pull_request_target workflow runs title="${{ github.event.pull_request.title }}" in a bash step to check the title format. A security review flags it. The check must stay an inline script, and the job needs its write token for a later labeling step. What change removes the injection risk?

  1. AWrap ${{ github.event.pull_request.title }} in single quotes instead of double quotes
  2. BSet env: TITLE: ${{ github.event.pull_request.title }} on the step and use "$TITLE" in the script
  3. CPass the title through toJSON() inside the run script
  4. DReduce the job's permissions to read-only
Show the answer and why
  • AWrap ${{ github.event.pull_request.title }} in single quotes instead of double quotes

    Incorrect

    The expression is still pasted into the script before it runs, so a title with a quote breaks out the same way.

  • BSet env: TITLE: ${{ github.event.pull_request.title }} on the step and use "$TITLE" in the script

    Correct

    The value then reaches the shell as a variable in memory instead of becoming part of the generated script.

  • CPass the title through toJSON() inside the run script

    Incorrect

    The value is still substituted into the script text before the shell runs.

  • DReduce the job's permissions to read-only

    Incorrect

    That limits the damage, but the injection remains and the labeling step needs write access.

Expressions in run are evaluated and substituted before the shell script runs, so attacker-controlled values such as a pull request title can inject commands. For inline scripts, GitHub's preferred approach is an intermediate environment variable, which keeps the value out of script generation; passing it to an action as an input is another option.

Question 2 · choose 1

A workflow has five jobs. Only the release job creates a GitHub release; the others build and test. The repository uses the permissive default token. Security wants every job to get only what it needs. What should the workflow declare?

  1. Apermissions: write-all at the top
  2. Bcontents: write at the top
  3. Ccontents: read at the top and contents: write on the release job
  4. DNo permissions key, relying on the repository default for the release job
Show the answer and why
  • Apermissions: write-all at the top

    Incorrect

    That grants every write scope to all five jobs.

  • Bcontents: write at the top

    Incorrect

    Four jobs would get write access they don't need.

  • Ccontents: read at the top and contents: write on the release job

    Correct

    Job-level permissions override the workflow's, so only the release job can write.

  • DNo permissions key, relying on the repository default for the release job

    Incorrect

    The permissive default gives every job write access.

permissions can be set at the top level for all jobs and overridden in a job. Setting read access at the top and granting write only to the job that needs it gives each job the least access, whatever the repository's default.

Question 3 · choose 1

A security policy requires third-party actions to be pinned to an immutable reference, but developers worry they will miss security fixes in those actions. Which approach meets both concerns?

  1. APin each action to its major version tag, such as @v4
  2. BFull-length commit SHAs, with Dependabot version updates for github-actions
  3. CPin to the first seven characters of each commit SHA
  4. DReference each action's default branch and review its new commits every week
Show the answer and why
  • APin each action to its major version tag, such as @v4

    Incorrect

    A tag can be moved, so it isn't an immutable reference.

  • BFull-length commit SHAs, with Dependabot version updates for github-actions

    Correct

    SHAs are immutable, and Dependabot proposes updates to the pinned actions.

  • CPin to the first seven characters of each commit SHA

    Incorrect

    Workflows must use the full-length SHA.

  • DReference each action's default branch and review its new commits every week

    Incorrect

    A branch moves with every commit, so nothing is pinned.

A tag or branch can be moved, while a full-length commit SHA always identifies the same code; abbreviated SHAs aren't accepted. Dependabot version updates keep references to actions and reusable workflows up to date by opening pull requests. Where it can be adopted, GitHub now describes a workflow dependency lockfile as the strongest option.

Question 4 · choose 1

A company's builds already generate artifact attestations, which give SLSA v1.0 Build Level 2. It wants Build Level 3, with consumers able to require that a specific vetted build definition produced each artifact. What should it do?

  1. AAttest each artifact twice, once per job
  2. BAdd an SBOM attestation to every build
  3. CBuild and attest in a shared reusable workflow; verify with --signer-workflow
  4. DSign the binaries with a gpg key stored as a repository secret and publish the signatures
Show the answer and why
  • AAttest each artifact twice, once per job

    Incorrect

    More attestations don't isolate the build process.

  • BAdd an SBOM attestation to every build

    Incorrect

    An SBOM lists dependencies; it doesn't raise the build level.

  • CBuild and attest in a shared reusable workflow; verify with --signer-workflow

    Correct

    A reusable workflow isolates the build, and verification can require that workflow as the signer.

  • DSign the binaries with a gpg key stored as a repository secret and publish the signatures

    Incorrect

    That bypasses provenance attestations entirely.

Artifact attestations alone provide SLSA v1.0 Build Level 2. Building in a reusable workflow shared across the organization isolates the build from the calling workflow and helps meet Build Level 3. gh attestation verify accepts --signer-repo or --signer-workflow to require the reusable workflow that signed.

Question 5 · choose 1

A workflow in octo-org/app must open issues in octo-org/tracker. The GITHUB_TOKEN can't reach that repository. The team wants a credential that isn't tied to a person, expires quickly and can write issues in tracker only. What should the workflow use?

  1. AA fine-grained personal access token limited to tracker
  2. BThe GITHUB_TOKEN with issues: write
  3. Cactions/create-github-app-token with repositories: tracker and permission-issues: write
  4. DA deploy key for octo-org/tracker
Show the answer and why
  • AA fine-grained personal access token limited to tracker

    Incorrect

    It can be scoped well, but it belongs to a person.

  • BThe GITHUB_TOKEN with issues: write

    Incorrect

    The GITHUB_TOKEN is limited to the repository that runs the workflow.

  • Cactions/create-github-app-token with repositories: tracker and permission-issues: write

    Correct

    The app's installation token is short-lived, not personal, and scoped to the listed repository and permission.

  • DA deploy key for octo-org/tracker

    Incorrect

    Deploy keys give Git access, not access to the issues API.

The GITHUB_TOKEN's permissions are limited to the repository that contains the workflow. A GitHub App installation token, created in the workflow with actions/create-github-app-token, is short-lived, isn't tied to a user and can be limited to specific repositories and permissions.

Question 6 · choose 1

A new team member asks what kind of credential the GITHUB_TOKEN in a workflow actually is. What is the answer?

  1. AA personal access token of the user who pushed the commit
  2. BAn SSH deploy key added to the repository
  3. CA long-lived organization-wide token
  4. DAn installation access token of the GitHub App that GitHub installs for Actions
Show the answer and why
  • AA personal access token of the user who pushed the commit

    Incorrect

    It isn't tied to a person.

  • BAn SSH deploy key added to the repository

    Incorrect

    It is used with the API and Git over HTTPS, not as an SSH key.

  • CA long-lived organization-wide token

    Incorrect

    It is created for each job and scoped to one repository.

  • DAn installation access token of the GitHub App that GitHub installs for Actions

    Correct

    Enabling Actions installs a GitHub App, and each job gets one of its installation tokens.

When you enable GitHub Actions, GitHub installs a GitHub App on your repository. The GITHUB_TOKEN is an installation access token for that app, created at the start of each job, limited to the repository that contains the workflow, and also available as github.token.

Question 7 · choose 1

A repository keeps a cloud deployment credential as a repository secret. A contractor is about to get write access so they can push branches. What does GitHub's secure use guidance say about the secret?

  1. AOnly repository administrators can use it in the workflows they write
  2. BThe contractor reaches it only after being added to the secret's own access list
  3. CIt stays out of reach of everyone except the person who created it
  4. DAnyone with write access, the contractor included, has read access to it
Show the answer and why
  • AOnly repository administrators can use it in the workflows they write

    Incorrect

    Any workflow pushed by someone with write access can reference the secret.

  • BThe contractor reaches it only after being added to the secret's own access list

    Incorrect

    Repository secrets have no per-user access list.

  • CIt stays out of reach of everyone except the person who created it

    Incorrect

    Its value isn't shown in the settings, but workflows can still read it.

  • DAnyone with write access, the contractor included, has read access to it

    Correct

    Write access to a repository gives read access to all of its secrets, so each credential should carry only the privileges it needs.

GitHub's secure use reference notes that any user with write access to a repository has read access to all secrets configured in it, so credentials used in workflows should have the least privileges required. Environment secrets protected by required reviewers can't be accessed by a job until a reviewer approves it.

Question 8 · choose 1

An organization disabled GitHub Actions for most repositories, yet Dependabot update jobs still appear as Actions runs in those repositories. Why?

  1. AThe policy takes up to a week to apply
  2. BDependabot jobs bypass Actions policy checks and disablement
  3. CDependabot uses the repositories' own workflow files in .github/workflows
  4. DDependabot runs are billed to GitHub and ignore policies
Show the answer and why
  • AThe policy takes up to a week to apply

    Incorrect

    Policies apply right away.

  • BDependabot jobs bypass Actions policy checks and disablement

    Correct

    When Dependabot is enabled, its jobs always run on GitHub Actions.

  • CDependabot uses the repositories' own workflow files in .github/workflows

    Incorrect

    Dependabot runs dynamic workflows that aren't stored in the repository.

  • DDependabot runs are billed to GitHub and ignore policies

    Incorrect

    Billing has nothing to do with the policy bypass.

If Dependabot is enabled for a repository, its jobs always run on GitHub Actions, bypassing Actions policy checks and disablement at the repository or organization level. GitHub creates a dynamic workflow for each job.

Question 9 · choose 1

A cloud administrator writing trust conditions asks what an OIDC token from GitHub Actions tells the cloud provider. What does it contain?

  1. AThe repository's secrets, encrypted
  2. BA long-lived password for the cloud account
  3. CThe source code of the workflow
  4. DClaims about the job, such as the repository, ref, environment and workflow
Show the answer and why
  • AThe repository's secrets, encrypted

    Incorrect

    The token carries claims, not secrets.

  • BA long-lived password for the cloud account

    Incorrect

    The token is short-lived and holds no cloud password.

  • CThe source code of the workflow

    Incorrect

    The token describes the workflow; it doesn't contain it.

  • DClaims about the job, such as the repository, ref, environment and workflow

    Correct

    Cloud providers use these claims to decide whether to issue access.

Each OIDC token contains standard and custom claims about the job, such as sub, repository, ref, environment and workflow, which a cloud provider's trust conditions check before issuing a short-lived access token.

Practice domain 5 →Practice all domains →