Skip to content

Commit 644b728

Browse files
authored
Add Centralised Repository Governance pattern
This document outlines a governance pattern for managing repository settings across large organizations. It details the problems of inconsistent settings, the proposed solution of a central governance repository, and the components involved in implementing automated audits.
1 parent 557dbf2 commit 644b728

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
# **Centralised Repository Governance**
2+
3+
## **Patlet**
4+
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.
6+
7+
## **Problem**
8+
9+
When many teams manage their own repositories, settings naturally become inconsistent. Typical issues include:
10+
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.
17+
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.
19+
20+
## **Context**
21+
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.
27+
28+
## **Forces**
29+
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.
35+
36+
## **Solution**
37+
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.
39+
40+
The governance repository includes three main components:
41+
42+
### **1. Policy-as-Code**
43+
44+
Store expected settings in version-controlled files under `policies/`.
45+
46+
**Example structure:**
47+
48+
```
49+
policies/
50+
branch_protection.yml
51+
workflow_permissions.yml
52+
codeowners.yml
53+
commit_signing.yml
54+
tag_protection.yml
55+
```
56+
57+
**Example baseline rule:**
58+
59+
```yaml
60+
required_pull_request_reviews:
61+
required_approving_review_count: 1
62+
enforce_admins: true
63+
require_signed_commits: true
64+
dismiss_stale_reviews: true
65+
```
66+
67+
These files form a clear, shared baseline for all teams.
68+
69+
### **2. Audit Engine**
70+
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")
81+
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+
```
89+
90+
Checks may include:
91+
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:**
102+
103+
```python
104+
if "pull_request_target" in workflow_yaml["on"]:
105+
findings.append(f"{repo.name}: Uses pull_request_target")
106+
```
107+
108+
### **3. Scheduled Audit (GitHub Actions)**
109+
110+
A workflow in the governance repo runs the audit regularly.
111+
112+
**Example `.github/workflows/audit.yml`:**
113+
114+
```yaml
115+
name: Nightly Audit
116+
117+
on:
118+
schedule:
119+
- 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
141+
```
142+
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:
148+
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.
153+
154+
**Example GitHub Issue:**
155+
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+
```
168+
169+
## **Resulting Context**
170+
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.
177+
178+
## **Use This Pattern When**
179+
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.
186+
187+
## **Don’t Use This Pattern When**
188+
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.
195+
196+
## **Authors**
197+
198+
[Amburi Roy](https://www.linkedin.com/in/amburi/)
199+
200+
## **Alias**
201+
202+
Governance-as-Code Audit Repository
203+
204+
## **Related Patterns**
205+
206+
* **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+

0 commit comments

Comments
 (0)