What is Configuration Drift?
Drift happens when:- Users manually change settings through GitHub UI
- Automation tools modify configurations
- Branch protections are deleted or weakened
- Team permissions are altered
- Repository settings are changed
- Create security vulnerabilities
- Violate compliance policies
- Cause inconsistencies across repositories
- Undermine policy-as-code governance
Drift Prevention Strategies
Safe Settings uses two complementary approaches:- Webhook-based detection - Immediate response to changes
- Scheduled synchronization - Periodic convergence
Webhook-Based Drift Prevention
Safe Settings listens to GitHub webhook events and automatically reverts unauthorized changes.Monitored Events
Safe Settings responds to these webhook events to prevent drift:Branch Protection Changes
- User disables “Require pull request reviews” in GitHub UI
- Webhook fires:
branch_protection_rule.edited - Safe Settings detects change doesn’t match configuration
- Automatically restores required reviews setting
Repository Settings Changes
- User changes repository from private to public
- Webhook fires:
repository.edited - Safe Settings compares against settings configuration
- Reverts repository to private if configured
Team Permission Changes
- User manually grants team admin access to repository
- Webhook fires:
team.added_to_repository - Safe Settings checks configured permissions
- Adjusts to configured permission level (e.g., write)
Ruleset Changes
- User modifies ruleset to remove status check requirements
- Webhook fires:
repository_ruleset.edited - Safe Settings restores status check requirements
Custom Property Changes
- User sets custom property
environment=production - Webhook fires:
custom_property_values - Safe Settings applies suborg configuration for production repos
How Webhook Drift Prevention Works
Configuration for Webhooks
Webhook-based drift prevention is automatic. Ensure your GitHub App has these permissions:- Repository administration: Read & write
- Repository hooks: Read & write
- Organization administration: Read & write
Webhook Event Examples
Example 1: Branch Protection Drift
Example 2: Team Permission Drift
Scheduled Synchronization
Scheduled sync provides a safety net by periodically converging all repositories to their configured state, catching any drift that webhooks might miss.Why Scheduled Sync?
Webhooks aren’t always guaranteed to be delivered:- Network failures
- Webhook delivery failures
- Service outages
- GitHub webhook limits
- Missed events during maintenance
Configuring Scheduled Sync
Set theCRON environment variable to run Safe Settings on a schedule.
Cron Syntax
Safe Settings uses node-cron syntax:Common Cron Patterns
| Pattern | Description | Use Case |
|---|---|---|
*/5 * * * * | Every 5 minutes | Testing, high-security |
0 * * * * | Every hour | Standard production |
0 */2 * * * | Every 2 hours | Balanced approach |
0 */6 * * * | Every 6 hours | Light sync |
0 0 * * * | Daily at midnight | Low-frequency |
0 2 * * * | Daily at 2 AM | Off-peak hours |
0 0 * * 0 | Weekly on Sunday | Minimal sync |
0 9 * * 1-5 | Weekdays at 9 AM | Business hours |
How Scheduled Sync Works
Scheduled Sync Behavior
During scheduled sync:- Load all configurations: Org, suborg, and repo settings
- Process each repository: Apply configuration hierarchy
- Detect differences: Compare current GitHub state with expected state
- Apply only changes: Only make API calls when drift is detected
- Create check runs: Document sync results
Performance Considerations
Scheduled sync is optimized for organizations with thousands of repositories:- Only loads changed configuration files (not all files every time)
- Only makes API calls when drift is detected
- Respects rate limits automatically (via Probot)
- Completes within GitHub App token lifetime (1 hour)
Comparison Logic
Both webhook and scheduled sync use intelligent comparison to detect drift.What Gets Compared
Safe Settings compares:- Repository settings (visibility, features, default branch)
- Branch protection rules
- Required status checks
- Team permissions
- Collaborator permissions
- Labels
- Milestones
- Autolinks
- Environments
- Variables
- Rulesets
- Custom properties
How Comparison Works
ThecompareDeep function generates detailed differences:
Smart Comparison Features
Ignores irrelevant fields:Monitoring Drift
Check Runs
Every drift detection and correction creates a check run in your admin repository:Check Run Details
Click into check runs to see detailed changes:Logging
Safe Settings logs all drift detection:Best Practices
Choose Appropriate Sync Frequency
High-security environments:Consider API Rate Limits
More frequent syncs consume more API quota:- Webhooks: Minimal API usage (only affected repos)
- Scheduled sync: API calls for all repos (even without changes)
Schedule During Off-Peak Hours
Run heavy syncs when developers are less active:Combine Both Approaches
Use webhooks for immediate response + scheduled sync as backup:Monitor Drift Patterns
Review check runs to identify:- Frequently drifting repositories
- Common types of drift
- Users making unauthorized changes
- Gaps in your policies
- Educate teams on policy
- Adjust configurations
- Identify process gaps
Handle Legitimate Changes
If drift corrections are unwanted: Option 1: Update configuration to match desired statedeployment-settings.yml
Troubleshooting
Drift Not Being Corrected
Problem: Manual changes aren’t being reverted. Possible causes:-
Webhooks not configured
-
Repository is restricted
-
Setting matches configuration
Scheduled Sync Not Running
Problem: Cron job doesn’t seem to execute. Debug steps:-
Verify CRON syntax
-
Check environment variable
-
Review application logs
-
Verify app is running
Too Many API Calls
Problem: Hitting GitHub API rate limits. Solutions:-
Reduce sync frequency
-
Use restricted repos
-
Monitor API usage
Unexpected Drift Corrections
Problem: Safe Settings is reverting legitimate changes. Cause: Configuration doesn’t reflect desired state. Solution: Update configuration to match requirements:Advanced Configuration
Repository-Specific Drift Handling
Combine scheduled sync with repository restrictions for granular control:deployment-settings.yml
.env
Temporary Drift Allowance
Temporarily disable drift prevention for maintenance:deployment-settings.yml