Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 66 additions & 5 deletions docs/governance/codeowners-branch-protection.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,64 @@
- Keep review load on project teams, not the organizers — each project owns its own merge gates.
- Provide consistent guardrails (branch protection, required checks) that match CivicTechWR's volunteer-friendly workflow.

## Team-Based Access Model

**All repository access must be granted through teams, not directly to individual users.** Direct user-to-repo assignments bypass the team governance model, are invisible in team audit views, and create stale access when contributors rotate off.

### Permission Levels

| GitHub Permission | Plain-English meaning | Who gets it |
|------------------|----------------------|-------------|
| **Read** | You can see everything, open issues, leave comments — but not touch code | Anyone browsing or giving feedback |
| **Triage** | Read + you can label/close issues and PRs, but still can't push code | Community managers, issue shepherds |
| **Write** | You can push branches, open PRs, review and merge PRs (if branch protection allows) | All active project contributors |
| **Maintain** | Everything Write + you can change branch protection settings, close stale issues, push to protected branches in an emergency | Project leads |
| **Admin** | Full control: settings, delete the repo, manage who has access, change billing | `@CivicTechWR/organizers` only, on governance repos |

**Maintain is the right permission for project leads.** It covers all day-to-day lead responsibilities without the nuclear options — deleting the repo, changing billing, or modifying org-level settings. Any team named `*-leads` or `*-admins` should use Maintain, not Admin, unless there is a specific documented reason otherwise.

### Which permission should I assign? (Decision Guide)

```mermaid
flowchart TD
A[New person joining a project] --> B{Are they a project lead or maintainer?}
B -- No --> C[Add to contributor team: Write]
B -- Yes --> D{Do they need to delete repos or manage billing?}
D -- No --> E[Add to leads team: Maintain]
D -- Yes, organizer role --> F[Add to organizers team: Admin on governance repos only]

G[New team being created] --> H{What does this team need to do?}
H -- Contribute code / review PRs --> C
H -- Manage branch rules / close issues --> E
H -- Manage org settings --> F

style C fill:#d4edda
style E fill:#fff3cd
style F fill:#f8d7da
```

### Setting Up a New Project Team

1. Create a contributors team: `your-project-team` with **Write** permission
2. If leads are identified, create: `your-project-leads` with **Maintain** permission
3. Add the team(s) to the repository — do not add individual users directly
4. Remove any existing direct user-to-repo assignments once team coverage is confirmed
5. Add a `CODEOWNERS` file pointing to the team (see below)

### Removing Direct User Assignments

To check whether a repo has any direct assignments:
```bash
gh api repos/CivicTechWR/REPO/collaborators?affiliation=direct --jq '.[].login'
```
If the list is non-empty and those users are already covered by a team, remove the direct grants:
```bash
gh api repos/CivicTechWR/REPO/collaborators/USERNAME -X DELETE
```
Do not remove a direct assignment until the user's team membership is confirmed — removing it without team coverage will cut off their access entirely.

---

## How CODEOWNERS Works in This Organization

**Important:** GitHub does not propagate a `CODEOWNERS` file from the org-level `.github` repository to other repositories in the organization. The `CODEOWNERS` file in this repository protects only *this* repository.
Expand Down Expand Up @@ -82,11 +140,13 @@ Projects without a dedicated team fall back to `@CivicTechWR/organizers` as revi

## Implementation Checklist

1. **Confirm team access:** Ensure each team has triage or write permissions on its corresponding repositories.
2. **Add a CODEOWNERS file to each active project repo:** Use the templates above. Do not rely on the organizer-level `.github` file — it does not propagate.
3. **Update branch protection per repo:** Apply the recommended rule to each repository's default branch.
4. **Communicate the change:** Post in `#organizers`, update `CTWR-Organization-Documentation`, and mention during the weekly meetup.
5. **Track coverage:** Open an issue to track which repos still lack a CODEOWNERS file and invite project teams to add their own.
1. **Create teams before adding people.** Never add a user directly to a repo. Create (or identify) the appropriate team first.
2. **Apply the right permission level.** Contributors → Write. Leads → Maintain. Do not use Admin for project teams.
3. **No direct user assignments.** Verify the repo has no direct collaborators (`Settings → Collaborators → Direct access`). If it does, confirm team coverage first, then remove the direct grants.
4. **Add a CODEOWNERS file to each active project repo.** Use the templates above. Do not rely on the organizer-level `.github` file — it does not propagate.
5. **Update branch protection per repo.** Apply the recommended rule to each repository's default branch.
6. **Communicate the change.** Post in `#organizers`, update `CTWR-Organization-Documentation`, and mention during the weekly meetup.
7. **Track coverage.** Open an issue to track which repos still lack a CODEOWNERS file and invite project teams to add their own.

## Break-Glass Procedure

Expand Down Expand Up @@ -123,6 +183,7 @@ Do not use this procedure to skip security or compliance reviews.

## Risks and Pitfalls

- **Direct user assignments bypass team governance:** Adding users directly to repos instead of via teams makes them invisible to team-level audits and creates stale access that persists after someone leaves a project. Always use teams.
- **CODEOWNERS does not auto-propagate:** Repos without their own CODEOWNERS file have no code-owner enforcement, regardless of what this governance repo contains.
- **Stale team membership:** CODEOWNERS blocks merges when listed reviewers are inactive. Reconfirm rosters every quarter and any time a maintainer steps back.
- **Automation permissions:** Workflows that create teams or modify permissions require an organization-level Personal Access Token with `admin:org`; keep the token scoped and rotate it periodically.
Expand Down
Loading