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

442 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:**
`<SERVICE>_<RESOURCE>_<ENV or PURPOSE>`
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