Enhanced .gitignore to protect: - Configuration files with secrets (config.yaml, .env files) - Mastodon credential files (*_clientcred.secret, *_usercred.secret) - API keys and tokens (*.key, *.token, *.pem, credentials.json) - Database files (may contain user data) - Backup files (may contain sensitive data) - LLM API key directories (.llm/, .openai/, .anthropic/) Added SECURITY.md documentation covering: - Where secrets are stored - What is/isn't committed to git - Best practices for credential management - Production secret management options - What to do if secrets are accidentally committed - Pre-commit hook examples - Security audit checklist Verified all patterns with test suite - all sensitive files properly ignored. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
7.8 KiB
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:
-
Platform Credentials
- Mastodon access tokens
- Discord bot tokens
- Telegram bot tokens
- OAuth client secrets
-
AI Model API Keys
- OpenAI API keys
- Anthropic (Claude) API keys
- Other cloud LLM providers
-
Governance Data
- Vote records
- User actions
- Audit logs (in database)
-
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.
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:
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
# 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
# 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
# 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
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:
# Use a text editor
nano config/config.yaml
# Or use environment variable editor
export EDITOR=nano
Step 3: Verify It's Ignored
git status
# Should NOT show config/config.yaml as untracked
Best Practices
1. Never Hard-Code Secrets
❌ Bad - Hard-coding in source files:
# DON'T DO THIS!
access_token = "abc123secret"
✅ Good - Load from config:
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:
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:
# Set restrictive permissions on config
chmod 600 config/config.yaml
# Don't share your config directory
Production server:
# 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:
services:
govbot:
secrets:
- mastodon_token
- openai_key
Kubernetes Secrets:
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:
[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
# 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:
-
Rotate the secret immediately - Consider it compromised
- Generate new Mastodon access token
- Create new API keys
- Update your local config
-
Remove from git history (advanced):
# 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 -
Notify collaborators to pull fresh history
-
Check access logs for unauthorized use
Secure Development Workflow
Daily Development
# 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
# 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:
#!/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:
chmod +x .git/hooks/pre-commit
Audit Checklist
Run this before going to production:
config/config.yamlis in.gitignore- No secrets in git history:
git log -p | grep -i "token" - Config file has restrictive permissions:
ls -la config/ .envfiles 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
Questions?
If you suspect a security issue:
- Rotate affected credentials immediately
- Check access logs
- Open a security issue (mark as security vulnerability)
Remember: It's better to be paranoid about secrets than to have them leaked!