Files
vm-cloudflare/MULTI_ACCOUNT_AUTH.md
Vault Sovereign f0b8d962de
Some checks failed
WAF Intelligence Guardrail / waf-intel (push) Waiting to run
Cloudflare Registry Validation / validate-registry (push) Has been cancelled
chore: pre-migration snapshot
Layer0, MCP servers, Terraform consolidation
2025-12-27 01:52:27 +00:00

11 KiB
Raw Blame History

Multiple Accounts Configuration 🔐

Overview

This project supports multiple accounts for the same service:

  • Multiple GitHub accounts (personal, work, alt)
  • Multiple Cloudflare accounts (prod, staging, dev)
  • Multiple GitLab instances (internal, external)

Each account is:

  1. Bound to a unique environment variable name, and
  2. Exposed as a separate MCP server in opencode.jsonc.

🔒 Security Note: Never commit tokens to git. Keep them in your shell environment, a .env file that is .gitignored, or a secrets manager.


1. Export Tokens with Unique Variable Names

Use descriptive names that encode both service and purpose.

Pattern:
<SERVICE>_<RESOURCE>_<ENV or PURPOSE>

Examples:

  • GITHUB_TOKEN_WORK
  • CLOUDFLARE_API_TOKEN_PRODUCTION
  • GITLAB_TOKEN_INTERNAL

Shell Export (for session-based or profile)

# GitHub  multiple accounts
export GITHUB_TOKEN_SECONDARY="ghp_another_token_here"
export GITHUB_TOKEN_WORK="ghp_work_account_token"
export GITHUB_TOKEN_PERSONAL="ghp_personal_account_token"

# Cloudflare  multiple accounts
export CLOUDFLARE_API_TOKEN_PRODUCTION="prod_token_here"
export CLOUDFLARE_ACCOUNT_ID_PRODUCTION="prod_account_id"

export CLOUDFLARE_API_TOKEN_STAGING="staging_token_here"
export CLOUDFLARE_ACCOUNT_ID_STAGING="staging_account_id"

# GitLab  multiple instances
export GITLAB_TOKEN_INTERNAL="glpat_internal_token"
export GITLAB_URL_INTERNAL="https://gitlab.internal.company.com"

export GITLAB_TOKEN_EXTERNAL="glpat_external_token"
export GITLAB_URL_EXTERNAL="https://gitlab.com"
# .env (remember to add this to .gitignore)
CLOUDFLARE_API_TOKEN_PRODUCTION=prod_token
CLOUDFLARE_ACCOUNT_ID_PRODUCTION=prod_account_id

CLOUDFLARE_API_TOKEN_STAGING=staging_token
CLOUDFLARE_ACCOUNT_ID_STAGING=staging_account_id

Then load in shell:

set -a
source .env
set +a

2. Add MCP Entries in opencode.jsonc

Each account becomes its own MCP entry, wired to its own env vars:

// Secondary GitHub account
"github_secondary": {
  "type": "local",
  "command": ["npx", "-y", "@modelcontextprotocol/server-github"],
  "environment": {
    "GITHUB_PERSONAL_ACCESS_TOKEN": "{env:GITHUB_TOKEN_SECONDARY}"
  },
  "enabled": false
},

// Production Cloudflare account
"cloudflare_prod": {
  "type": "local",
  "command": ["python3", "-m", "mcp.cloudflare_safe"],
  "environment": {
    "CLOUDFLARE_API_TOKEN": "{env:CLOUDFLARE_API_TOKEN_PRODUCTION}",
    "CLOUDFLARE_ACCOUNT_ID": "{env:CLOUDFLARE_ACCOUNT_ID_PRODUCTION}"
  },
  "enabled": false
},

// Staging Cloudflare account
"cloudflare_staging": {
  "type": "local",
  "command": ["python3", "-m", "mcp.cloudflare_safe"],
  "environment": {
    "CLOUDFLARE_API_TOKEN": "{env:CLOUDFLARE_API_TOKEN_STAGING}",
    "CLOUDFLARE_ACCOUNT_ID": "{env:CLOUDFLARE_ACCOUNT_ID_STAGING}"
  },
  "enabled": false
},

// Internal GitLab instance
"gitlab_internal": {
  "type": "local",
  "command": ["npx", "-y", "@modelcontextprotocol/server-gitlab"],
  "environment": {
    "GITLAB_TOKEN": "{env:GITLAB_TOKEN_INTERNAL}",
    "GITLAB_URL": "{env:GITLAB_URL_INTERNAL}"
  },
  "enabled": false
}

Recommended: Enable accounts per agent for isolation.

"agents": {
  "cloudflare-ops": {
    "tools": {
      "cloudflare_prod": true,      // Production account
      "cloudflare_staging": true,    // Staging account
      "github_secondary": true,      // Secondary GitHub
      "gitlab_internal": true        // Internal GitLab
    }
  },
  "security-audit": {
    "tools": {
      "cloudflare_prod": true,       // Only production for audits
      "github_secondary": false      // Disable secondary for security
    }
  }
}

Global enable (less strict, use sparingly):

"tools": {
  "cloudflare_prod": true,
  "github_secondary": true
}

🔑 Principle: Production credentials should only be wired into a few, tightly-scoped agents (e.g., cloudflare-ops, security-audit), not "playground" agents.


4. Best Practices

Naming Conventions

Use suffixes that make intent obvious:

  • _PRODUCTION / _PROD Production environment
  • _STAGING / _STAGE Staging environment
  • _DEVELOPMENT / _DEV Development environment
  • _INTERNAL Internal/private instance
  • _EXTERNAL External/public instance
  • _WORK / _PERSONAL Work vs personal identity
  • _SECONDARY / _BACKUP Secondary/backup account

Security Isolation

  1. Per-agent configuration Only give each agent the accounts it truly needs
  2. Environment separation Different tokens per environment (prod / stage / dev)
  3. Least privilege Grant minimal scopes to each token
  4. Token rotation Rotate regularly, especially production

⚠️ Golden Rule: Never give production tokens to "exploratory" or "play" agents; only to audited / narrow-scope agents (e.g., security-audit, cloudflare-ops).

Example: Multi-Environment Setup

# .env file
# Production
export CLOUDFLARE_API_TOKEN_PRODUCTION="prod_token"
export CLOUDFLARE_ACCOUNT_ID_PRODUCTION="prod_account_id"

# Staging
export CLOUDFLARE_API_TOKEN_STAGING="staging_token"
export CLOUDFLARE_ACCOUNT_ID_STAGING="staging_account_id"

# Development
export CLOUDFLARE_API_TOKEN_DEVELOPMENT="dev_token"
export CLOUDFLARE_ACCOUNT_ID_DEVELOPMENT="dev_account_id"
// opencode.jsonc
"cloudflare_prod": {
  "environment": {
    "CLOUDFLARE_API_TOKEN": "{env:CLOUDFLARE_API_TOKEN_PRODUCTION}",
    "CLOUDFLARE_ACCOUNT_ID": "{env:CLOUDFLARE_ACCOUNT_ID_PRODUCTION}"
  }
},
"cloudflare_staging": {
  "environment": {
    "CLOUDFLARE_API_TOKEN": "{env:CLOUDFLARE_API_TOKEN_STAGING}",
    "CLOUDFLARE_ACCOUNT_ID": "{env:CLOUDFLARE_ACCOUNT_ID_STAGING}"
  }
},
"cloudflare_dev": {
  "environment": {
    "CLOUDFLARE_API_TOKEN": "{env:CLOUDFLARE_API_TOKEN_DEVELOPMENT}",
    "CLOUDFLARE_ACCOUNT_ID": "{env:CLOUDFLARE_ACCOUNT_ID_DEVELOPMENT}"
  }
}

Cursor IDE Integration

How Cursor Agent Works with Multiple Accounts

Cursor IDE itself uses a single account (your Cursor subscription), but Cursor Agent can access unlimited external service accounts via:

  1. Environment Variables (loaded from .env)
  2. MCP Servers (configured in ~/.cursor/mcp.json or project-specific)
  3. Workspace-Specific Config (each project folder can have different credentials)

Configuring MCP in Cursor

File: ~/.cursor/mcp.json

{
  "mcpServers": {
    "github_work": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_work_token_here"
      }
    },
    "github_personal": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_personal_token_here"
      }
    },
    "cloudflare_prod": {
      "command": "python3",
      "args": ["-m", "mcp.cloudflare_safe"],
      "env": {
        "CLOUDFLARE_API_TOKEN": "prod_token",
        "CLOUDFLARE_ACCOUNT_ID": "prod_account_id"
      }
    }
  }
}

Using Multiple Accounts in Cursor

Once configured, Cursor Agent can:

# In Cursor chat/command bar:

"Check production Cloudflare for drift"
→ Uses cloudflare_prod MCP

"Search my work GitHub for similar implementations"
→ Uses github_work MCP

"Compare personal and work repos for this pattern"
→ Uses both github_personal and github_work MCPs

Workspace-Specific .env

Each project can have its own .env:

# /Users/sovereign/Desktop/CLOUDFLARE/.env
export CLOUDFLARE_API_TOKEN="client_a_token"
export GITLAB_TOKEN="client_a_gitlab_token"

# /Users/sovereign/Desktop/CLIENT_B/.env
export CLOUDFLARE_API_TOKEN="client_b_token"
export GITLAB_TOKEN="client_b_gitlab_token"

Cursor loads the appropriate .env when you switch workspaces.

5. Usage Examples

Launching with Multiple Accounts

# Set tokens before launching
export GITHUB_TOKEN_SECONDARY="ghp_..."
export CLOUDFLARE_API_TOKEN_PRODUCTION="prod_..."

# Launch OpenCode
opencode
/init

Inside OpenCode:

/use github_secondary
Search for issues in my secondary GitHub account

/use cloudflare_prod
List all zones in the production Cloudflare account

Agent-Specific Access

/agent cloudflare-ops
# Has: cloudflare_prod, cloudflare_staging, github_secondary

/agent security-audit
# Has: cloudflare_prod only (no staging, no personal GitHub)

Cross-Account Validation

/agent cloudflare-ops

Compare configuration between production and staging accounts:
1. Query cloudflare_prod for all WAF rules
2. Query cloudflare_staging for all WAF rules
3. Show differences
4. Validate staging matches production baseline

6. Troubleshooting

Token Not Working

  1. Verify the environment variable is set:

    echo "$GITHUB_TOKEN_SECONDARY"
    
  2. Check MCP configuration in opencode.jsonc:

    • Variable names match
    • {env:VARIABLE_NAME} syntax is correct
  3. Restart OpenCode after exporting tokens

MCP Not Loading

  1. Check MCP status inside OpenCode:

    /mcp list
    /mcp status github_secondary
    
  2. Validate token format:

    • GitHub: usually ghp_...
    • GitLab: usually glpat_...
  3. Confirm agent config:

    • MCP is enabled for that agent in agents[...].tools
    • Or globally enabled in "tools"

7. Security Considerations

Token Storage

DO:

  • Store tokens in .env (gitignored)
  • Use environment variables for credentials
  • Rotate tokens every 90 days
  • Use separate tokens for prod/staging/dev

DON'T:

  • Commit tokens to git
  • Hardcode tokens in config files
  • Share tokens via chat/email
  • Use same token across environments

Audit Trail

Log all multi-account operations:

# Enable audit logging in .env
export AUDIT_LOG_ENABLED=true
export AUDIT_LOG_PATH="./observatory/audit.log"

Operations using multiple accounts will be logged with account identifiers.

Token Rotation

💡 Future Enhancement: Could integrate with playbooks/TUNNEL-ROTATION-PROTOCOL.md for automated token rotation policies.

  • AGENTS.md Agent configuration and usage
  • MCP_GUIDE.md Full MCP reference
  • GITLAB_CLOUDFLARE_AUTH.md Auth setup
  • .env.example Environment variable examples
  • COGNITION_FLOW.md How multi-account fits into cognition flow

9. Summary

To add another account:

  1. Create a unique env var for the token

    • e.g., GITHUB_TOKEN_SECONDARY, CLOUDFLARE_API_TOKEN_STAGING
  2. Add an MCP entry in opencode.jsonc that uses {env:...}

  3. Enable it per-agent (recommended) or globally

  4. Keep naming and scopes clear so you always know which token is doing what

🔐 Key Point:
One account = one env var = one MCP entry.
From there, agents decide which identities they're allowed to wield.


Next Steps:

  • See GITLAB_CLOUDFLARE_AUTH.md for detailed token creation
  • See AGENTS.md for agent-specific tool configuration
  • See .env.example for complete environment template