Skill v1.0.1
currentAutomated scan100/100+8 new
version: "1.0.1" name: 1password description: Guide for implementing 1Password secrets management - CLI operations, service accounts, Developer Environments, and Kubernetes integration. Use when retrieving secrets, managing vaults, configuring CI/CD pipelines, integrating with External Secrets Operator, managing Developer Environments, or automating secrets workflows with 1Password.
1Password
Overview
This skill provides comprehensive guidance for working with 1Password's secrets management ecosystem. It covers the op CLI for local development, service accounts for automation, Developer Environments for project secrets, and Kubernetes integrations including the native 1Password Operator and External Secrets Operator.
Quick Reference
Command Structure
1Password CLI uses a noun-verb structure: op <noun> <verb> [flags]
# Authenticationop signin # Sign in to accountop signout # Sign outop whoami # Show signed-in account info# Secret retrievalop read "op://vault/item/field" # Read single secretop run -- <command> # Inject secrets as env varsop inject -i template.env -o .env # Inject secrets into file# Item managementop item list # List all itemsop item get <item> # Get item detailsop item create --category login # Create new itemop item edit <item> field=value # Edit itemop item delete <item> # Delete item# Vault managementop vault list # List vaultsop vault get <vault> # Get vault infoop vault create <name> # Create vault# Document managementop document list # List documentsop document get <document> # Download documentop document create <file> --vault <vault> # Upload document
Workflow Decision Tree
What do you need to do?├── Retrieve a secret for local development?│ └── Use: op read, op run, or op inject├── Manage project environment variables?│ └── See: Developer Environments (below)├── Manage items/vaults in 1Password?│ └── Use: op item, op vault, op document commands├── Automate secrets in CI/CD?│ └── Use: Service Accounts with OP_SERVICE_ACCOUNT_TOKEN├── Sync secrets to Kubernetes?│ ├── Using External Secrets Operator?│ │ └── See: External Secrets Operator Integration│ └── Using native 1Password Operator?│ └── See: 1Password Kubernetes Operator└── Configure shell plugins for CLI tools?└── Use: op plugin commands
Developer Environments
Developer Environments provide a dedicated location to store, organize, and manage project secrets as environment variables. CLI tools are available in both TypeScript/Bun and Python SDK variants.
Feature Overview
| Feature | GUI | TypeScript CLI | Python SDK CLI | |
|---|---|---|---|---|
| Create environment | Yes | bun run create | uv run op-env-create | |
| Update environment | Yes | bun run update | uv run op-env-update | |
| Delete environment | Yes | bun run delete | uv run op-env-delete | |
| Show environment | Yes | bun run show | uv run op-env-show | |
| List environments | Yes | bun run list | uv run op-env-list | |
| Export to .env | Yes | bun run export | uv run op-env-export | |
| Mount .env file | Yes (beta) | No | No |
CLI Tools Setup (TypeScript)
Tools are written in TypeScript and require Bun runtime:
# Navigate to tools directorycd tools# Run any tool with bunbun run src/op-env-create.ts --helpbun run src/op-env-list.ts --help# Or use npm scriptsbun run create -- --helpbun run list -- --help
CLI Tools Setup (Python SDK)
Python tools use the official onepassword-sdk package and require uv:
# Navigate to tools-python directorycd tools-python# Install dependenciesuv sync# Run any tooluv run op-env-create --helpuv run op-env-list --help
Requirements: Python 3.9+, OP_SERVICE_ACCOUNT_TOKEN environment variable.
When to Use SDK vs CLI
| Use Case | Recommended | Why | |
|---|---|---|---|
| Python applications (FastAPI, Django) | Python SDK | Native async, no subprocess overhead | |
| Shell scripts, CI/CD pipelines | TypeScript CLI or op CLI | Direct CLI integration | |
| Batch secret resolution | Python SDK | resolve_all() for efficiency | |
| Tag-based filtering | TypeScript CLI | SDK lacks tag filter support | |
| Interactive local development | Either | Both have identical interfaces |
SecretsManager (Python SDK)
For Python applications that need runtime secret resolution:
from op_env.secrets_manager import SecretsManagerasync def main():sm = await SecretsManager.create()# Single secret (with caching)api_key = await sm.get("op://Production/API/key")# Batch resolvesecrets = await sm.get_many(["op://Production/DB/password","op://Production/DB/host",])# Load all vars from an environment itemenv = await sm.resolve_environment("my-app-prod", "Production")
See references/python-sdk.md for full SDK reference and integration patterns.
Environment Workflow
1. Create Environment
# From inline variablesbun run src/op-env-create.ts my-app-dev Personal \API_KEY=secret \DB_HOST=localhost \DB_PORT=5432# From .env filebun run src/op-env-create.ts my-app-prod Production --from-file .env.prod# Combine file + inline (inline overrides file)bun run src/op-env-create.ts azure-config Shared --from-file .env EXTRA_KEY=value# With custom tagsbun run src/op-env-create.ts secrets DevOps --tags "env,production,api" KEY=value
2. List Environments
# List all environments (tagged with 'environment')bun run src/op-env-list.ts# Filter by vaultbun run src/op-env-list.ts --vault Personal# Filter by tagsbun run src/op-env-list.ts --tags "production"# JSON outputbun run src/op-env-list.ts --json
3. Show Environment Details
# Show with masked values (default)bun run src/op-env-show.ts my-app-dev Personal# Show with revealed valuesbun run src/op-env-show.ts my-app-dev Personal --reveal# JSON outputbun run src/op-env-show.ts my-app-dev Personal --json# Show only variable namesbun run src/op-env-show.ts my-app-dev Personal --keys
4. Update Environment
# Update/add single variablebun run src/op-env-update.ts my-app-dev Personal API_KEY=new-key# Merge from .env filebun run src/op-env-update.ts my-app-dev Personal --from-file .env.local# Remove variablesbun run src/op-env-update.ts my-app-dev Personal --remove OLD_KEY,DEPRECATED# Update and remove in one commandbun run src/op-env-update.ts my-app-dev Personal NEW_KEY=value --remove OLD_KEY
5. Export Environment
# Export to .env file (standard format)bun run src/op-env-export.ts my-app-dev Personal > .env# Docker-compatible format (quoted values)bun run src/op-env-export.ts my-app-dev Personal --format docker > .env# op:// references template (for op run/inject)bun run src/op-env-export.ts my-app-dev Personal --format op-refs > .env.tpl# JSON formatbun run src/op-env-export.ts my-app-dev Personal --format json# Add prefix to all variablesbun run src/op-env-export.ts azure-config Shared --prefix AZURE_ > .env
6. Delete Environment
# Interactive deletion (asks for confirmation)bun run src/op-env-delete.ts my-app-dev Personal# Force delete without confirmationbun run src/op-env-delete.ts my-app-dev Personal --force# Archive instead of permanent deletebun run src/op-env-delete.ts my-app-dev Personal --archive
Environment Secret Reference
Access individual variables using the secret reference format:
op://<vault>/<environment>/variables/<key>
Example:
# Read single variableop read "op://Personal/my-app-dev/variables/API_KEY"# Use in template file (.env.tpl)API_KEY=op://Personal/my-app-dev/variables/API_KEYDB_HOST=op://Personal/my-app-dev/variables/DB_HOST
Integration Patterns
With op run (recommended)
# 1. Export environment as op:// templatebun run src/op-env-export.ts my-app-dev Personal --format op-refs > .env.tpl# 2. Run command with injected secretsop run --env-file .env.tpl -- ./deploy.shop run --env-file .env.tpl -- docker compose upop run --env-file .env.tpl -- npm startop run --env-file .env.tpl -- python app.py
With op inject
# 1. Create template with op:// referencesbun run src/op-env-export.ts my-app-dev Personal --format op-refs > config.tpl# 2. Inject secrets into fileop inject -i config.tpl -o .env# 3. Use the generated .env filesource .env && ./app
With Docker Compose
# 1. Export environmentbun run src/op-env-export.ts my-app-dev Personal --format op-refs > .env.tpl# 2. Run docker compose with secretsop run --env-file .env.tpl -- docker compose up -d
In CI/CD (GitHub Actions)
name: Deployon: [push]jobs:deploy:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Install 1Password CLIuses: 1password/install-cli-action@v1- name: Load secretsuses: 1password/load-secrets-action@v2with:export-env: trueenv:OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}API_KEY: op://CI-CD/my-app-prod/variables/API_KEYDB_PASSWORD: op://CI-CD/my-app-prod/variables/DB_PASSWORD- name: Deployrun: ./deploy.sh
Naming your environments
Name each 1Password Developer Environment after the thing it holds credentials for, e.g. <project>-azure-rg-<name>-dev, <team>-pim, <project>-github. Keep the actual inventory of your environments in a git-ignored local note, not in a committed (and potentially public) skill file.
Secret Retrieval
Secret Reference Format
The standard format for referencing secrets:
op://<vault>/<item>/<field>
Examples:
op://Development/AWS/access_key_idop://Production/Database/passwordop://Shared/API Keys/github_token
Reading Secrets Directly
# Read a specific fieldop read "op://Development/AWS/access_key_id"# Read with JSON outputop item get "AWS" --vault Development --format json# Read specific field from itemop item get "AWS" --vault Development --fields access_key_id
Injecting Secrets into Commands
The op run command injects secrets as environment variables:
# Run command with secretsop run --env-file=.env.tpl -- ./deploy.sh# Example .env.tpl file:# AWS_ACCESS_KEY_ID=op://Development/AWS/access_key_id# AWS_SECRET_ACCESS_KEY=op://Development/AWS/secret_access_key
Injecting Secrets into Files
The op inject command replaces secret references in template files:
# Inject secrets from template to output fileop inject -i config.tpl.yaml -o config.yaml# Example config.tpl.yaml:# database:# host: localhost# password: op://Production/Database/password
Item Management
Creating Items
# Create a login itemop item create --category login \--title "My Service" \--vault Development \username=admin \password=secretpassword# Create with generated passwordop item create --category login \--title "New Account" \--generate-password# Create from JSON templateop item create --template item.json
Item Template (JSON)
{"title": "my-service-credentials","vault": {"id": "vault-uuid-or-name"},"category": "LOGIN","fields": [{"label": "username", "value": "admin", "type": "STRING"},{"label": "password", "value": "secret", "type": "CONCEALED"},{"label": "api_key", "value": "key123", "type": "CONCEALED"}]}
Editing Items
# Edit a fieldop item edit "My Service" password=newpassword# Add a new fieldop item edit "My Service" api_key=newkey# Edit with specific vaultop item edit "My Service" --vault Development password=newpassword
Service Accounts
Service accounts enable automation without personal credentials.
Prerequisites
- 1Password CLI version 2.18.0 or later
- Active 1Password subscription
- Admin permissions to create service accounts
Creating Service Accounts
Via CLI:
# Create with read-only accessop service-account create "CI/CD Pipeline" \--vault Production:read_items# Create with write accessop service-account create "Deployment Bot" \--vault Production:read_items,write_items# Create with vault creation permissionop service-account create "Provisioning Bot" \--vault Production:read_items,write_items \--can-create-vaults
Using Service Accounts
Export the service account token:
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."
Then use normal CLI commands - they automatically authenticate with the service account.
Service Account Limitations
- Cannot access Personal, Private, Employee, or default Shared vaults
- Permissions cannot be modified after creation
- Limited to 100 service accounts per account
- Subject to rate limits
CI/CD Integration
GitHub Actions
name: Deployon: [push]jobs:deploy:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Install 1Password CLIuses: 1password/install-cli-action@v1- name: Load secretsuses: 1password/load-secrets-action@v2with:export-env: trueenv:OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}AWS_ACCESS_KEY_ID: op://CI-CD/AWS/access_key_idAWS_SECRET_ACCESS_KEY: op://CI-CD/AWS/secret_access_key- name: Deployrun: ./deploy.sh
GitLab CI
deploy:image: 1password/op:2variables:OP_SERVICE_ACCOUNT_TOKEN: $OP_SERVICE_ACCOUNT_TOKENscript:- export AWS_ACCESS_KEY_ID=$(op read "op://CI-CD/AWS/access_key_id")- export AWS_SECRET_ACCESS_KEY=$(op read "op://CI-CD/AWS/secret_access_key")- ./deploy.sh
CircleCI
version: 2.1orbs:onepassword: onepassword/secrets@1jobs:deploy:docker:- image: cimg/base:stablesteps:- checkout- onepassword/exec:command: ./deploy.shenv:AWS_ACCESS_KEY_ID: op://CI-CD/AWS/access_key_idAWS_SECRET_ACCESS_KEY: op://CI-CD/AWS/secret_access_key
External Secrets Operator Integration
External Secrets Operator (ESO) syncs secrets from 1Password to Kubernetes.
Prerequisites
- 1Password Connect Server (v1.5.6+)
- Credentials file (
1password-credentials.json) - Access token for authentication
- External Secrets Operator installed in cluster
Connect Server Setup
# Create automation environment and get credentials# This generates 1password-credentials.json and an access token# Create Kubernetes secret for Connect Server credentialskubectl create secret generic onepassword-credentials \--from-file=1password-credentials.json# Create secret for access tokenkubectl create secret generic onepassword-token \--from-literal=token=your-access-token
Deploy Connect Server
apiVersion: apps/v1kind: Deploymentmetadata:name: onepassword-connectspec:replicas: 1selector:matchLabels:app: onepassword-connecttemplate:metadata:labels:app: onepassword-connectspec:containers:- name: connect-apiimage: 1password/connect-api:latestports:- containerPort: 8080volumeMounts:- name: credentialsmountPath: /home/opuser/.op/1password-credentials.jsonsubPath: 1password-credentials.jsonvolumes:- name: credentialssecret:secretName: onepassword-credentials---apiVersion: v1kind: Servicemetadata:name: onepassword-connectspec:selector:app: onepassword-connectports:- port: 8080targetPort: 8080
ClusterSecretStore Configuration
apiVersion: external-secrets.io/v1kind: ClusterSecretStoremetadata:name: onepasswordspec:provider:onepassword:connectHost: http://onepassword-connect:8080vaults:production: 1staging: 2auth:secretRef:connectTokenSecretRef:name: onepassword-tokennamespace: external-secretskey: token
ExternalSecret Examples
Basic secret retrieval:
apiVersion: external-secrets.io/v1kind: ExternalSecretmetadata:name: database-credentialsspec:refreshInterval: 1hsecretStoreRef:kind: ClusterSecretStorename: onepasswordtarget:name: database-credentialscreationPolicy: Ownerdata:- secretKey: usernameremoteRef:key: Database # Item title in 1Passwordproperty: username # Field label- secretKey: passwordremoteRef:key: Databaseproperty: password
Using dataFrom with regex:
apiVersion: external-secrets.io/v1kind: ExternalSecretmetadata:name: env-configspec:refreshInterval: 1hsecretStoreRef:kind: ClusterSecretStorename: onepasswordtarget:name: app-envdataFrom:- find:path: app-config # Item titlename:regexp: "^[A-Z_]+$" # Match all uppercase env vars
PushSecret (Kubernetes to 1Password)
apiVersion: external-secrets.io/v1alpha1kind: PushSecretmetadata:name: push-generated-secretspec:refreshInterval: 1hsecretStoreRefs:- name: onepasswordkind: ClusterSecretStoreselector:secret:name: generated-credentialsdata:- match:secretKey: api-keyremoteRef:remoteKey: generated-api-keyproperty: passwordmetadata:apiVersion: kubernetes.external-secrets.io/v1alpha1kind: PushSecretMetadataspec:vault: productiontags:- generated- kubernetes
1Password Kubernetes Operator
The native 1Password Operator provides direct integration without External Secrets Operator.
Installation via Helm
helm repo add 1password https://1password.github.io/connect-helm-chartshelm install connect 1password/connect \--set-file connect.credentials=1password-credentials.json \--set operator.create=true \--set operator.token.value=your-access-token
OnePasswordItem CRD
apiVersion: onepassword.com/v1kind: OnePasswordItemmetadata:name: database-secretspec:itemPath: "vaults/Production/items/Database"
This creates a Kubernetes Secret named database-secret with all fields from the 1Password item.
Auto-Restart Configuration
Enable automatic deployment restarts when secrets change:
# Operator-level (environment variable)AUTO_RESTART=true# Namespace-level (annotation)apiVersion: v1kind: Namespacemetadata:name: productionannotations:operator.1password.io/auto-restart: "true"# Deployment-level (annotation)apiVersion: apps/v1kind: Deploymentmetadata:annotations:operator.1password.io/auto-restart: "true"
Shell Plugins
Shell plugins enable automatic authentication for third-party CLIs.
Available Plugins
# List available pluginsop plugin list# Common plugins: aws, gh, stripe, vercel, fly, etc.
Plugin Setup
# Initialize AWS pluginop plugin init aws# This configures shell aliases to use 1Password for AWS credentials# Add to your shell profile as instructed
Git Workflow with 1Password
Use 1Password to manage GitHub authentication for git operations (push, pull, clone).
Quick Setup
Run the setup script to configure everything:
./scripts/setup-gh-plugin.sh
Manual Setup
Step 1: Initialize the gh plugin
# Sign in to 1Passwordop signin# Initialize gh plugin (interactive - select your GitHub token)op plugin init gh
Step 2: Configure git credential helper
# Remove any broken credential helpersgit config --global --unset-all credential.https://github.com.helper 2>/dev/null# Set gh as the credential helper for GitHubgit config --global credential.https://github.com.helper '!/opt/homebrew/bin/gh auth git-credential'git config --global credential.https://gist.github.com.helper '!/opt/homebrew/bin/gh auth git-credential'
Step 3: Add shell integration
Add to your ~/.zshrc or ~/.bashrc:
# 1Password CLI pluginssource ~/.config/op/plugins.sh
How It Works
┌─────────────────────────────────────────────────────────────────┐│ Git Push Workflow │├─────────────────────────────────────────────────────────────────┤│ ││ git push ││ │ ││ ▼ ││ Git credential helper ││ │ ││ ▼ ││ gh auth git-credential ││ │ ││ ▼ ││ 1Password plugin (via op wrapper) ││ │ ││ ▼ ││ 1Password (biometric/password unlock) ││ │ ││ ▼ ││ Token retrieved and passed to git ││ │ ││ ▼ ││ Push completes successfully ││ │└─────────────────────────────────────────────────────────────────┘
Multiple GitHub Accounts
If you work with multiple GitHub accounts, you can configure per-repo credentials:
# For a specific repo, use a different 1Password itemcd /path/to/work-repogit config credential.https://github.com.helper '!/opt/homebrew/bin/gh auth git-credential'# Or use includeIf in ~/.gitconfig for path-based selection[includeIf "gitdir:~/work/"]path = ~/.gitconfig-work
Fixing Common Issues
"Item not found in vault" error
This means the 1Password plugin is pointing to a deleted token:
# Remove the broken plugin configurationrm ~/.config/op/plugins/used_items/gh.json# Re-initializeop plugin init gh
gh aliased to op plugin run
If gh is aliased to run through 1Password but failing:
# Check the aliaswhich gh # Shows: gh: aliased to op plugin run -- gh# Run gh directly to bypass the alias/opt/homebrew/bin/gh auth status
Git prompting for username/password
Verify the credential helper is configured:
git config --list | grep credential
Should show:
credential.https://github.com.helper=!/opt/homebrew/bin/gh auth git-credential
Troubleshooting
Common Issues
Authentication fails:
# Check current sessionop whoami# Sign in againop signin# For service accounts, verify tokenecho $OP_SERVICE_ACCOUNT_TOKEN | head -c 10
Item not found:
# List items in vault to verify nameop item list --vault "Vault Name"# Use item ID instead of name for reliabilityop item get --vault Development dh7fjsh3kd8fjs
Permission denied in CI/CD:
# Verify service account has access to vaultop vault list # Should show accessible vaults# Check rate limitsop service-account ratelimit
External Secrets not syncing:
# Check ExternalSecret statuskubectl describe externalsecret <name># Check Connect Server logskubectl logs -l app=onepassword-connect# Verify SecretStore connectionkubectl describe secretstore <name>
Best Practices
- Use secret references (
op://) instead of hardcoding vault/item names in scripts - Prefer service accounts over personal accounts for automation
- Scope permissions minimally - grant only necessary vault access
- Use item IDs in scripts for stability (names can change)
- Rotate service account tokens when sign-in addresses change
- Enable auto-restart in Kubernetes for seamless secret rotation
- Use separate vaults per environment (dev, staging, prod)
- Tag items for organization and filtering
Resources
References
references/cli-commands.md- Complete CLI command referencereferences/kubernetes-examples.md- Kubernetes manifest examplesreferences/python-sdk.md- Python SDK reference and integration guidereferences/environments/README.md- Developer Environments guide
Tools
Environment management CLI tools in TypeScript and Python:
| Operation | TypeScript (tools/) | Python (tools-python/) | |
|---|---|---|---|
| Create | bun run create | uv run op-env-create | |
| Update | bun run update | uv run op-env-update | |
| Delete | bun run delete | uv run op-env-delete | |
| Show | bun run show | uv run op-env-show | |
| List | bun run list | uv run op-env-list | |
| Export | bun run export | uv run op-env-export |
TypeScript requirements: Bun runtime Python requirements: Python 3.9+, uv, OP_SERVICE_ACCOUNT_TOKEN
# TypeScript toolscd tools && bun run src/op-env-list.ts --help# Python SDK toolscd tools-python && uv sync && uv run op-env-list --help
Templates
Environment and integration templates (in templates/):
| Template | Description | |
|---|---|---|
env.template | Standard .env file template | |
env-op-refs.template | Template with op:// references | |
github-actions-env.yaml | GitHub Actions workflow example | |
docker-compose-env.yaml | Docker Compose with secrets injection |
Scripts
scripts/setup-gh-plugin.sh- Setup GitHub CLI with 1Password integrationscripts/setup-service-account.sh- Create and configure a service accountscripts/sync-check.sh- Verify External Secrets synchronization
External Documentation
- 1Password CLI Documentation
- Service Accounts Guide
- Developer Environments
- Local .env Files
- Kubernetes Operator
- External Secrets Provider
Gotchas
- Service Account vs Connect Server vs CLI auth modes differ in rate limits, vault visibility, and cred shape — a script using
opinteractively won't necessarily work as a service-account token. - `op inject` evaluates `op://...` refs at render time — templates checked into git are safe; rendered output never goes near git.
- CLI biometric prompt unless `OP_DEVICE` is set — CI containers without that env var fail silently as if there were no secrets.
- Shell plugin (`op plugin init`) sources at shell start — plugin updates don't apply until you open a new shell.
- `op read op://vault/item/field` returns the FIRST match across duplicates — items with the same field name resolve by lexicographic order, not creation date.