DriftHound can be configured using environment variables for deployment flexibility. This guide covers all available configuration options.
The base URL where DriftHound is hosted. Used for generating links in Slack notifications.
Required: Recommended for production
Default: http://localhost:3000
Example: https://drifthound.example.com
APP_URL=https://drifthound.example.comUsage:
- Generates clickable "View in DriftHound" buttons in Slack notifications
- Should match your actual domain (without trailing slash)
The Rails environment to run in.
Required: No
Default: development
Options: development, test, production
RAILS_ENV=productionControls the verbosity of application logs.
Required: No
Default: info
Options: debug, info, warn, error, fatal
RAILS_LOG_LEVEL=infoRecommendations:
infofor production (default)debugfor troubleshooting (includes SQL queries and detailed logs)warnorerrorfor high-traffic deployments
Rails secret key used for encrypting sessions, cookies, and other sensitive data.
Required: Yes (production only) Format: 128-character hexadecimal string (64 bytes)
SECRET_KEY_BASE=your-generated-secret-key-baseHow to generate:
# Using OpenSSL (recommended)
openssl rand -hex 64
# Or using Rails (requires working bundle)
bin/rails secretSecurity Notes:
- Never commit this to version control
- Use a secrets management system (e.g., sops, AWS Secrets Manager, HashiCorp Vault)
- Changing this value will invalidate all existing sessions and encrypted data
- Each environment should use a different secret
Controls whether DriftHound requires authentication for viewing content.
Required: No
Default: false (private - authentication required)
Options: true, false
# Private mode (default) - requires login to view anything
PUBLIC_MODE=false
# Public mode - anyone can view dashboard, projects, environments
PUBLIC_MODE=trueBehavior:
| Mode | Dashboard | Projects | Environments | Checks | Admin Actions |
|---|---|---|---|---|---|
Private (false) |
🔒 Login required | 🔒 Login required | 🔒 Login required | 🔒 Login required | 🔒 Admin only |
Public (true) |
✅ Public | ✅ Public | ✅ Public | ✅ Public | 🔒 Admin only |
Notes:
- Private by default - New deployments require authentication out of the box
- Admin actions (delete projects/environments, user management, API tokens) always require authentication regardless of this setting
- Use public mode for internal dashboards where authentication would add friction
- Use private mode for sensitive infrastructure data or external-facing deployments
Use cases:
- Private mode (recommended): Production deployments, sensitive infrastructure data, compliance requirements
- Public mode: Internal team dashboards, demo instances, open-source project monitoring
DriftHound includes a web-based admin authentication system to protect destructive operations like deleting projects and environments. Admin credentials are configured via environment variables.
Email address for the admin user account.
Required: Yes (production only) Example:
ADMIN_EMAIL=admin@example.comPassword for the admin user account.
Required: Yes (production only) Minimum: 6 characters Example:
ADMIN_PASSWORD=your-secure-passwordDevelopment:
- Run
rails db:seedto create an admin user with defaults (admin/changeme) - Or set
ADMIN_EMAILandADMIN_PASSWORDbefore seeding for custom credentials
Production:
- Both
ADMIN_EMAILandADMIN_PASSWORDenvironment variables are required - The admin user is created automatically during
rails db:migrate - If credentials are not provided, both migration and app boot will fail with an error
# Production deployment
ADMIN_EMAIL=admin@example.com ADMIN_PASSWORD=secure_password rails db:migrate- Never use default credentials in production - The migration will fail if you don't provide credentials
- Use strong passwords - Minimum 6 characters, but longer is better
- Store credentials securely - Use environment variables, secrets managers, or encrypted configs
- Admin credentials can be updated by running the migration again with new ENV values (upsert behavior)
When logged in as admin, you can:
- Delete projects (cascades to all environments and drift checks)
- Delete environments (cascades to all drift checks)
Read-only operations (viewing dashboard, projects, environments, drift history) do not require authentication.
Access the login page at /login. After successful authentication, you'll be redirected to the dashboard with access to admin actions.
DriftHound supports GitHub OAuth for team-based authentication. Users can sign in with their GitHub account and be automatically assigned roles based on their GitHub team membership.
Set the following environment variables to enable GitHub OAuth:
GITHUB_OAUTH_ENABLED=true
GITHUB_CLIENT_ID=your-github-app-client-id
GITHUB_CLIENT_SECRET=your-github-app-client-secret
GITHUB_ORG=your-organization-nameMap GitHub teams to DriftHound roles using these environment variables. You can specify multiple teams per role using comma-separated values:
# Single team per role
GITHUB_TEAM_ADMIN=platform-admins
GITHUB_TEAM_EDITOR=platform-editors
GITHUB_TEAM_VIEWER=platform-viewers
# Multiple teams per role (comma-separated)
GITHUB_TEAM_ADMIN=platform-admins,security-team,devops-leads
GITHUB_TEAM_EDITOR=developers,contractors
GITHUB_TEAM_VIEWER=read-only,auditorsNotes:
- At least one team mapping must be configured
- Multiple teams can be assigned to the same role using commas (e.g.,
team1,team2,team3) - Team slugs are case-insensitive
- If a user belongs to multiple mapped teams with different roles, they receive the highest privilege role
- Users not in any configured team will be denied access
- Go to your GitHub organization settings
- Navigate to Developer settings > OAuth Apps > New OAuth App
- Configure the application:
- Application name: DriftHound (or your preferred name)
- Homepage URL: Your DriftHound instance URL (e.g.,
https://drifthound.example.com) - Authorization callback URL:
https://drifthound.example.com/auth/github/callback
- After creating, copy the Client ID and generate a Client Secret
The OAuth app requires access to:
- User's email address (
user:emailscope) - User's organization team memberships (
read:orgscope)
Users will be prompted to authorize these permissions when signing in.
- User clicks "Sign in with GitHub" on the login page
- User is redirected to GitHub to authorize access
- After authorization, GitHub redirects back to DriftHound with an auth code
- DriftHound exchanges the code for an access token
- DriftHound fetches the user's profile and team memberships
- Role is determined based on team mappings (highest privilege wins)
- User account is created (if new) or updated with the mapped role
- User is logged in and redirected to the dashboard
Users authenticated via OAuth can also set a password for traditional email/password login. This allows flexibility in how users access the system.
# GitHub OAuth - Basic (single team per role)
GITHUB_OAUTH_ENABLED=true
GITHUB_CLIENT_ID=Iv1.a1b2c3d4e5f6g7h8
GITHUB_CLIENT_SECRET=secret123456789abcdef
GITHUB_ORG=my-company
GITHUB_TEAM_ADMIN=infrastructure-admins
GITHUB_TEAM_EDITOR=infrastructure-team
GITHUB_TEAM_VIEWER=developers
# GitHub OAuth - Advanced (multiple teams per role)
GITHUB_OAUTH_ENABLED=true
GITHUB_CLIENT_ID=Iv1.a1b2c3d4e5f6g7h8
GITHUB_CLIENT_SECRET=secret123456789abcdef
GITHUB_ORG=my-company
GITHUB_TEAM_ADMIN=infrastructure-admins,security-team
GITHUB_TEAM_EDITOR=infrastructure-team,platform-engineers,sre
GITHUB_TEAM_VIEWER=developers,contractorsDriftHound uses PostgreSQL and supports multiple databases for different concerns (primary, cache, queue, cable).
PostgreSQL password for the production database.
Required: Yes (production only) Example:
DRIFTHOUND_DATABASE_PASSWORD=your-secure-passwordYou can also provide a full PostgreSQL connection URL instead of individual settings.
Required: No (alternative to individual settings) Example:
DATABASE_URL=postgresql://username:password@host:port/database_nameMaximum number of database connections per process.
Required: No
Default: 5
Example:
RAILS_MAX_THREADS=5Note: This affects database connection pool size. Adjust based on your workload and available database connections.
Database settings are defined in config/database.yml:
Development:
- Host:
localhost:5432 - Database:
drifthound_development - Username:
drifthound - Password:
drifthound
Production:
- Database:
drifthound_production- Single database for all application data - Username:
drifthound - Password: Set via
DRIFTHOUND_DATABASE_PASSWORD
Note: DriftHound uses in-memory adapters for caching and background jobs. This keeps the setup simple and is sufficient for low to medium traffic applications. Only one database is needed.
DriftHound automatically manages drift check data retention to prevent unbounded database growth while maintaining sufficient historical data for trend analysis and charts.
Number of days to retain drift check history per environment.
Required: No
Default: 90
Example:
DRIFT_CHECK_RETENTION_DAYS=90Behavior:
- Drift checks older than this number of days are automatically deleted when new checks are created
- Retention is enforced per-environment (each environment maintains its own history)
- Set to
0to disable retention and keep all checks indefinitely
Recommended values based on check frequency:
| Check Frequency | Recommended Retention | Approximate Checks/Env |
|---|---|---|
| Multiple per day | 30-60 days | 120-240+ checks |
| Once daily | 90 days (default) | ~90 checks |
| Weekly | 180-365 days | 26-52 checks |
Storage considerations:
- Each drift check consumes approximately 1-2 KB of database storage
- With 100 environments running daily checks at 90-day retention: ~9,000 checks (~18 MB)
- Adjust based on your number of environments and check frequency
Example configurations:
# Default: 90 days (recommended for most users)
DRIFT_CHECK_RETENTION_DAYS=90
# Short retention for high-frequency checking
DRIFT_CHECK_RETENTION_DAYS=30
# Long retention for weekly checks
DRIFT_CHECK_RETENTION_DAYS=365
# Disable retention (keep all checks forever)
DRIFT_CHECK_RETENTION_DAYS=0DriftHound can send Slack notifications when drift is detected. Configuration can be done via environment variables or config/notifications.yml.
Enable or disable Slack notifications globally.
Required: Yes (to enable Slack)
Default: false
Example:
SLACK_NOTIFICATIONS_ENABLED=trueYour Slack Bot User OAuth Token.
Required: Yes (if Slack is enabled)
Format: Starts with xoxb-
Example:
SLACK_BOT_TOKEN=xoxb-your-slack-bot-tokenHow to get a token:
- Go to https://api.slack.com/apps
- Create a new app or select an existing one
- Navigate to "OAuth & Permissions"
- Add the following Bot Token Scopes:
chat:write- Post messageschat:write.public- Post to public channels without joiningchat:write.customize- Message format customization
- Install the app to your workspace
- Copy the "Bot User OAuth Token"
Default Slack channel for drift notifications.
Required: No
Default: #infrastructure-drift
Format: Channel name with # prefix
Example:
SLACK_DEFAULT_CHANNEL=#infra-alertsNote: This can be overridden per-environment via the API or CLI using the --slack-channel flag.
Controls whether notifications are sent on the first drift check for new environments.
Required: No
Default: false
Example:
NOTIFY_ON_FIRST_CHECK=trueBehavior:
By default, new environments start with unknown status. The first drift check establishes a baseline and does not trigger notifications. This prevents notification spam when onboarding many environments.
When set to true, DriftHound will send notifications immediately if the first check detects drift or an error:
| First Check Result | false (default) |
true |
|---|---|---|
unknown → ok |
No notification | No notification |
unknown → drift |
No notification | Drift Detected |
unknown → error |
No notification | Error Detected |
Use cases for enabling:
- You want immediate alerts when adding new infrastructure monitoring
- Your environments should never have drift on first check
- You prefer proactive alerting over baseline establishment
Alternatively, you can configure notifications in config/notifications.yml. Environment variables take precedence and are interpolated in the YAML file.
📖 See Slack Notifications Guide for detailed setup instructions.
DriftHound uses Puma as its web server.
The port the web server listens on.
Required: No
Default: 3000
Example:
PORT=8080Number of threads per Puma worker.
Required: No
Default: 3
Example:
RAILS_MAX_THREADS=5Number of Puma worker processes.
Required: No
Default: 0 (single process mode)
Example:
WEB_CONCURRENCY=2Recommendations:
- Set to number of CPU cores for production
- Each worker consumes additional memory
- Not needed for small deployments
In production, DriftHound logs to STDOUT with request ID tagging for easy integration with log aggregation services (e.g., CloudWatch, Datadog, Splunk).
The /up health check endpoint is silenced by default to prevent log clutter. This is configured in config/environments/production.rb:
config.silence_healthcheck_path = "/up"DriftHound uses Rails' async adapter for background job processing. This means:
- Jobs (like sending Slack notifications) run in background threads within the web process
- No separate job processor or database is needed
- Simple deployment with automatic job processing
- Jobs are lost if the process crashes before completion (acceptable for notifications)
Note: For high-traffic applications where job durability is critical, you may want to switch to Solid Queue or Sidekiq in the future.
Create a .env file or configure your deployment platform with these variables:
# Application
RAILS_ENV=production
APP_URL=https://drifthound.example.com
RAILS_LOG_LEVEL=info
SECRET_KEY_BASE=340b6113695da1baed5d5b7945bff4dc4ab86b75f602c5183624c1b87ffc17d192c18572196456bc3242b13ebf74ab75053c9c87ee2202d2718fbfe85e2ff94a
# Access Control (private by default)
PUBLIC_MODE=false
# Admin Authentication (required in production)
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=your-secure-admin-password
# GitHub OAuth (optional)
GITHUB_OAUTH_ENABLED=true
GITHUB_CLIENT_ID=your-github-client-id
GITHUB_CLIENT_SECRET=your-github-client-secret
GITHUB_ORG=your-organization
# Multiple teams per role supported (comma-separated)
GITHUB_TEAM_ADMIN=platform-admins,security-team
GITHUB_TEAM_EDITOR=platform-editors,developers
GITHUB_TEAM_VIEWER=read-only
# Database
DRIFTHOUND_DATABASE_PASSWORD=your-secure-db-password
# Data Retention
DRIFT_CHECK_RETENTION_DAYS=90
# Slack Notifications
SLACK_NOTIFICATIONS_ENABLED=true
SLACK_BOT_TOKEN=xoxb-your-slack-bot-token
SLACK_DEFAULT_CHANNEL=#infrastructure-drift
NOTIFY_ON_FIRST_CHECK=false
# Web Server
PORT=3000
RAILS_MAX_THREADS=5
WEB_CONCURRENCY=2After configuration, verify your setup:
curl http://localhost:3000/upShould return 200 OK.
# Create a token via the web UI:
# 1. Log in as admin at /login
# 2. Navigate to API Tokens in the navigation bar
# 3. Create a new token and copy it
# Test API call
curl -X POST http://localhost:3000/api/v1/projects/test/environments/dev/checks \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "ok"}'Check Rails logs for notification configuration:
bin/rails runner "puts Rails.application.config.notifications.inspect"# Test database connection
bin/rails runner "puts ActiveRecord::Base.connection.execute('SELECT 1').to_a"# Check Slack configuration
bin/rails runner "puts Rails.application.config.notifications[:slack].inspect"
# Test Slack connection manually
bin/rails console
> client = Slack::Web::Client.new(token: ENV['SLACK_BOT_TOKEN'])
> client.chat_postMessage(channel: '#test', text: 'Test message')# Change the port
PORT=8080 bin/rails server- Slack Notifications Setup - Detailed Slack configuration guide
- API Usage - API token management
- CLI Usage - Using environment variables with the CLI