|
1 | | -# GitHub Safe-Settings |
| 1 | +# 🛡️ GitHub Safe-Settings |
2 | 2 |
|
3 | 3 | [](https://github.com/github/safe-settings/actions/workflows/create-release.yml) |
| 4 | +[](https://opensource.org/licenses/ISC) |
| 5 | +[](https://nodejs.org/) |
4 | 6 |
|
5 | | -`Safe-settings` – an app to manage policy-as-code and apply repository settings across an organization. |
| 7 | +> **Policy-as-Code for GitHub Organizations** |
| 8 | +> Centrally manage and enforce repository settings, branch protections, teams, and more across your entire GitHub organization. |
6 | 9 |
|
7 | | -1. In `safe-settings`, all the settings are stored centrally in an `admin` repo within the organization. Unlike the [GitHub Repository Settings App](https://github.com/repository-settings/app), the settings files cannot be in individual repositories. |
| 10 | +## ✨ What is Safe-Settings? |
8 | 11 |
|
9 | | - > It is possible specify a custom repo instead of the `admin` repo with `ADMIN_REPO`. See [Environment variables](#environment-variables) for more details. |
| 12 | +Safe-Settings is a powerful GitHub App that enables **Policy-as-Code** for your organization. Instead of manually configuring each repository, define your policies once and let Safe-Settings apply them consistently across all your repositories. |
10 | 13 |
|
11 | | -1. The **settings** in the **default** branch are applied. If the settings are changed on a non-default branch and a PR is created to merge the changes, the app runs in a `dry-run` mode to evaluate and validate the changes. Checks pass or fail based on the `dry-run` results. |
| 14 | +### 🏗️ Core Concepts |
12 | 15 |
|
13 | | -1. In `safe-settings` the settings can have 2 types of targets: |
14 | | - 1. `org` - These settings are applied to the organization. `Org`-targeted settings are defined in `.github/settings.yml`. Currently, only `rulesets` are supported as `org`-targeted settings. |
15 | | - 1. `repo` - These settings are applied to repositories. |
| 16 | +1. **Centralized Configuration**: All settings are stored centrally in an `admin` repo within the organization. Unlike the [GitHub Repository Settings App](https://github.com/repository-settings/app), the settings files cannot be in individual repositories. |
16 | 17 |
|
17 | | -1. For the `repo`-targeted settings, there can be 3 levels at which the settings are managed: |
18 | | - 1. `Org`-level settings are defined in `.github/settings.yml` |
| 18 | + > You can specify a custom repo instead of the `admin` repo with `ADMIN_REPO`. See [Environment variables](#environment-variables) for more details. |
19 | 19 |
|
20 | | - > It is possible to override this behavior and specify a different filename for the `settings.yml` file with `SETTINGS_FILE_PATH`. Similarly, the `.github` directory can be overridden with `CONFIG_PATH`. See [Environment variables](#environment-variables) for more details. |
| 20 | +2. **Branch-Based Application**: The **settings** in the **default** branch are applied. If settings are changed on a non-default branch and a PR is created to merge the changes, the app runs in `dry-run` mode to evaluate and validate the changes. Checks pass or fail based on the `dry-run` results. |
21 | 21 |
|
22 | | - 1. `Suborg` level settings. A `suborg` is an arbitrary collection of repos belonging to projects, business units, or teams. The `suborg` settings reside in a yaml file for each `suborg` in the `.github/suborgs` folder. |
| 22 | +3. **Multi-Level Settings Management**: Settings are managed at three levels with clear precedence: |
| 23 | + - **Organization-level**: Defined in `.github/settings.yml` |
| 24 | + - **Sub-organization level**: Defined in `.github/suborgs/*.yml` for groups of repositories |
| 25 | + - **Repository-level**: Defined in `.github/repos/*.yml` for specific repositories |
23 | 26 |
|
24 | | - > In `safe-settings`, `suborgs` could be groups of repos based on `repo names`, or `teams` which the repos have collaborators from, or `custom property values` set for the repos |
| 27 | +4. **Team-Based Management**: It's recommended to break settings into org-level, suborg-level, and repo-level units. This allows different teams to define and manage policies for their specific projects or business units. With `CODEOWNERS`, different people can be responsible for approving changes in different projects. |
25 | 28 |
|
26 | | - 1. `Repo` level settings. They reside in a repo specific yaml in `.github/repos` folder |
| 29 | +> [!NOTE] |
| 30 | +> The `suborg` and `repo` level settings directory structure cannot be customized. |
| 31 | +
|
| 32 | +### 🎯 Key Benefits |
| 33 | + |
| 34 | +- **🏢 Centralized Management**: All settings stored in a single admin repository |
| 35 | +- **📋 Policy-as-Code**: Version-controlled, reviewable configuration changes |
| 36 | +- **🔄 Automatic Sync**: Real-time enforcement prevents configuration drift |
| 37 | +- **🎚️ Multi-Level Control**: Organization, sub-organization, and repository-specific settings |
| 38 | +- **✅ Validation & Testing**: Dry-run mode with PR checks before applying changes |
| 39 | +- **🚀 Easy Deployment**: Multiple deployment options including AWS Lambda template |
| 40 | + |
| 41 | +## 🚀 Quick Start |
| 42 | + |
| 43 | +### 1. **Deploy Safe-Settings** |
| 44 | + |
| 45 | +Choose your preferred deployment method: |
| 46 | + |
| 47 | +- **🌟 AWS Lambda**: Use the [SafeSettings-Template](https://github.com/bheemreddy181/SafeSettings-Template) for production-ready deployment |
| 48 | +- **🐳 Docker**: Deploy using Docker containers |
| 49 | +- **☁️ Cloud Platforms**: Deploy to Heroku, Glitch, or Kubernetes |
| 50 | + |
| 51 | +👉 **[View all deployment options →](docs/deploy.md)** |
27 | 52 |
|
28 | | -1. It is recommended to break the settings into `org`-level, `suborg`-level, and `repo`-level units. This will allow different teams to define and manage policies for their specific projects or business units. With `CODEOWNERS`, this will allow different people to be responsible for approving changes in different projects. |
| 53 | +### 2. **Create Admin Repository** |
| 54 | + |
| 55 | +Create an `admin` repository in your organization to store all configuration files: |
| 56 | + |
| 57 | +```bash |
| 58 | +# Create admin repo in your organization |
| 59 | +gh repo create your-org/admin --private |
| 60 | +``` |
| 61 | + |
| 62 | +### 3. **Configure Settings** |
| 63 | + |
| 64 | +Add your organization policies in the admin repository: |
| 65 | + |
| 66 | +``` |
| 67 | +admin/ |
| 68 | +├── .github/ |
| 69 | +│ ├── settings.yml # Organization-wide settings |
| 70 | +│ ├── suborgs/ # Sub-organization settings |
| 71 | +│ │ ├── frontend-team.yml |
| 72 | +│ │ └── backend-team.yml |
| 73 | +│ └── repos/ # Repository-specific settings |
| 74 | +│ ├── api-service.yml |
| 75 | +│ └── web-app.yml |
| 76 | +``` |
| 77 | + |
| 78 | +### 4. **Install GitHub App** |
| 79 | + |
| 80 | +Install the Safe-Settings GitHub App in your organization with the required permissions. |
| 81 | + |
| 82 | +👉 **[Complete setup guide →](#how-to-use)** |
| 83 | + |
| 84 | +## 🏗️ Architecture Overview |
| 85 | + |
| 86 | +Safe-Settings uses a **hierarchical configuration system** with three levels of control: |
| 87 | + |
| 88 | +### 📊 Configuration Hierarchy |
| 89 | + |
| 90 | +```mermaid |
| 91 | +graph TD |
| 92 | + A[Organization Settings<br/>.github/settings.yml] --> B[Sub-Organization Settings<br/>.github/suborgs/*.yml] |
| 93 | + B --> C[Repository Settings<br/>.github/repos/*.yml] |
| 94 | + |
| 95 | + style A fill:#e1f5fe,stroke:#01579b,stroke-width:2px,color:#000 |
| 96 | + style B fill:#f3e5f5,stroke:#4a148c,stroke-width:2px,color:#000 |
| 97 | + style C fill:#e8f5e8,stroke:#1b5e20,stroke-width:2px,color:#000 |
| 98 | +``` |
| 99 | + |
| 100 | +**Precedence Order**: Repository > Sub-Organization > Organization |
| 101 | + |
| 102 | +### 🎯 Target Types |
| 103 | + |
| 104 | +- **🏢 Organization (`org`)**: Applied to the entire organization (e.g., rulesets) |
| 105 | +- **📁 Repository (`repo`)**: Applied to specific repositories (e.g., branch protection, teams, labels) |
| 106 | + |
| 107 | +### 📂 Sub-Organizations |
| 108 | + |
| 109 | +Group repositories by: |
| 110 | +- **Team membership**: Repositories with collaborators from specific teams |
| 111 | +- **Naming patterns**: Repositories matching glob patterns (e.g., `api-*`, `frontend-*`) |
| 112 | +- **Custom properties**: Repositories with specific GitHub custom property values |
29 | 113 |
|
30 | 114 | > [!NOTE] |
31 | | -> The `suborg` and `repo` level settings directory structure cannot be customized. |
32 | | -> |
| 115 | +> Unlike the [GitHub Repository Settings App](https://github.com/repository-settings/app), all settings are centrally managed in the admin repository, not in individual repositories. |
| 116 | +
|
| 117 | +### 🔄 Request Flow |
| 118 | + |
| 119 | +```mermaid |
| 120 | +sequenceDiagram |
| 121 | + participant GH as GitHub |
| 122 | + participant SS as Safe-Settings |
| 123 | + participant AR as Admin Repo |
| 124 | + participant TR as Target Repos |
| 125 | + |
| 126 | + Note over GH,TR: Webhook Event Processing |
| 127 | + |
| 128 | + GH->>+SS: Webhook Event<br/>(push, repo created, etc.) |
| 129 | + SS->>SS: Validate Event Source |
| 130 | + SS->>+AR: Fetch Configuration Files<br/>(.github/settings.yml, suborgs/, repos/) |
| 131 | + AR-->>-SS: Return Config Files |
| 132 | + |
| 133 | + SS->>SS: Merge Configurations<br/>(Org → Suborg → Repo) |
| 134 | + SS->>SS: Compare with Current<br/>GitHub Settings |
| 135 | + |
| 136 | + alt Configuration Changes Detected |
| 137 | + SS->>+TR: Apply Settings<br/>(Branch Protection, Teams, etc.) |
| 138 | + TR-->>-SS: Confirm Changes |
| 139 | + SS->>GH: Create Check Run<br/>(Success/Failure) |
| 140 | + else No Changes Needed |
| 141 | + SS->>GH: Create Check Run<br/>(No Changes) |
| 142 | + end |
| 143 | + |
| 144 | + SS-->>-GH: HTTP 200 Response |
| 145 | + |
| 146 | + Note over GH,TR: Pull Request Validation (Dry-Run Mode) |
| 147 | + |
| 148 | + GH->>+SS: PR Event<br/>(opened, synchronize) |
| 149 | + SS->>+AR: Fetch PR Changes<br/>(Modified Config Files) |
| 150 | + AR-->>-SS: Return Changed Configs |
| 151 | + |
| 152 | + SS->>SS: Validate Changes<br/>(Dry-Run Mode) |
| 153 | + SS->>SS: Run Custom Validators<br/>(if configured) |
| 154 | + |
| 155 | + alt Validation Passes |
| 156 | + SS->>GH: ✅ Check Success<br/>+ PR Comment (optional) |
| 157 | + else Validation Fails |
| 158 | + SS->>GH: ❌ Check Failure<br/>+ Error Details |
| 159 | + end |
| 160 | + |
| 161 | + SS-->>-GH: HTTP 200 Response |
| 162 | + |
| 163 | + Note over GH,TR: Scheduled Sync (Drift Prevention) |
| 164 | + |
| 165 | + SS->>SS: Cron Trigger<br/>(if configured) |
| 166 | + SS->>+AR: Fetch All Configurations |
| 167 | + AR-->>-SS: Return All Configs |
| 168 | + SS->>+TR: Sync All Repositories<br/>(Prevent Drift) |
| 169 | + TR-->>-SS: Confirm Sync |
| 170 | + SS->>GH: Create Check Run<br/>(Sync Results) |
| 171 | +``` |
33 | 172 |
|
| 173 | +## 🔧 How it Works |
34 | 174 |
|
35 | | -## How it works |
| 175 | +Safe-Settings operates as a **GitHub App** that can run in multiple modes: |
36 | 176 |
|
37 | | -`Safe-settings` is designed to run as a service listening for webhook events or as a scheduled job running on some regular cadence. It can also be triggered through GitHub Actions. (See the [How to use](#how-to-use) section for details on deploying and configuring.) |
| 177 | +- **🎯 Event-Driven**: Responds to GitHub webhook events in real-time |
| 178 | +- **⏰ Scheduled**: Runs on a cron schedule to prevent configuration drift |
| 179 | +- **🚀 GitHub Actions**: Triggered via GitHub Actions workflows |
38 | 180 |
|
| 181 | +### 📡 Webhook Events |
39 | 182 |
|
40 | | -### Events |
41 | | -The App listens to the following webhook events: |
| 183 | +Safe-Settings automatically responds to these GitHub events: |
42 | 184 |
|
43 | 185 | - **push**: If the settings are created or modified, that is, if push happens in the `default` branch of the `admin` repo and the file added or changed is `.github/settings.yml` or `.github/repos/*.yml`or `.github/suborgs/*.yml`, then the settings would be applied either globally to all the repos, or specific repos. For each repo, the settings that are actually applied depend on the default settings for the org, overlaid with settings for the suborg that the repo belongs to, overlaid with the settings for that specific repo. |
44 | 186 |
|
|
0 commit comments