1Password CLI (op) Skill
Master reference for the 1Password CLI (op command) covering secrets management, environment injection, shell plugins, service accounts, and CI/CD automation.
Decision Tree
code
┌─────────────────────────────────────────────────────────────────────────────────┐
│ 1PASSWORD CLI TASK ROUTER │
└─────────────────────────────────────────────────────────────────────────────────┘
│
┌──────────────┬───────────┼───────────┬──────────────┐
│ │ │ │ │
AUTHENTICATE READ/WRITE INJECT AUTOMATE PLUGINS
│ SECRETS SECRETS │ │
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─────────┐ ┌──────────┐ ┌─────────┐ ┌──────────┐ ┌──────────┐
│Desktop │ │op item │ │op run │ │Service │ │Shell │
│App Int. │ │op read │ │op inject│ │Account │ │Plugins │
│or Token │ │op vault │ │.env │ │CI/CD │ │CLI Auth │
└─────────┘ └──────────┘ └─────────┘ └──────────┘ └──────────┘
Prerequisites
bash
# Verify installation op --version # Check authentication status op whoami # List available accounts op account list
Authentication Methods
Method 1: Desktop App Integration (Recommended for Development)
Best for interactive use with biometric authentication.
bash
# Enable in 1Password app: # Settings > Developer > "Integrate with 1Password CLI" # Verify integration op vault list # Prompts for biometric auth
Method 2: Service Account Token (CI/CD & Automation)
For non-interactive environments.
bash
# Set environment variable export OP_SERVICE_ACCOUNT_TOKEN="ops_..." # Commands now work without prompts op vault list op item get "API Keys" --vault Production
Create Service Account:
bash
# Create with vault access and permissions op service-account create "ci-pipeline" \ --vault Dev:read_items \ --vault Staging:read_items,write_items \ --expires-in 90d # Token output (SAVE IMMEDIATELY - shown only once): # ops_eyJhbGciOi...
Permission Options:
- •
read_items- Read secrets (default) - •
write_items- Create/edit items (requires read_items) - •
share_items- Share items (requires read_items)
Method 3: Manual Sign-In (Legacy)
bash
# Interactive sign-in eval $(op signin) # Specific account eval $(op signin --account my-team.1password.com) # Get raw token (for scripts) op signin --raw
Secret Reference Syntax
The op:// URI format for referencing secrets:
code
op://vault/item/[section/]field[?attribute=value]
Examples
bash
# Simple field op://Private/GitHub/password # Field in section op://Production/Database/Credentials/connection-string # With query parameter (OTP) "op://Private/Google/one-time password?attribute=otp" # SSH key in OpenSSH format "op://DevOps/SSH Key/private key?ssh-format=openssh"
Get Reference for Existing Item
bash
# Get reference URL for a field op item get "GitHub" --vault Private --fields password --format json | jq -r '.reference' # Output: op://Private/GitHub/password
Reading Secrets
Read Single Secret
bash
# Using secret reference op read "op://vault/item/field" # Examples op read "op://Private/API Keys/openai-key" op read "op://Production/Database/password" # Save to file (SSH key, certificate) op read --out-file ./key.pem "op://DevOps/Server/ssh-key" op read --out-file ./cert.pem --file-mode 0600 "op://Production/SSL/certificate" # No trailing newline (for scripts) op read -n "op://Private/Token/value"
Get Item Details
bash
# Full item as JSON op item get "Database" --vault Production --format json # Specific field op item get "GitHub" --fields password # Multiple fields op item get "Database" --fields username,password # Fields by type (all concealed fields) op item get "Server" --fields type=concealed # Get OTP op item get "Google" --otp # Get shareable link op item get "API Key" --vault Shared --share-link # Reveal concealed fields in output op item get "Secrets" --reveal
Environment Injection
Using op run (Recommended)
Secrets exist only during command execution - never in shell history.
bash
# Set reference in environment export DB_PASSWORD="op://Production/Database/password" # Run command with injected secrets op run -- ./deploy.sh op run -- npm start op run -- docker-compose up # Secrets are masked in output op run -- printenv DB_PASSWORD # Shows: <concealed by 1Password> # Disable masking if needed op run --no-masking -- printenv DB_PASSWORD
Using .env Files
bash
# .env file with secret references DATABASE_URL="op://Production/Postgres/connection-string" API_KEY="op://Production/Stripe/secret-key" JWT_SECRET="op://Production/Auth/jwt-secret" # Run with env file op run --env-file=.env -- npm start op run --env-file=.env.production -- ./deploy.sh # Multiple env files (last wins on conflicts) op run --env-file=.env --env-file=.env.local -- npm run dev
Environment-Specific Switching
bash
# .env with variable interpolation DB_PASSWORD="op://$APP_ENV/database/password" API_KEY="op://$APP_ENV/api/key" # Switch environments via variable APP_ENV=dev op run --env-file=.env -- npm start APP_ENV=staging op run --env-file=.env -- npm test APP_ENV=production op run --env-file=.env -- ./deploy.sh
Using op inject (Config Files)
For templating configuration files with secrets.
bash
# Template file (config.yml.tpl)
database:
host: {{ op://Production/DB/host }}
user: {{ op://Production/DB/username }}
pass: {{ op://Production/DB/password }}
# Inject secrets and output to file
op inject -i config.yml.tpl -o config.yml
# From stdin
echo "key: {{ op://Private/API/key }}" | op inject
# Multiple secrets concatenated
echo "postgres://{{ op://db/user }}:{{ op://db/pass }}@{{ op://db/host }}/mydb" | op inject
# With environment variable switching
echo "secret: {{ op://$ENV/app/secret }}" | ENV=prod op inject
Vault Operations
List & Search
bash
# List all vaults op vault list op vault list --format json # Get vault details op vault get "Production" op vault get "Production" --format json
Create & Manage
bash
# Create vault with icon op vault create "API Keys" --icon vault-door --description "Third-party API credentials" # Available icons: # airplane, application, bankers-box, buildings, castle, coffee, document, # gears, globe, heart-with-monitor, house, id-card, plant, puzzle, shop, # treasure-chest, vault-door, vehicle, wallet, wrench # Edit vault op vault edit "API Keys" --name "External APIs" --icon globe # Delete vault op vault delete "Old Vault"
Vault Access Management
bash
# Grant user access op vault user grant --vault "Production" --user user@example.com --permissions manage_vault # Grant group access op vault group grant --vault "Production" --group "DevOps" --permissions manage_vault # Revoke access op vault user revoke --vault "Production" --user user@example.com
Item Operations
List Items
bash
# List all items op item list # Filter by vault op item list --vault Production # Filter by category op item list --categories Login,Password # Filter by tags op item list --tags api-key,production # Include archived items op item list --include-archive # Detailed list op item list --long # Combine filters op item list --vault Dev --categories "API Credential" --tags active --format json
Create Items
bash
# Login item with generated password op item create --category Login \ --title "Service Account" \ --vault Production \ --url "https://api.example.com" \ --generate-password='letters,digits,symbols,32' \ username=service@example.com # API credential op item create --category "API Credential" \ --title "OpenAI API" \ --vault "API Keys" \ api-key=sk-xxx... \ --tags "ai,production" # With custom section op item create --category "Secure Note" \ --title "Database Credentials" \ --vault Production \ "Connection.host=db.example.com" \ "Connection.port=5432" \ "Connection.database=myapp" \ "Credentials.username=admin" \ "Credentials.password[password]=secret123" # SSH key (generate new) op item create --category "SSH Key" \ --title "Deploy Key" \ --vault DevOps \ --ssh-generate-key ed25519 # From JSON template op item template get Login --out-file login.json # Edit login.json op item create --template login.json --vault Private # Duplicate from another vault op item get "Template Item" --format json | op item create --vault Production -
Edit Items
bash
# Update field value op item edit "GitHub" --vault Private password="new-password" # Generate new password op item edit "Service" --generate-password='letters,digits,32' # Update multiple fields op item edit "Database" \ username="newuser" \ password="newpass" \ "Connection.host=newhost.example.com" # Change field type op item edit "Config" "api-key[password]" # Delete custom field op item edit "Item" "old-field[delete]" # Update tags op item edit "API Key" --tags "production,active,v2" # Dry run (preview changes) op item edit "Item" --dry-run password="test"
Delete & Archive
bash
# Delete item op item delete "Old API Key" --vault Archive # Archive instead of delete op item delete "Deprecated Key" --archive
Share Items
bash
# Generate shareable link (expires in 7 days by default) op item share "Shared Secret" --vault Shared # Share with specific people op item share "Credentials" --emails "user1@example.com,user2@example.com" # Single-view link op item share "One-time Password" --view-once # Custom expiration op item share "Temp Access" --expires-in 24h
Move Items
bash
# Move between vaults op item move "API Key" --from-vault Dev --to-vault Production
Document Operations
bash
# Upload document op document create ./config.json --title "Production Config" --vault Secrets # From stdin cat sensitive.log | op document create - --title "Debug Log" --file-name "debug.log" # Download document op document get "Production Config" --vault Secrets --out-file ./config.json # List documents op document list --vault Secrets # Edit document metadata op document edit "Config" --title "New Title" --tags "config,production" # Delete document op document delete "Old Config" --vault Archive
Shell Plugins
Authenticate third-party CLIs securely through 1Password.
Available Plugins
bash
# List all available plugins op plugin list # Common plugins: # aws, gh (GitHub), glab (GitLab), heroku, docker, kubectl # vercel, netlify, fly, railway, supabase # openai, anthropic, stripe, twilio
Configure Plugin
bash
# Initialize plugin (interactive) op plugin init aws op plugin init gh # After setup, add to shell profile: # source ~/.op/plugins.sh # Inspect current configurations op plugin inspect # Clear plugin config op plugin clear aws
Using Plugins
bash
# After plugin setup, CLIs authenticate automatically aws s3 ls # Uses 1Password for AWS credentials gh repo list # Uses 1Password for GitHub token kubectl get pods # Uses 1Password for kubeconfig # Run single command with plugin credentials op plugin run -- aws s3 ls
CI/CD Integration
GitHub Actions
yaml
name: Deploy
on: push
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install 1Password CLI
uses: 1password/install-cli-action@v1
- name: Load secrets and deploy
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
run: |
op run --env-file=.env.ci -- ./deploy.sh
GitLab CI
yaml
deploy:
image: 1password/op:2
variables:
OP_SERVICE_ACCOUNT_TOKEN: $OP_TOKEN
script:
- op run --env-file=.env.ci -- ./deploy.sh
Docker
dockerfile
# Use op to inject secrets at runtime
FROM 1password/op:2 AS secrets
COPY .env.tpl .
RUN --mount=type=secret,id=OP_SERVICE_ACCOUNT_TOKEN \
export OP_SERVICE_ACCOUNT_TOKEN=$(cat /run/secrets/OP_SERVICE_ACCOUNT_TOKEN) && \
op inject -i .env.tpl -o .env
FROM node:20
COPY --from=secrets .env .
Docker Compose
yaml
services:
app:
build: .
environment:
OP_SERVICE_ACCOUNT_TOKEN: ${OP_SERVICE_ACCOUNT_TOKEN}
command: op run --env-file=.env -- npm start
Item Categories
code
API Credential Bank Account Credit Card Database Document Driver License Email Account Identity Login Membership Outdoor License Passport Password Reward Program Secure Note Server Social Security Software License SSH Key Wireless Router
Get Category Template
bash
# List all templates op item template list # Get specific template op item template get "API Credential" --format json op item template get Login --out-file login-template.json
Account Management
bash
# Add new account op account add --address my-team.1password.com # List configured accounts op account list # Get current account info op account get # Switch accounts (use with commands) op vault list --account work op vault list --account personal # Forget account from device op account forget my-team.1password.com
Output Formats
bash
# Human-readable (default) op vault list # JSON output op vault list --format json # Use jq for parsing op item get "Database" --format json | jq -r '.fields[] | select(.label=="password") | .value' # ISO timestamps op item list --iso-timestamps
Common Workflows
Local Development Setup
bash
# 1. Create .env.local with references cat > .env.local << 'EOF' DATABASE_URL="op://Dev/Postgres/connection-string" REDIS_URL="op://Dev/Redis/url" API_KEY="op://Dev/Internal API/key" JWT_SECRET="op://Dev/Auth/jwt-secret" EOF # 2. Start development op run --env-file=.env.local -- npm run dev
Rotate Credentials
bash
# Generate new password op item edit "Service Account" --generate-password='letters,digits,symbols,64' # Get new value NEW_PASS=$(op read "op://Production/Service Account/password") # Update dependent systems...
Backup/Export Secrets
bash
# Export vault items (JSON) op item list --vault Production --format json > vault-inventory.json # Get all items with full details op item list --vault Production --format json | op item get - --format json > full-export.json
Audit Access
bash
# List all users op user list # List groups op group list # Check vault permissions op vault user list --vault Production op vault group list --vault Production
Troubleshooting
"You are not currently signed in"
bash
# Check status op whoami # Re-authenticate eval $(op signin) # Or set service account token export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
"Item not found"
bash
# Verify vault access op vault list # Search for item op item list --vault "VaultName" | grep -i "item" # Check with archive op item list --include-archive | grep -i "item"
"Permission denied"
bash
# Check service account permissions # Service accounts cannot access Personal/Private vaults # Verify vault access op vault get "VaultName"
Desktop Integration Not Working
- •Ensure 1Password app is running and unlocked
- •Check Settings > Developer > "Integrate with 1Password CLI"
- •Restart terminal after enabling
- •Check app and CLI versions are compatible
Rate Limiting
bash
# Check rate limit status (service accounts) op service-account ratelimit # Use caching (default on Unix) op item list --cache
Security Best Practices
- •Use
op runover export - Secrets only exist during command execution - •Service accounts for CI/CD - Never use personal credentials in automation
- •Minimal vault access - Service accounts should only access required vaults
- •Rotate tokens regularly - Set expiration on service account tokens
- •Never log secrets - Keep
op runmasking enabled - •Use secret references - Store references in config, not actual secrets
- •Audit access regularly - Review service account usage and permissions
- •Separate environments - Use different vaults for dev/staging/production
Quick Reference
| Task | Command |
|---|---|
| Check auth status | op whoami |
| List vaults | op vault list |
| List items | op item list --vault X |
| Read secret | op read "op://vault/item/field" |
| Get item | op item get "Name" --vault X |
| Get OTP | op item get "Name" --otp |
| Run with secrets | op run --env-file=.env -- cmd |
| Inject into config | op inject -i template.tpl -o config |
| Create item | op item create --category X --title Y |
| Generate password | op item edit "X" --generate-password |
| Share item | op item share "X" --expires-in 24h |
| Setup plugin | op plugin init aws |
| Create service account | op service-account create "name" --vault X:read_items |
Integration
This skill integrates with:
- •
eng-security-safety- Threat modeling for secrets management - •
tools-docker- Container secrets injection - •
tools-github-actions- CI/CD pipeline secrets - •
tools-aws- AWS credential management via shell plugins