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.
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.
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.
Knowledge check
Can repository YAML override an enterprise policy that denies an external action?
No. A higher-scope deny is an administrative boundary. Diagnose and change the authorized policy layer or the workflow dependency; do not attempt to bypass it in YAML.
Does enabling full-SHA enforcement mean
actions/checkout may still use a floating major tag
because GitHub owns it?
No. Current enforcement applies to actions including GitHub-authored actions.
What does a runner group govern that a runner label does not?
A runner group can govern which organizations, repositories and workflows may use a runner pool; labels mainly participate in runner matching/routing.
Why is “verified creator” not equivalent to “safe action”?
It establishes publisher verification, not the safety of every release, requested permission, transitive dependency or runtime behavior.
A policy was changed correctly but no audit data is retained beyond the review window. What governance property is missing?
Auditability. Preventive controls may still work, but the organization cannot reliably reconstruct who changed the policy and why over its required retention period.
Official references and version notes
- Enforcing policies for GitHub Actions in your enterprise — Current enterprise policy options, selected-action rules and full-SHA enforcement.
- Managing GitHub Actions settings for a repository — Repository-level action policy, token defaults and fork settings, including inheritance limits.
- Managing access to self-hosted runners using groups — Runner-group organization/repository/workflow access and public-repository warnings.
- Reviewing the audit log for your organization — Audit-log search/export/API boundaries and retention guidance.
- Secure use reference — Least privilege, untrusted input, third-party action and runner security guidance.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this
address.