Skip to content

Credential Management

This document details the credential management practices for Project Aegis.

Directory Structure

All credentials are stored in the ~/.secure/ directory with restricted permissions:

~/.secure/
├── .env                          # Main environment file (600 permissions)
├── api_keys/                     # API key subdirectory
├── aegis_api_key                 # Aegis dashboard API key
├── meshy-api-key                 # Meshy 3D generation API
├── meshy_webhook_secret          # Meshy webhook validation
├── perplexity_api_key            # Perplexity AI API
├── replicate-api-key             # Replicate model inference
├── restic-password               # Backup encryption password
├── service-passwords.txt         # Service passwords index
├── starling-token                # Starling Bank API token
├── stripe.env                    # Stripe API keys
├── stripe-intel-config.json      # Intel dashboard Stripe config
├── stripe-services-config.json   # Services API Stripe config
├── oauth_all_google.py           # Google OAuth helper
└── exchange_all_google.py        # Google token exchange helper

Security: The ~/.secure/ directory has 700 permissions (owner read/write/execute only).

Environment File Structure

~/.secure/.env

The main .env file contains credentials organized by service:

# Z.ai API Configuration (GLM-4.7)
ZAI_API_KEY=<key>
ZAI_BASE_URL=https://api.z.ai/api/anthropic/v1

# Ollama Configuration
OLLAMA_HOST=http://127.0.0.1:11434
OLLAMA_KEEP_ALIVE=5m

# PostgreSQL
POSTGRES_USER=agent
POSTGRES_PASSWORD=agent
POSTGRES_DB=aegis

# Discord
DISCORD_BOT_TOKEN=<token>
DISCORD_GUILD_ID=<guild_id>
DISCORD_CHANNEL_GENERAL=<channel_id>

# GitHub
GITHUB_TOKEN=<personal_access_token>

# Telegram
TELEGRAM_BOT_TOKEN=<token>
TELEGRAM_CHAT_ID=<chat_id>

# Vonage/WhatsApp
VONAGE_API_KEY=<key>
VONAGE_API_SECRET=<secret>
VONAGE_APPLICATION_ID=<app_id>
VONAGE_WHATSAPP_NUMBER=<number>
VONAGE_PRIVATE_KEY_B64=<base64_encoded_private_key>
VONAGE_SIGNATURE_SECRET=<secret>

# Email/Resend
RESEND_API_KEY=<key>

# Perplexity AI
PERPLEXITY_API_KEY=<key>

# Meshy 3D
MESHY_API_KEY=<key>
MESHY_WEBHOOK_SECRET=<secret>

# Stripe (Payment Processing)
STRIPE_SECRET_KEY=<key>
STRIPE_WEBHOOK_SECRET=<secret>
STRIPE_PRICE_DEVELOPER=<price_id>
STRIPE_PRICE_PRO=<price_id>
STRIPE_PRICE_ENTERPRISE=<price_id>

# Anna's Archive
ANNAS_SECRET_KEY=<key>
ANNAS_BASE_URL=https://annas-archive.li

# Knowledge Graph (FalkorDB)
FALKORDB_HOST=host.docker.internal
FALKORDB_PORT=6379

Project-Level .env

A separate .env file exists at /home/agent/projects/aegis-core/.env for project-specific overrides (gitignored).

MCP Server Configuration

MCP servers are configured in ~/.claude.json with inline credentials:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "<token>"
      }
    },
    "discord": {
      "command": "npx",
      "args": ["-y", "mcp-discord"],
      "env": {
        "DISCORD_BOT_TOKEN": "<token>"
      }
    },
    "telegram": {
      "command": "npx",
      "args": ["-y", "@iqai/mcp-telegram"],
      "env": {
        "TELEGRAM_BOT_TOKEN": "<token>"
      }
    },
    "stackwiz": {
      "command": "/home/agent/.local/share/pipx/venvs/stackwiz-mcp/bin/stackwiz-mcp",
      "env": {
        "STACKWIZ_CF_API_TOKEN": "<cloudflare_token>",
        "STACKWIZ_BASE_DIR": "/home/agent/stacks",
        "STACKWIZ_DEFAULT_DOMAIN": "rbnk.uk"
      }
    }
  }
}

API Key Rotation

Procedure

  1. Generate new key from service provider
  2. Update in ~/.secure/.env (or specific key file)
  3. Update in ~/.claude.json if MCP-related
  4. Restart affected services:
    cd /home/agent/projects/aegis-core && docker compose restart
    
  5. Verify functionality with health checks
  6. Revoke old key from service provider
  7. Document rotation in /home/agent/memory/security/key-rotation.jsonl

Rotation Schedule

Service Frequency Last Rotated
GitHub PAT 90 days Check token expiry
Discord Bot Annually On compromise
Telegram Bot Annually On compromise
Stripe Keys Manually On security event
Z.ai API Key Quarterly Based on usage
Vonage Keys Manually On security event

Docker Compose Secret Injection

Services receive credentials via environment variables loaded from .env:

services:
  dashboard:
    environment:
      - STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY:-}
      - VONAGE_API_KEY=${VONAGE_API_KEY:-}
      - GITHUB_TOKEN=${GITHUB_TOKEN:-}

The :- syntax provides empty fallback if variable is unset (prevents container crashes).

Never Commit Secrets Policy

Protected Files

The following patterns are automatically blocked by the block-sensitive-files.py hook:

  • *.pem (SSL certificates, private keys)
  • *.key (Private keys)
  • id_rsa, id_ed25519 (SSH keys)
  • .env, .env.* (Environment files) - warned but allowed for config work
  • Files in /.secure/ - warned but allowed for automation
  • credentials, *credentials* - warned but allowed
  • .claude.json - warned but allowed for MCP setup

Git Configuration

.gitignore patterns:

# Credentials
.env
.env.*
.secure/
*credentials*
*.pem
*.key
id_rsa*
id_ed25519*

# MCP config with inline tokens
.claude.json

Pre-Commit Verification

Before committing:

  1. Run git diff and manually review for secrets
  2. Check that hook didn't warn about sensitive files
  3. Verify .gitignore catches new credential files
  4. Use git-secrets or gitleaks for automated scanning (optional)

Service-Specific Credentials

GitHub Personal Access Token

Scopes required: - repo (full control of private repositories) - workflow (update GitHub Actions workflows) - read:org (read org and team membership)

Located: ~/.secure/.env (GITHUB_TOKEN)

Discord Bot Token

Permissions required: - Send Messages - Read Message History - Embed Links

Located: ~/.secure/.env (DISCORD_BOT_TOKEN)

Vonage/WhatsApp

Multi-component authentication: - VONAGE_API_KEY - Account API key - VONAGE_API_SECRET - Account API secret - VONAGE_APPLICATION_ID - Messages API application - VONAGE_PRIVATE_KEY_B64 - Base64-encoded private key for JWT signing - VONAGE_SIGNATURE_SECRET - Webhook signature validation

Located: ~/.secure/.env

Stripe API Keys

Separate keys for test and production: - STRIPE_SECRET_KEY - Main secret key (live mode) - STRIPE_WEBHOOK_SECRET - Webhook signature validation - STRIPE_PRICE_* - Price IDs for subscription tiers

Located: ~/.secure/stripe.env (loaded by dashboard)

Emergency Response

If Credentials Are Compromised

  1. IMMEDIATELY revoke the compromised key/token from the service provider
  2. Generate a new credential
  3. Update in ~/.secure/.env and ~/.claude.json
  4. Restart services: cd /home/agent/projects/aegis-core && docker compose restart
  5. Document incident in /home/agent/memory/security/incidents.jsonl
  6. Post to Discord #alerts channel
  7. Review recent logs for suspicious activity:
    tail -100 /home/agent/memory/security/mcp-audit.jsonl
    grep -i "error\|unauthorized" /home/agent/projects/aegis-core/logs/*.log
    

Incident Template

{
  "timestamp": "2026-01-25T12:00:00Z",
  "severity": "critical|high|medium|low",
  "credential_type": "github_token|discord_bot|etc",
  "impact": "Description of exposure",
  "response": [
    "Revoked key at 12:05 UTC",
    "Generated new key at 12:10 UTC",
    "Services restarted at 12:15 UTC"
  ],
  "root_cause": "Accidental commit|Log exposure|etc",
  "prevention": "Added .gitignore rule|Implemented hook|etc"
}

Best Practices

  1. Least Privilege: Request minimum scopes needed for each API token
  2. Expiration: Use short-lived tokens when supported (e.g., GitHub PAT expiry)
  3. Rotation: Rotate critical keys quarterly, all keys annually
  4. Isolation: Never share credentials between environments (dev/prod)
  5. Audit Logging: All credential usage is logged to ~/memory/security/mcp-audit.jsonl
  6. Backup Security: Encrypted backups use ~/.secure/restic-password
  7. No Hardcoding: Never hardcode credentials in source files
  8. MCP Audit: Review MCP security audit logs weekly for anomalies
  9. Access Review: Quarterly review of which services have access to what
  10. Documentation: Update this file when adding new credential types

Audit Trail

All credential access via MCP tools is logged by the mcp-security-audit.py hook:

{
  "timestamp": "2026-01-25T12:00:00Z",
  "session_id": "abc123",
  "mcp_server": "github",
  "operation": "create_repository",
  "risk_level": "medium",
  "flagged": false
}

Location: ~/memory/security/mcp-audit.jsonl

Review flagged operations:

jq 'select(.flagged == true)' ~/memory/security/mcp-audit.jsonl