Chapter 34Lesson 01~240 minutes

Enterprise Policies, Allowed Actions, Runner Governance, and Auditability: Core Concepts and Mental Model

Build a mental model for GitHub Actions governance that separates policy inheritance, executable-dependency allowlists, token defaults, runner access, rules, audit evidence and exceptions.

GovernanceAllowed actionsRunner groupsAuditabilityPolicy inheritance

Learning objectives

  • Explain how enterprise, organization and repository policy inheritance bounds workflow execution.
  • Separate action eligibility, token/fork policy, runner-group access, rules/environment controls and audit evidence.
  • Inspect current policy read-only before proposing changes.
  • Explain why full-SHA action enforcement, restrictive permissions and runner governance are complementary controls.
  • Model exceptions as scoped, expiring governance state.

1. The practical problem: governance cannot live in tribal memory

A repository can contain beautifully reviewed workflow YAML and still execute unsafe code, run on an over-trusted machine, or receive more token authority than its authors intended. The reason is that workflow behavior is bounded by policy outside the file: enterprise and organization Actions settings, allowed-action rules, default GITHUB_TOKEN policy, fork controls, runner-group access, environments, rulesets and audit retention all participate in the final execution decision.

This chapter therefore treats governance as an execution control plane, not as a style guide. A secure operating model answers six questions before a job starts: who owns the rule, what scope does it cover, which executable dependencies are allowed, which token capabilities can be granted, which runners may execute the job, and what evidence will prove that an exception or policy change was authorized.

Chapter invariant: repository YAML may request behavior, but it cannot legitimately “override” a deny imposed by a more authoritative enterprise or organization layer. When a policy blocks a workflow, the correct diagnostic question is “which controlling layer denied it?”—not “how can the workflow bypass it?”

2. Mental model: policy → eligible automation → governed execution → evidence

Start with the controlling policy. An enterprise may constrain organizations; an organization may constrain repositories; a repository may choose a still-narrower configuration. The policy determines which external actions or reusable workflows are eligible, whether action references must be immutable, the default token posture, private-fork behavior, and which runner groups or rules can be used. Only after those gates are satisfied does the workflow reach a runner and begin executing steps.

Execution then creates a second class of state: workflow run and attempt identifiers, job conclusions, runner identity, artifacts, environments, deployments and external side effects. Governance is incomplete unless those execution facts can be correlated with the policy revision and exception state that allowed them.

Governed Actions execution path
flowchart TD
  A[Enterprise / organization policy] --> B[Allowed actions + SHA rule]
  A --> C[Default token + fork policy]
  A --> D[Runner-group access]
  A --> E[Rules / environment controls]
  B --> F[Repository workflow revision]
  C --> F
  D --> G[Eligible runner]
  E --> F
  F --> H[Run / attempt / job graph]
  G --> H
  H --> I[Artifacts / deployments / external effects]
  H --> J[Audit + policy evidence]
  J --> K[Exception / review lifecycle]

Every arrow is causal. A full-SHA policy constrains which action reference can execute. A runner-group rule constrains where eligible jobs can run. A token default sets the starting authority, which a workflow should narrow further. Audit records do not themselves prevent execution; they provide evidence that administrators can review and export. An exception changes governance state, so it needs an owner, justification, narrow scope and expiry.

3. The state ledger: define what you are governing before changing it

A governance review becomes auditable when it records state explicitly instead of saying “Actions is locked down.” The following ledger separates configuration from runtime and evidence.

State family What to record Why it matters
Policy ownership Enterprise/org/repository owner; effective scope; inheritance path Explains which layer can tighten or relax a setting.
Executable dependency Action/reusable-workflow owner, repository, path and ref/SHA Identifies exactly what code can execute.
Token and fork Default token mode; explicit job permissions; private-fork settings Shows the credential authority that untrusted or trusted code may receive.
Runner trust Runner group, labels, repository/workflow access, public-repo access Separates scheduling metadata from the machine trust boundary.
Rules/environment Required workflow/ruleset/environments and approvals where available Shows pre-merge or pre-deployment governance distinct from job success.
Evidence Run ID/attempt, policy snapshot, audit event, exception record Lets a reviewer reconstruct why execution was permitted.

Do not collapse these into a single “security setting.” For example, a full-SHA action policy does not make a self-hosted runner safe for public pull requests, and a runner group does not reduce the permissions of GITHUB_TOKEN. Controls are complementary because they govern different state.

4. Inspect first: prove the current policy without changing it

The first operational move is read-only inspection. In a real organization, use the GitHub web settings or authorized read APIs to record the effective action policy, selected-action patterns, token defaults, runner-group access and audit evidence. In this course, the mandatory path uses a local policy snapshot so anyone can practice the same reasoning without an Enterprise account.

# Read-only examples for an authorized organization.
# Never paste an auth header into logs; let gh manage authentication.
ORG=example-lab-org

gh auth status

gh api \
  -H "Accept: application/vnd.github+json" \
  -H "X-GitHub-Api-Version: 2026-03-10" \
  "/orgs/$ORG/actions/permissions/selected-actions"

# A separate endpoint can be used to inspect organization workflow-permission
# defaults when your identity has permission to read those settings.
# Treat 403 as evidence of insufficient administration authority, not as a
# reason to switch to a broader token casually.

A 200 response is evidence about the setting returned by that endpoint; it is not proof that every repository is effectively allowed to run every action. Enterprise inheritance, repository narrowing, workflow references and runner access still matter. Likewise, a 403 is valuable evidence: record the identity and required administrative boundary rather than escalating privileges merely to make a lab command succeed.

5. Allowed actions: control the executable dependency graph

An Actions workflow is a software supply-chain graph. Every uses: line can bring executable code into the runner. GitHub currently supports broad modes such as allowing all actions, allowing only enterprise/organization-owned automation, or allowing owned automation plus selected external actions and reusable workflows. Selected policies can additionally distinguish GitHub-owned actions, Marketplace actions from verified creators, and explicit allow/block patterns.

A “verified creator” label helps establish publisher identity; it is not a substitute for reviewing code, permissions, release provenance or immutable references. The policy should express the organization’s trust decision, while repository reviews still evaluate whether a specific action is appropriate for the job.

# Production-style reference: exact executable revision.
steps:
  - name: Checkout source
    uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

As of the assumptions recorded for this chapter, GitHub can enforce full-length commit-SHA pinning for actions, and that enforcement includes actions authored by GitHub. Reusable workflows are a distinct policy/reference case; GitHub permits them to be referenced by tag, branch or SHA, though a full commit SHA remains the safest stability choice for externally referenced reusable workflows.

6. Token defaults and fork policy: constrain credential authority separately

Allowed code is only half of the trust equation. GITHUB_TOKEN is a per-job installation token whose effective permissions depend on platform defaults, event type, fork restrictions and the workflow’s explicit permissions. Current GitHub guidance favors restrictive defaults and then explicit least privilege at workflow or job scope.

permissions: {}

jobs:
  inspect:
    permissions:
      contents: read
    runs-on: ubuntu-24.04
    steps:
      - run: echo "This job requested only repository read access."

Private-repository fork policy is yet another layer. An organization can control whether fork pull-request workflows run, whether write tokens or secrets are sent, and whether approval is required. A repository cannot legitimately loosen a more restrictive organization or enterprise decision. Public repositories and untrusted pull requests also require special care around self-hosted or privileged runners.

7. Runner groups: scheduling control becomes a machine-trust boundary

A runner label answers “which machines match?” A runner group answers “which repositories and workflows are allowed to use this pool?” That distinction matters because self-hosted and larger runners may have network access, local caches, credentials, static IPs or proximity to production systems that ordinary hosted runners do not.

Current GitHub runner-group controls can restrict access by organization, repository and selected workflow. When workflow access is narrowed, only jobs directly defined in the selected workflow receive that access. This is why a privileged runner group should be treated like a production entitlement, not as a performance setting.

Public repository boundary: GitHub recommends using self-hosted runners only with private repositories because a public fork can potentially submit workflow code that executes on a reachable self-hosted machine. The same trust analysis applies to privileged larger-runner networking.

8. Auditability: policy without retained evidence is hard to prove

Governance needs evidence for both prevention and review. The organization and enterprise audit logs record many administrative events, while workflow runs record execution evidence. These datasets answer different questions: a run log tells you what a job did; an audit record can tell you who changed a setting, membership or access boundary.

GitHub currently exposes recent organization and enterprise audit activity in the web experience, with general audit events visible for roughly 180 days and Git events retained for a shorter window. Enterprise Cloud adds API and streaming capabilities that support longer external retention. A regulated organization should therefore define export/stream retention explicitly instead of assuming GitHub’s interactive history is its permanent compliance archive.

Audit streaming is an evidence transport, not an exactly-once ledger. Current GitHub documentation describes at-least-once delivery, so downstream ingestion should deduplicate using stable event attributes rather than treating a duplicate record as a second administrative change.

9. Exceptions are governed state, not side-channel permission

A useful platform must allow justified exceptions without turning every exception into a permanent backdoor. A waiver should name the requester, control being bypassed, exact repository/workflow/action or runner scope, reason, risk owner, compensating controls, start time, expiry, review evidence and rollback/removal plan.

Bad exception Why it fails Governed alternative
“Allow all Marketplace actions for this repo” Scope is much wider than the request Allow one reviewed action at one immutable SHA.
“Give deploy runner to the team forever” No expiry or workload boundary Grant selected workflow/repository access with review date.
“Use write-all until migration finishes” Credential authority is unbounded List exact permission keys and expiration condition.
“Ignore audit export for now” Evidence gap becomes invisible debt Create an owner/date and measurable export/stream requirement.

An exception lifecycle is therefore: request → evaluate → approve or deny → activate narrow scope → monitor evidence → expire → remove → review. The expiry is part of the control, not a calendar reminder.

10. Current platform assumptions recorded for this chapter

  • Behavior checked on 2026-09-10; REST examples use API version 2026-03-10.
  • Full-length action SHA enforcement applies to actions including GitHub-authored actions; reusable workflows have separate reference semantics.
  • Organization-level runner groups are available on current Team/Enterprise offerings for governed self-hosted/larger runner access; exact enterprise options depend on plan and account role.
  • Ruleset workflows and enterprise-wide audit streaming are optional governance layers whose availability depends on organization/enterprise capabilities.
  • The mandatory course path mutates no organization, enterprise, runner or production repository settings.

11. Lesson summary

A production GitHub Actions control model is a layered decision system: policy scope and inheritance bound executable dependencies, token authority, fork behavior and runner access; rules and environments add lifecycle gates; run metadata proves execution; audit and exception records explain administrative authorization. No single switch replaces the others.

Lesson 2 turns that model into a free local lab. You will evaluate sample workflows against a fictional organization standard, inspect denial reasons and build an evidence packet without needing an Enterprise account.

Next lesson

Enterprise Policies, Allowed Actions, Runner Governance, and Auditability: Guided Hands-On Workflow

Continue with the next lesson to build on the current concepts, evidence, security boundaries, and operational practices.

Knowledge check

Can repository YAML override an enterprise policy that denies an external action?

Does enabling full-SHA enforcement mean actions/checkout may still use a floating major tag because GitHub owns it?

What does a runner group govern that a runner label does not?

Why is “verified creator” not equivalent to “safe action”?

A policy was changed correctly but no audit data is retained beyond the review window. What governance property is missing?

Official references and version notes

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.