Initial commit: Cloudflare infrastructure with WAF Intelligence
- Complete Cloudflare Terraform configuration (DNS, WAF, tunnels, access) - WAF Intelligence MCP server with threat analysis and ML classification - GitOps automation with PR workflows and drift detection - Observatory monitoring stack with Prometheus/Grafana - IDE operator rules for governed development - Security playbooks and compliance frameworks - Autonomous remediation and state reconciliation
This commit is contained in:
441
MULTI_ACCOUNT_AUTH.md
Normal file
441
MULTI_ACCOUNT_AUTH.md
Normal file
@@ -0,0 +1,441 @@
|
||||
# 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": ["npx", "-y", "@modelcontextprotocol/server-cloudflare"],
|
||||
"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": ["npx", "-y", "@modelcontextprotocol/server-cloudflare"],
|
||||
"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": "npx",
|
||||
"args": ["-y", "@modelcontextprotocol/server-cloudflare"],
|
||||
"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
|
||||
Reference in New Issue
Block a user