# Security Runbook ## Security model The service supports three auth modes via `AUTH_MODE`: - `api_key`: static shared secret (`AGENT_API_KEY`) - `jwt`: bearer JWT with scope checks - `hybrid`: API key accepted first, then JWT fallback The same backend is used across: - REST API - A2A adapter - MCP tools MCP can override auth mode independently with `MCP_AUTH_MODE`: - `inherit` (default): use `AUTH_MODE` - `api_key|jwt|hybrid|oauth`: MCP-only override - In `oauth` mode, set `MCP_RESOURCE_SERVER_URL` to the public MCP URL and keep it HTTPS ## Recommended deployment posture External traffic: - Use `AUTH_MODE=jwt` - Require HTTPS at reverse proxy/gateway - Restrict exposed routes to required protocol endpoints - For MCP connectors, `MCP_AUTH_MODE=oauth` is recommended Internal traffic: - `AUTH_MODE=hybrid` is acceptable during migration - Prefer mTLS/private network for service-to-service traffic ## Scope matrix - `availability:read`: availability access - `available_meeting_intervals:read`: suggested meeting intervals access - `mail:scan`: inbox scan and triage - `unsubscribe:read`: candidate discovery - `unsubscribe:execute`: unsubscribe execution - `unsubscribe:digest`: digest scan and send ## Secret and token handling Never commit secrets: - `.env` - `token.json` - Google OAuth client secret files Always persist and back up: - `token.json` - `data/sent_unsubscribe_links.json` - `data/unsubscribed_methods.json` ## Key and token rotation ### API key rotation (api_key/hybrid) 1. Generate new strong key. 2. Update environment (`AGENT_API_KEY`) in deployment. 3. Restart services. 4. Update all clients. 5. Remove old key from all stores. ### JWT secret rotation (jwt/hybrid) 1. Generate new signing secret. 2. Roll out issuer/signing config first. 3. Update server `AUTH_JWT_SECRET`. 4. Restart services. 5. Force token refresh for clients. ## Incident response checklist If credential leak is suspected: 1. Revoke compromised key/secret immediately. 2. Rotate API key and JWT secret. 3. Invalidate active tokens (issuer-side). 4. Review logs for unusual scans/unsubscribe operations. 5. Disable mutation MCP tools (`MCP_ENABLE_MUTATION_TOOLS=false`) until investigation completes. 6. Re-enable features after containment and verification. ## Release rollout checklist Preflight: 1. `uv run pytest -q` 2. `uv run python -c "import app.main, app.mcp_main; print('import_ok')"` 3. `docker compose config --services` Canary: 1. Deploy to one node/environment. 2. Validate: - `GET /health` - `GET /.well-known/agent-card.json` - A2A `SendMessage` - MCP tool listing 3. Monitor errors for 30-60 minutes. Full rollout: 1. Deploy all nodes. 2. Re-run smoke checks. 3. Confirm scheduler jobs continue as expected. Rollback: 1. Redeploy previous image/tag. 2. Verify health and protocol smoke checks. 3. Keep state files (`data/*.json`) unchanged during rollback.