# Security Guide This document explains how to handle sensitive data securely when using Govbot. ## Sensitive Data in Govbot Govbot handles several types of sensitive information: 1. **Platform Credentials** - Mastodon access tokens - Discord bot tokens - Telegram bot tokens - OAuth client secrets 2. **AI Model API Keys** - OpenAI API keys - Anthropic (Claude) API keys - Other cloud LLM providers 3. **Governance Data** - Vote records - User actions - Audit logs (in database) 4. **Instance Configuration** - Admin credentials - Database passwords (if applicable) - Secret keys ## Where Secrets Are Stored ### Configuration File **Primary location**: `config/config.yaml` This file contains all your credentials and should **NEVER be committed to git**. ```yaml platform: type: mastodon mastodon: instance_url: https://your-instance.social access_token: YOUR_SECRET_TOKEN_HERE # ← SECRET! client_secret: YOUR_CLIENT_SECRET # ← SECRET! ``` **Protection**: Already in `.gitignore` (line 36) ### Environment Variables Alternative to config file, you can use environment variables: ```bash export GOVBOT_PLATFORM__MASTODON__ACCESS_TOKEN="your_token" export GOVBOT_PLATFORM__MASTODON__CLIENT_SECRET="your_secret" ``` **Protection**: `.env` files are in `.gitignore` (line 37) ### LLM API Keys The `llm` CLI tool stores API keys in `~/.llm/keys.json` ```bash # Set API keys llm keys set openai llm keys set anthropic ``` **Protection**: `.llm/` directory is in `.gitignore` (line 48) ### Database The SQLite database (`govbot.db`) contains: - All governance actions - Vote records - User information - Audit trail **Protection**: `*.db` files are in `.gitignore` (line 40) ## What IS Committed to Git These files are safe to commit and are already in the repository: ✅ `config/config.example.yaml` - Template with placeholder values ✅ `constitution.md` - Your governance rules (usually public) ✅ `README.md` and other documentation ✅ All Python source code ✅ `.gitignore` - Protects your secrets ## Verification ### Check What's Ignored ```bash # See what files git is ignoring git status --ignored # Check if a specific file would be ignored git check-ignore -v config/config.yaml ``` ### Test Before Committing ```bash # List files that would be committed git status # If you see any of these, STOP: # - config/config.yaml # - *.token, *.key, *.secret files # - .env files # - govbot.db ``` ## Creating Your Config File ### Step 1: Copy Template ```bash cp config/config.example.yaml config/config.yaml ``` The copied file (`config.yaml`) is automatically ignored by git. ### Step 2: Add Your Secrets Edit `config/config.yaml` with your actual credentials: ```bash # Use a text editor nano config/config.yaml # Or use environment variable editor export EDITOR=nano ``` ### Step 3: Verify It's Ignored ```bash git status # Should NOT show config/config.yaml as untracked ``` ## Best Practices ### 1. Never Hard-Code Secrets ❌ **Bad** - Hard-coding in source files: ```python # DON'T DO THIS! access_token = "abc123secret" ``` ✅ **Good** - Load from config: ```python access_token = config.platform.mastodon.access_token ``` ### 2. Use Different Secrets for Different Environments ``` config/ ├── config.example.yaml # Template (committed) ├── config.yaml # Production (NOT committed) ├── config.dev.yaml # Development (NOT committed) └── config.test.yaml # Testing (NOT committed) ``` Load different configs: ```bash python -m src.govbot --config config/config.dev.yaml ``` ### 3. Rotate Tokens Periodically - Change access tokens every 3-6 months - Rotate immediately if compromised - Use separate tokens for testing vs. production ### 4. Limit Token Scopes Only grant the permissions you need: **Mastodon**: - ✅ `read`, `write` - Basic operation - ✅ `admin:read`, `admin:write` - Only if bot needs admin powers - ❌ Don't grant scopes you don't use **OpenAI/Anthropic**: - Set usage limits on API keys - Use separate keys for development vs. production ### 5. Secure Your Environment **Development machine**: ```bash # Set restrictive permissions on config chmod 600 config/config.yaml # Don't share your config directory ``` **Production server**: ```bash # Use a service account sudo useradd -r -s /bin/false govbot # Restrict file access chown govbot:govbot config/config.yaml chmod 400 config/config.yaml ``` ### 6. Use Secret Management (Production) For production deployments, consider: **Docker Secrets**: ```yaml services: govbot: secrets: - mastodon_token - openai_key ``` **Kubernetes Secrets**: ```bash kubectl create secret generic govbot-secrets \ --from-literal=mastodon-token=your_token ``` **Cloud Provider Secret Managers**: - AWS Secrets Manager - GCP Secret Manager - Azure Key Vault - HashiCorp Vault **Environment variables in systemd**: ```ini [Service] Environment="GOVBOT_PLATFORM__MASTODON__ACCESS_TOKEN=your_token" EnvironmentFile=/etc/govbot/secrets.env ``` ## What If I Accidentally Commit a Secret? ### If You Haven't Pushed Yet ```bash # Remove the file from git (but keep it locally) git rm --cached config/config.yaml # Amend the commit git commit --amend # Verify it's gone git show ``` ### If You Already Pushed **You must:** 1. **Rotate the secret immediately** - Consider it compromised - Generate new Mastodon access token - Create new API keys - Update your local config 2. **Remove from git history** (advanced): ```bash # Use BFG Repo-Cleaner or git-filter-branch # See: https://rtyley.github.io/bfg-repo-cleaner/ bfg --replace-text passwords.txt git reflog expire --expire=now --all git gc --prune=now --aggressive git push --force ``` 3. **Notify collaborators** to pull fresh history 4. **Check access logs** for unauthorized use ## Secure Development Workflow ### Daily Development ```bash # 1. Pull latest code git pull # 2. Ensure config exists (one time) if [ ! -f config/config.yaml ]; then cp config/config.example.yaml config/config.yaml echo "⚠️ Edit config/config.yaml with your credentials" exit 1 fi # 3. Run the bot python -m src.govbot ``` ### Before Every Commit ```bash # Check what you're committing git status git diff --cached # Verify no secrets git diff --cached | grep -i "token\|secret\|password\|key" # If anything matches, DON'T COMMIT ``` ### Pre-commit Hook (Optional) Create `.git/hooks/pre-commit`: ```bash #!/bin/bash # Check for potential secrets if git diff --cached | grep -iE "(token|secret|password|api[_-]?key)" | grep -v "example"; then echo "⚠️ WARNING: Potential secret detected in commit!" echo "Review your changes carefully." exit 1 fi ``` Make it executable: ```bash chmod +x .git/hooks/pre-commit ``` ## Audit Checklist Run this before going to production: - [ ] `config/config.yaml` is in `.gitignore` - [ ] No secrets in git history: `git log -p | grep -i "token"` - [ ] Config file has restrictive permissions: `ls -la config/` - [ ] `.env` files are ignored - [ ] Database is not committed - [ ] API keys are rotated from development - [ ] Tokens have minimal required scopes - [ ] Production uses separate credentials from dev - [ ] Backup strategy excludes secrets or encrypts them - [ ] Team knows not to commit secrets ## Resources - [GitHub's Secret Scanning](https://docs.github.com/en/code-security/secret-scanning) - [OWASP Secrets Management Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html) - [12 Factor App: Config](https://12factor.net/config) ## Questions? If you suspect a security issue: 1. Rotate affected credentials immediately 2. Check access logs 3. Open a security issue (mark as security vulnerability) **Remember**: It's better to be paranoid about secrets than to have them leaked!