Git, CI/CD & GitOpsCXVII · Compliance and AuditArtefacts
The change authorisation record — the approval trail
What you'll learn
- Define the change authorisation record as the audit trail of approval, not the PR itself
- Distinguish required reviewers from advisory reviewers and CODEOWNERS approvers from change-board approvers
- Bind the authorisation record to the PR, the branch policy, and the change board when applicable
- Query the authorisation record from a fresh terminal using gh pr view and the GitHub API
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
The change authorisation record is the audit trail of approval. The auditor’s question is not “did you have a PR?”; the auditor’s question is “who approved the change, when, on what grounds, and under which policy?”. The PR is the conversation; the authorisation record is the artefact. This lesson defines the record, distinguishes the four kinds of approver, and teaches the query path.
What the record contains
The authorisation record is the audit-trail view of the approval chain:
flowchart LR
A["Authorisation record"] --> A1["Author"]
A --> A2["Required reviewers"]
A --> A3["Actual approvers"]
A --> A4["Approval timestamps"]
A --> A5["Review comments:\nthe grounds"]
A --> A6["Branch policy:\nthe rule"]
A --> A7["Change-board reference"]
The seven are stable across frameworks. SOX emphasises segregation (A1 vs A3). SOC 2 emphasises the documented grounds (A5). PCI-DSS emphasises the change-board approval (A7). ISO 27001 emphasises the branch policy (A6).
Four kinds of approver
The record can contain up to four kinds, and the auditor distinguishes them:
- CODEOWNERS approver. Owner of the affected
code path, identified by
CODEOWNERSat the repo root. Required when branch policy enforces CODEOWNERS review. - Peer reviewer. Assigned by the author or team rotation; required by the branch policy’s required-reviewer count.
- Security approver. From the security team when the change touches a sensitive path (IAM, network, secrets). A separate approval so segregation is queryable.
- Change-board approver. From the CAB, required when the change window or class demands it. Often in a separate system; the join to the PR is the audit’s responsibility.
Not all four are always present. A routine change may require only a peer; a sensitive IAM change may require peer plus security plus change-board.
Querying the record
The record is queryable from a fresh terminal via the GitHub API:
PR_NUMBER="$LAST_PR_NUMBER"
gh pr view "$PR_NUMBER" --json reviews,reviewRequests,files
--json reviews returns every review event with
reviewer, state, timestamp, and body. --json reviewRequests returns the required-reviewer set.
--json files returns the file list, cross-reference
with CODEOWNERS to identify the approver. The full
record is reconstructed by joining these three with
the branch policy (gh api repos/:owner/:repo/ branches/main/protection) and the change-board
system where applicable.
The branch policy as the rule of record
The branch policy is not metadata; it is the rule that determined which approvals were required. A record that says “approved by Alice” without naming the rule is a record that cannot answer whether the approval was required:
flowchart LR
P["Branch policy:\nmain requires 2 peer\n+ CODEOWNERS for /infra/**"] --> R1["Required:\n2 peer approvers"]
P --> R2["Required:\nCODEOWNERS for infra paths"]
P --> R3["Advisory:\nsecurity notification"]
R1 --> REC["Authorisation record"]
R2 --> REC
R3 --> REC
REC --> Q["Auditor query:\nwas the required set\nsatisfied?"]
The branch policy must be snapshotted at the time
of the change. A policy tightened after a merge is
not the policy the change was approved under; the
record must record the policy as it stood when the
PR was merged. The GitHub API returns the current
policy, not the historical one; the team must keep
a snapshot in the repository (.github/branch-protection.json).
Production discipline
- Every approval has a capacity. Peer, CODEOWNERS, security, change-board.
- The branch policy is snapshotted in the repository. Live is operator’s view; committed is auditor’s view; CI verifies the two.
- The review comment is the grounds. “LGTM” is not grounds.
- The change-board approval is recorded with the same fields.
Cross-course references
- This course, Part CVI (ChangeMgmt) covered the change-record pattern this extends.
- This course, Part CXV (OperatingModel) named the reviewer, approver, and change-board roles.
- Terraform for Production Sysadmins - Part XII covers the same pattern at the Terraform plan layer.
Quiz
Knowledge check · 4 questions
Q1. A PR for a sensitive IAM change was approved by Alice and Bob. Alice is on the security team and is the CODEOWNERS approver for the iam/ path. The branch policy requires both a peer reviewer and a CODEOWNERS approver. The record says only 'approved by Alice and Bob'. What can the auditor not determine?
Q2. A branch policy that lives only in the GitHub settings UI is sufficient for audit, because the GitHub API can retrieve the historical policy.
Q3. Name the four kinds of approver a change authorisation record can contain.
Q4. Diagnose the authorisation record and recommend the structural fix.
Team T's PRs are merged via GitHub. The branch policy requires two peer reviewers and CODEOWNERS review for any change touching /infra/**. The PR page records approvals only as 'approved by Alice' and 'approved by Bob' - the capacity is not recorded. The CODEOWNERS file is in the repository, but the live branch policy is configured in the GitHub UI and has been edited three times in the last six months. A change-board exists for freeze-window changes, but the approvals are recorded in Jira, not in the PR.
Passing score: 75%. Answers are checked in this browser.