Domain 6: Manage GitHub Actions (16%) โ
โ Domain 5 ยท Cheatsheet โ
Exam Tip
Domain 6 focuses on administration of GitHub Actions โ not writing workflows. Know how to distribute and control actions, manage runners at the enterprise level, and secure secrets. The "how to run a CI pipeline" is developer knowledge; the "how to govern it" is admin knowledge.
Distributing Actions and Workflows in the Enterprise โ
Admins control which actions can run and how reusable CI/CD logic is shared across the organization.
Controlling Access to Actions โ
Enterprise and org admins can configure which actions are allowed to run:
| Policy | What it allows |
|---|---|
| All actions | Any action from any source (marketplace, third-party, internal) |
| Local actions only | Only actions defined in the same org's repositories |
| Allowed list | Specific actions and/or verified creators (e.g., actions/*, github/*) |
| Disabled | No workflows can run |
Configure at: Enterprise Settings โ Policies โ Actions (applies to all orgs) or Org Settings โ Actions โ General.
Trap
Enterprise-level action policies override org-level settings. If you need to restrict actions uniformly across all orgs, configure at the enterprise level.
Reusable Workflows โ
Reusable workflows let teams define a workflow once and call it from other workflows โ reducing duplication and enforcing standards.
# Calling a reusable workflow
jobs:
call-security-scan:
uses: my-org/shared-workflows/.github/workflows/security-scan.yml@main
with:
environment: production
secrets: inheritKey concepts:
- The called workflow must be in a repo accessible to the caller
secrets: inheritpasses the caller's secrets to the reusable workflow- Reusable workflows must define
workflow_callas a trigger - Enterprise: store shared workflows in a dedicated internal repo (e.g.,
org/shared-workflows)
Naming and Managing Reusable Components โ
Best practices for enterprise reusable workflow management:
- Dedicated repo:
{org}/shared-workflowsโ single source of truth - Naming conventions:
{domain}-{action}.yml(e.g.,security-scan.yml,deploy-staging.yml) - Versioning: Reference workflows by tag or commit SHA, not
@main, for stability - Maintenance: Assign team ownership to the shared-workflows repo with branch protection on
main
Managing Runners โ
Runners are the compute environments where GitHub Actions workflows execute.
GitHub-Hosted vs Self-Hosted Runners โ
| GitHub-Hosted | Self-Hosted | |
|---|---|---|
| Managed by | GitHub | You |
| Cost | Per-minute (included quota + overage) | Your infrastructure costs |
| Setup | None | Configure and register the runner |
| OS options | Ubuntu, Windows, macOS | Any OS (Linux, Windows, macOS, ARM) |
| Network access | Public internet only | Can reach private networks / on-prem resources |
| Isolation | Fresh VM per job | Persistent (unless configured for ephemeral) |
| IP predictability | Dynamic IPs | Static / known IPs |
| Best for | Standard workloads | Custom hardware, private network, on-prem |
Exam Tip
Use self-hosted runners when workflows need to access on-premises resources (databases, artifact servers, private APIs) or when IP allow-listing is required. GitHub-hosted runner IPs are dynamic and cannot be allow-listed reliably.
Self-Hosted Runner Security Risks on Public Repos โ
Critical
Never use self-hosted runners on public repositories. Any GitHub user can fork a public repo and open a PR, triggering a workflow that runs on your self-hosted runner. This could allow arbitrary code execution on your infrastructure.
Mitigation for public repos:
- Use GitHub-hosted runners only
- Or: restrict which workflows trigger on PRs from forks (
pull_request_targetwith care)
Configuring Self-Hosted Runners โ
Steps to register a self-hosted runner:
- Navigate to: Repo/Org/Enterprise Settings โ Actions โ Runners โ New runner
- Download the runner application on the target machine
- Run the configuration script with the provided registration token
- Start the runner service (
./run.shor as a system service)
Configuration options:
- Labels: Assign custom labels (
gpu,large,windows-arm) to target specific runners in workflows (runs-on: [self-hosted, gpu]) - Proxies: Configure
https_proxyandno_proxyenvironment variables for runners behind a corporate proxy - Networking: Ensure the runner can reach
github.com(port 443) and optionally your artifact servers
IP Allow Lists and Self-Hosted Runners โ
- GitHub-hosted runner IPs change dynamically โ internal systems must allow GitHub's IP ranges (published via
api.github.com/meta) - Self-hosted runners use your infrastructure's IPs โ allow-list those specific IPs on internal systems instead
- Enabling IP allow lists on an org restricts which IPs can access the org's APIs โ ensure runner IPs are included
Runner Groups โ
Runner groups let admins organize and control access to self-hosted runners.
What Runner Groups Do โ
- Define which organizations and repositories can use a set of runners
- Restrict enterprise runners to specific orgs (e.g., only the
productionorg can use GPU runners) - Restrict org runners to specific repos (e.g., only the
apirepo can use the high-memory runner)
Managing Runner Groups โ
- Create: Enterprise/Org Settings โ Actions โ Runner groups โ New group
- Move runners: Runners can be moved between groups without re-registering
- Access policy: Set which orgs/repos can use the group
Monitoring and Troubleshooting Self-Hosted Runners โ
| Task | Where / How |
|---|---|
| View runner status | Settings โ Actions โ Runners (Active / Offline / Idle) |
| View runner logs | On the runner machine โ _diag/ folder contains log files |
| Check workflow logs | GitHub Actions tab โ specific run โ job log |
| Update runner | Runner checks for updates automatically; or run ./run.sh with --update |
| Troubleshoot connectivity | Check github.com port 443, proxy config, registration token validity |
GitHub Actions Limits & Quotas (GHEC) โ
These are critical numbers the exam tests โ memorize them.
Job & Workflow Execution Limits โ
| Limit | Value | Notes |
|---|---|---|
| Max job execution time | 6 hours | Single job on a GitHub-hosted runner โ job is cancelled after this |
| Max workflow run time | 35 days | Total time including wait times for approvals and manual gates |
| Max queued time | 24 hours | A job waiting in "Queued" state is automatically cancelled after 24h |
| Max matrix jobs | 256 per run | A single strategy.matrix can generate up to 256 job combinations |
| Max concurrent jobs (Enterprise) | 500 | On standard GitHub-hosted runners for an Enterprise plan |
Workflow File Limits โ
| Limit | Value |
|---|---|
| Max workflow files per repo | No hard limit, but GitHub recommends keeping it manageable |
| Max workflow file size | 512 KB |
| Max reusable workflow nesting | 4 levels deep |
| Max environment protection reviewers | 6 users or teams |
Trap
The 6-hour limit applies to a single job, not the entire workflow. A workflow with multiple sequential jobs can run longer than 6 hours total. But the 35-day cap applies to the entire workflow run including approval wait times.
Exam Tip
If a job exceeds 6 hours, it is cancelled (not failed). The distinction matters for retry logic and status checks. If a queued job sits for 24 hours without a runner picking it up, it is also automatically cancelled.
Encrypted Secrets โ
Secrets are encrypted variables stored in GitHub and injected into workflow environments at runtime.
Secret Scope Levels โ
| Level | Where stored | Who can access |
|---|---|---|
| Repository | Individual repo settings | Workflows in that repo only |
| Environment | Repo environment (e.g., production) | Workflows using that specific environment |
| Organization | Org settings | Workflows in repos the org allows |
| Enterprise | Enterprise settings | Workflows in all orgs in the enterprise |
Creating and Accessing Secrets โ
Creating (UI): Settings โ Secrets and variables โ Actions โ New repository/org/enterprise secret
Accessing in a workflow:
steps:
- name: Use a secret
run: echo "Connecting to DB..."
env:
DB_PASSWORD: ${{ secrets.DB_PASSWORD }}Trap
Secrets are never printed in logs โ GitHub automatically masks values that match a known secret. However, base64-encoding a secret and printing it will bypass masking. Educate developers not to decode secrets in workflow logs.
Organization-Level Secrets โ
- Set in Org Settings โ Secrets and variables โ Actions
- Access policy options: All repositories, Private repositories only, or Selected repositories
- Useful for: shared API keys, deployment credentials used across multiple repos
Repository-Level Secrets โ
- Set in Repo Settings โ Secrets and variables โ Actions
- Available only to workflows in that specific repo
- Take precedence over org-level secrets with the same name
Third-Party Vaults โ
For high-security environments, secrets can be stored externally and retrieved at runtime:
- HashiCorp Vault: Use the
hashicorp/vault-actionto fetch secrets at workflow start - AWS Secrets Manager / Azure Key Vault: Similar pattern using cloud provider actions
- Benefits: Centralized rotation, fine-grained access policies, audit trail outside GitHub
- Pattern: Workflow authenticates to the vault (via OIDC or a stored token), retrieves the secret, uses it in subsequent steps
- name: Import secrets from Vault
uses: hashicorp/vault-action@v3
with:
url: https://vault.example.com
method: jwt
role: github-actions
secrets: |
secret/data/prod db_password | DB_PASSWORDEnvironments and Deployment Protection Rules โ
GitHub Environments add policy controls around deployments.
What Environments Can Enforce โ
- Required reviewers before deployment jobs continue
- Wait timers before deployment begins
- Branch and tag restrictions so only approved refs can deploy
- Custom deployment protection rules via GitHub Apps
Environment Secrets โ
- Environment secrets are available only to jobs that target that environment
- If approvals are required, the job does not receive those secrets until the protection gate passes
Exam Tip
If the question is about protecting production deployments, adding approval gates, or scoping secrets to production only, the answer often involves a GitHub Environment, not just a repository secret.
OIDC for Cloud Authentication โ
GitHub Actions can use OpenID Connect (OIDC) to authenticate to cloud providers without storing long-lived cloud credentials in GitHub.
- The workflow requests an identity token from GitHub
- The cloud provider trusts GitHub as an identity provider
- The workflow exchanges that token for short-lived credentials
Common examples include AWS, Azure, GCP, Vault, and package registries that support trusted publishing.
Exam Tip
If the question is "how do we avoid storing long-lived cloud secrets in GitHub Actions?", the strongest answer is usually OIDC federation.
Domain 6 Quick Quiz
Why should self-hosted runners never be used on public repositories?
(Click to reveal)