# 1Password Integration Patterns Common patterns for integrating 1Password with developer tools and AI workflows. ## Claude Code / Claude Desktop ### Claude Desktop MCP Config Store API keys securely and reference them in `claude_desktop_config.json`: ```bash # Store the key op item create --category API_CREDENTIAL --title "My MCP Server" \ --vault Dev api_key[password]=your-key-here # Get the secret reference # op://Dev/My MCP Server/api_key ``` ```json { "mcpServers": { "my-server": { "command": "op", "args": ["run", "--", "node", "/path/to/server.js"], "env": { "API_KEY": "op://Dev/My MCP Server/api_key" } } } } ``` ### Claude Code Shell Environment ```bash # .env.tpl (safe to commit — no real secrets) ANTHROPIC_API_KEY=op://Dev/Anthropic/api_key OPENAI_API_KEY=op://Dev/OpenAI/api_key # ✅ Wrap claude with op run — secrets injected into subprocess only op run --env-file=.env.tpl -- claude # ✅ Or export individually for interactive shell use export ANTHROPIC_API_KEY=$(op read "op://Dev/Anthropic/api_key") claude ``` ### In CLAUDE.md (project secrets reference) ```markdown ## Secrets Setup Secrets are managed via 1Password. Run before working: ```bash op run --env-file=.env.tpl -- claude ``` Do NOT commit `.env` — commit `.env.tpl` only. ``` ## n8n ### Environment Injection at Startup ```bash # n8n.env.tpl (commit this) N8N_ENCRYPTION_KEY=op://Dev/n8n/encryption_key DB_POSTGRESDB_PASSWORD=op://Dev/n8n-postgres/password N8N_BASIC_AUTH_PASSWORD=op://Dev/n8n/basic_auth_password # docker-compose.yml startup op run --env-file=n8n.env.tpl -- docker compose up -d n8n ``` ### n8n Credential Storage via API Use n8n's credential API to push secrets from 1Password into n8n: ```bash # Get secret from 1Password API_KEY=$(op read "op://Dev/Some Service/api_key") # Push to n8n credential (HTTP Request) curl -s -X POST "https://n8n.example.com/api/v1/credentials" \ -H "X-N8N-API-KEY: $(op read 'op://Dev/n8n/api_key')" \ -H "Content-Type: application/json" \ -d "{\"name\": \"Service Credential\", \"type\": \"httpHeaderAuth\", \"data\": {\"name\": \"Authorization\", \"value\": \"Bearer $API_KEY\"}}" ``` ## Docker / Docker Compose ```yaml # docker-compose.yml services: app: image: myapp:latest environment: DATABASE_URL: ${DATABASE_URL} API_KEY: ${API_KEY} ``` ```bash # .env.tpl DATABASE_URL=op://Dev/Postgres/connection_string API_KEY=op://Dev/MyApp/api_key # Start with injection op run --env-file=.env.tpl -- docker compose up ``` ## Python Scripts ```python import subprocess def get_secret(reference: str) -> str: """Read a secret from 1Password using a secret reference.""" result = subprocess.run( ["op", "read", reference], capture_output=True, text=True, check=True ) return result.stdout.strip() # Usage api_key = get_secret("op://Dev/Anthropic/api_key") ``` Or using the 1Password Python SDK (if available): ```bash pip install onepassword-sdk ``` ```python import asyncio import onepassword async def main(): client = await onepassword.Client.authenticate( auth=os.environ["OP_SERVICE_ACCOUNT_TOKEN"], integration_name="My Script", integration_version="1.0.0", ) secret = await client.secrets.resolve("op://Dev/Anthropic/api_key") ``` ## GitHub Actions / CI ```yaml # .github/workflows/deploy.yml jobs: deploy: runs-on: ubuntu-latest steps: - uses: 1password/load-secrets-action@v2 with: export-env: true env: OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }} ANTHROPIC_API_KEY: op://Dev/Anthropic/api_key DEPLOY_KEY: op://Dev/Deploy/private_key - run: deploy-script.sh # ANTHROPIC_API_KEY is available ``` ## Shell / .zshrc Auto-Load ```bash # ~/.zshrc # Auto-load common dev secrets on shell start (optional — only if you trust your machine) load_dev_secrets() { if command -v op &>/dev/null && op whoami &>/dev/null 2>&1; then source <(op run --env-file=~/.config/dev.env.tpl -- env 2>/dev/null) && \ echo "✅ Dev secrets loaded from 1Password" fi } # Call explicitly when needed: alias load-secrets='load_dev_secrets' ``` ## Supabase ```bash # Store Supabase credentials op item create --category API_CREDENTIAL --title "Supabase - My Project" \ --vault Dev \ url[text]=https://myproject.supabase.co \ anon_key[password]=eyJ... \ service_key[password]=eyJ... # Use in scripts SUPABASE_URL=$(op read "op://Dev/Supabase - My Project/url") SUPABASE_KEY=$(op read "op://Dev/Supabase - My Project/service_key") ``` ## Replit Replit has its own Secrets manager, but for local dev before deploying: ```bash # Generate a .env from 1Password, then paste values into Replit Secrets UI op run --env-file=.env.tpl -- env | grep -E "^(ANTHROPIC|SUPABASE|N8N)" # Copy output values → paste into Replit Secrets one by one ``` ## Rotation Workflow When rotating a credential: ```bash # 1. Update in the service (get new key) NEW_KEY="new-key-from-service" # 2. Update in 1Password op item edit "Service Name" api_key[password]="$NEW_KEY" # 3. Verify op read "op://Dev/Service Name/api_key" # 4. Re-inject wherever used source <(op run --env-file=.env.tpl -- env) # Or restart services that use the key ```