Skip to content

Commit 6480e13

Browse files
authored
Revise Centralised Repository Governance documentation
Updated the Centralised Repository Governance document to clarify the importance of a governance repository, enhance the narrative around repository drift, and refine the structure and examples for better understanding.
1 parent 644b728 commit 6480e13

File tree

1 file changed

+87
-131
lines changed

1 file changed

+87
-131
lines changed

patterns/1-initial/centralised-repository-governance.md

Lines changed: 87 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -2,48 +2,62 @@
22

33
## **Patlet**
44

5-
Large organisations often struggle to keep repository settings aligned across many teams. Over time, policies such as branch protection, workflow permissions, and commit signing drift away from the intended standard. A central governance repository that runs automated audits can detect this drift early and give teams clear feedback without interrupting their work.
5+
It’s easy for repository settings to drift when many teams manage their own projects. A central governance repository, backed by automated nightly audits, helps keep everything aligned with the organisation’s engineering standards while allowing teams to work freely.
6+
67

78
## **Problem**
89

9-
When many teams manage their own repositories, settings naturally become inconsistent. Typical issues include:
10+
As organisations grow, each team naturally sets up repositories in their own way. Over time, these settings begin to diverge:
11+
12+
* branch protection disappears or becomes inconsistent,
13+
* workflow permissions expand beyond what’s allowed,
14+
* CODEOWNERS files go missing,
15+
* admin bypass quietly slips in,
16+
* and new repositories start life without any safeguards at all.
17+
18+
No one notices immediately, and no one does it on purpose. It just... happens.
19+
Manual audits are slow and rarely complete. Before long, the organisation has dozens of small risks scattered everywhere, hidden in plain sight.
20+
21+
## **Story**
1022

11-
* missing or weakened branch protection,
12-
* overly broad workflow permissions,
13-
* missing or outdated CODEOWNERS files,
14-
* admin bypass enabled unintentionally,
15-
* use of risky workflow triggers,
16-
* or new repositories lacking required protections altogether.
23+
A platform team in a large engineering organisation realised something worrying: every few weeks, a production incident or security concern could be traced back to a simple repository misconfiguration. Nothing dramatic—just things like a missing review requirement or an overly generous GitHub Actions permission.
1724

18-
Manual checking does not scale. Teams focus on delivery, not on remembering organisation-wide rules. As a result, gaps grow slowly and silently, increasing both security exposure and operational risk.
25+
People weren’t careless; they were busy. They moved fast, created new repos, copied old workflows, and tweaked settings when needed. Over time, these changes compounded into a patchwork of configurations.
26+
27+
Instead of telling every team to “be more careful”, the platform team built a small governance repository. It held a clear, versioned baseline of expected repo settings, and each night a GitHub Action scanned every repository, comparing it with the baseline.
28+
29+
The next morning, teams received a calm, simple report:
30+
**Here’s what changed. Here’s where drift happened. Here’s how to fix it.**
31+
32+
Within a month, the number of incidents dropped, standards became consistent, and onboarding new repos felt effortless.
33+
The best part? No one’s workflow was interrupted. The whole system quietly supported good engineering hygiene in the background.
1934

2035
## **Context**
2136

22-
* The organisation hosts many repositories on GitHub.
23-
* Teams have autonomy to create and configure their own repos.
24-
* Leadership expects predictable engineering safeguards.
25-
* There is no simple way to see where configuration drift has occurred.
26-
* Automation is accepted and available through GitHub Actions.
37+
* Many repositories exist across multiple teams.
38+
* Teams have the freedom to configure their own repos.
39+
* Engineering or security leadership expects a shared baseline.
40+
* Visibility across all repos is limited.
41+
* GitHub Actions or similar tooling is available for automation.
2742

2843
## **Forces**
2944

30-
* **Autonomy vs consistency** — teams should move fast, but common safeguards matter.
31-
* **Scale** — manual audits fail once repo count grows.
32-
* **Transparency** — policies should be visible and reviewable.
33-
* **Low friction** — governance should not slow everyday work.
34-
* **Early detection** — drift needs to be surfaced before it becomes risky.
45+
* **Autonomy vs alignment:** Teams need freedom to build, but consistent safeguards matter.
46+
* **Scale:** Manual reviews fail once repository numbers grow.
47+
* **Transparency:** Policies should be easy to understand and open to contribution.
48+
* **Low friction:** Governance should guide, not block.
49+
* **Early warning:** Small mistakes should surface before they turn into costly incidents.
3550

3651
## **Solution**
3752

38-
Create a dedicated “Governance Repository” that stores the organisation’s baseline policies as code and contains an audit engine that checks all repositories on a set schedule, such as nightly. The audit compares each repository’s real configuration to the baseline and reports any drift.
53+
Create a **central governance repository** that stores baseline policies as code and runs a scheduled audit—usually nightly—to compare real repository configurations against the baseline.
3954

40-
The governance repository includes three main components:
55+
The repository contains three essential parts.
4156

4257
### **1. Policy-as-Code**
4358

44-
Store expected settings in version-controlled files under `policies/`.
45-
46-
**Example structure:**
59+
Store baseline expectations under a `policies/` directory.
60+
This might include:
4761

4862
```
4963
policies/
@@ -54,157 +68,99 @@ policies/
5468
tag_protection.yml
5569
```
5670

57-
**Example baseline rule:**
71+
**Example baseline (branch_protection.yml):**
5872

5973
```yaml
6074
required_pull_request_reviews:
6175
required_approving_review_count: 1
62-
enforce_admins: true
6376
require_signed_commits: true
64-
dismiss_stale_reviews: true
77+
enforce_admins: true
6578
```
6679
67-
These files form a clear, shared baseline for all teams.
80+
These files become the shared, reviewable definition of “how we configure repositories here”.
6881
6982
### **2. Audit Engine**
7083
71-
A script (written in Python, Node, or Go) loops through all organisation repositories using the GitHub API, retrieves their configuration, and compares it to the baseline.
72-
73-
**Python example (simplified):**
74-
75-
```python
76-
from github import Github
77-
import yaml, os
78-
79-
gh = Github(os.environ["GITHUB_TOKEN"])
80-
org = gh.get_organization("my-org")
84+
An audit script (Python, Node, or Go) uses the GitHub API to inspect every repository and compare its configuration to the baseline.
8185
82-
baseline = yaml.safe_load(open("policies/branch_protection.yml"))
83-
84-
for repo in org.get_repos():
85-
rules = repo.get_branch("main").get_protection()
86-
if rules.required_pull_request_reviews is None:
87-
findings.append(f"{repo.name}: Missing PR review rule")
88-
```
86+
**Example behaviour:**
8987
90-
Checks may include:
88+
* Check branch and tag protection
89+
* Validate CODEOWNERS
90+
* Examine workflow permissions (including nested job/step scopes)
91+
* Detect risky triggers (`pull_request_target`)
92+
* Identify admin bypass or unapproved overrides
9193

92-
* branch protection
93-
* tag protection
94-
* CODEOWNERS consistency
95-
* required reviews and approvers
96-
* commit signing rules
97-
* workflow permissions (including nested job/step scopes)
98-
* risky triggers such as `pull_request_target`
99-
* ruleset and bypass drift
100-
101-
**Workflow trigger example:**
94+
**Simplified Python example:**
10295

10396
```python
104-
if "pull_request_target" in workflow_yaml["on"]:
97+
if "pull_request_target" in workflow_yaml.get("on", {}):
10598
findings.append(f"{repo.name}: Uses pull_request_target")
10699
```
107100

108-
### **3. Scheduled Audit (GitHub Actions)**
101+
When differences appear, the engine records them as drift.
109102

110-
A workflow in the governance repo runs the audit regularly.
103+
### **3. Nightly Audit Workflow**
111104

112-
**Example `.github/workflows/audit.yml`:**
105+
A GitHub Actions workflow runs the audit automatically.
113106

114107
```yaml
115-
name: Nightly Audit
116-
117108
on:
118109
schedule:
119110
- cron: "0 2 * * *"
120-
workflow_dispatch:
121-
122-
jobs:
123-
audit:
124-
runs-on: ubuntu-latest
125-
permissions:
126-
contents: read
127-
actions: read
128-
steps:
129-
- uses: actions/checkout@v4
130-
- name: Install dependencies
131-
run: pip install -r requirements.txt
132-
- name: Run audit
133-
env:
134-
GITHUB_TOKEN: ${{ secrets.GOVERNANCE_TOKEN }}
135-
run: python audit/runner.py
136-
- name: Store report
137-
uses: actions/upload-artifact@v4
138-
with:
139-
name: nightly-report
140-
path: reports/latest.json
141111
```
142112

143-
The token should be a GitHub App or PAT with read-only org access.
144-
145-
### **4. Reporting**
146-
147-
Results are summarised in a consolidated report. Teams may be notified through:
113+
It collects findings, creates a summary report, and optionally:
148114

149-
* a Slack message,
150-
* a Markdown summary stored in the governance repo,
151-
* GitHub Issues created on affected repositories,
152-
* or optional PRs that apply simple fixes.
115+
* posts to Slack,
116+
* opens GitHub Issues on non-compliant repositories, or
117+
* creates PRs to apply straightforward fixes.
153118

154-
**Example GitHub Issue:**
119+
**Key principles:**
155120

156-
```
157-
Title: Repository policy drift detected
158-
159-
Your repository does not match the organisation’s baseline.
160-
161-
Findings:
162-
- Missing CODEOWNERS file
163-
- Workflow grants overly broad write permissions
164-
- Signed commits not enforced
165-
166-
Please review and update the configuration.
167-
```
121+
* Read-only access
122+
* No blocking behaviour
123+
* Clear, actionable reporting
168124

169125
## **Resulting Context**
170126

171-
* Repository settings stabilise over time, reducing risk.
172-
* Drift becomes visible early and is easy to address.
173-
* Teams keep their autonomy while receiving clear, automated feedback.
174-
* Policy changes flow through normal code review and remain transparent.
175-
* New repositories inherit governance automatically.
176-
* Leadership gains an accurate daily snapshot of organisational configuration health.
127+
* Repository settings become more consistent and predictable.
128+
* Drift is found early rather than after an incident.
129+
* Teams stay autonomous while receiving helpful guidance.
130+
* Policies remain transparent and open to discussion.
131+
* New repositories inherit standards from day one.
132+
* Leadership gains confidence in organisational hygiene without micromanagement.
177133

178134
## **Use This Pattern When**
179135

180-
* You have many repositories maintained by different teams.
181-
* You want consistent engineering safeguards across the organisation.
182-
* You need early visibility into risky configuration changes.
183-
* You prefer light-touch governance rather than strict enforcement.
184-
* You want policies to be explicit, reviewable, and version-controlled.
185-
* You want to reduce manual auditing work.
136+
* You have many repositories owned by different teams.
137+
* You want reliable, repeatable engineering safeguards.
138+
* You prefer guidance rather than strict enforcement.
139+
* You want policies to be version-controlled and adaptable.
140+
* You want to reduce manual audit work and platform overhead.
186141

187142
## **Don’t Use This Pattern When**
188143

189-
* Your organisation has only a few repositories and manual checks are easier.
190-
* You need strict enforcement at merge time rather than advisory feedback.
191-
* Your baseline policies change frequently and are not yet stable.
192-
* You cannot grant a GitHub App or token read access across the organisation.
193-
* Many repositories require unique settings, making a single baseline impractical.
194-
* Your organisation is not ready to adopt policy-as-code.
144+
* Only a few repositories exist and manual checks are enough.
145+
* You need hard, immediate enforcement at merge time.
146+
* Baseline policies change too frequently to maintain.
147+
* A GitHub App or read-access token cannot be used.
148+
* Most teams require unique repo configurations that don’t fit a shared baseline.
195149

196-
## **Authors**
197150

198-
[Amburi Roy](https://www.linkedin.com/in/amburi/)
151+
## **Known Instances**
199152

200-
## **Alias**
153+
* Large technology organisations using GitHub Enterprise.
154+
* Platform teams responsible for organisational governance and lifecycle tooling.
155+
* Engineering groups moving towards policy-as-code and automation.
201156

202-
Governance-as-Code Audit Repository
157+
## **Authors**
158+
159+
[Amburi Roy](https://www.linkedin.com/in/amburi/)
203160

204161
## **Related Patterns**
205162

206163
* **Automated Testing** — shared automated checks for quality.
207-
* **InnerSource Product Owner** — defines ownership of the governance repo.
208-
* **Trusted Committers** — supports safe changes to shared policy.
209-
* **InnerSource Portal** — complements centralising organisational knowledge.
210-
164+
* **InnerSource Product Owner** — helps with stewardship of the governance repo.
165+
* **Trusted Committers** — supports safe and consistent policy changes.
166+
* **InnerSource Portal** — complements central access to shared organisational knowledge.

0 commit comments

Comments
 (0)