# 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 `.gitignore`d, or a secrets manager. --- ## 1. Export Tokens with Unique Variable Names Use descriptive names that encode both **service** and **purpose**. **Pattern:** `__` Examples: - `GITHUB_TOKEN_WORK` - `CLOUDFLARE_API_TOKEN_PRODUCTION` - `GITLAB_TOKEN_INTERNAL` ### Shell Export (for session-based or profile) ```bash # 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 File (recommended for project isolation) ```bash # .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: ```bash 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: ```jsonc // 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 } ``` --- ## 3. Enable Per-Agent (Recommended) or Globally **Recommended:** Enable accounts per agent for isolation. ```jsonc "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): ```jsonc "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 ```bash # .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" ``` ```jsonc // 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` ```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`: ```bash # /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 ```bash # 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 ```bash /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 ```bash /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:** ```bash 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: ```bash # 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. ## 8. Related Docs - **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