| 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]
op signin
op signout
op whoami
op read "op://vault/item/field"
op run -- <command>
op inject -i template.env -o .env
op item list
op item get <item>
op item create --category login
op item edit <item> field=value
op item delete <item>
op vault list
op vault get <vault>
op vault create <name>
op document list
op document get <document>
op document create <file> --vault <vault>
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:
cd tools
bun run src/op-env-create.ts --help
bun run src/op-env-list.ts --help
bun run create -- --help
bun run list -- --help
CLI Tools Setup (Python SDK)
Python tools use the official onepassword-sdk package and require uv:
cd tools-python
uv sync
uv run op-env-create --help
uv 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 SecretsManager
async def main():
sm = await SecretsManager.create()
api_key = await sm.get("op://Production/API/key")
secrets = await sm.get_many([
"op://Production/DB/password",
"op://Production/DB/host",
])
env = 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
bun run src/op-env-create.ts my-app-dev Personal \
API_KEY=secret \
DB_HOST=localhost \
DB_PORT=5432
bun run src/op-env-create.ts my-app-prod Production --from-file .env.prod
bun run src/op-env-create.ts azure-config Shared --from-file .env EXTRA_KEY=value
bun run src/op-env-create.ts secrets DevOps --tags "env,production,api" KEY=value
2. List Environments
bun run src/op-env-list.ts
bun run src/op-env-list.ts --vault Personal
bun run src/op-env-list.ts --tags "production"
bun run src/op-env-list.ts --json
3. Show Environment Details
bun run src/op-env-show.ts my-app-dev Personal
bun run src/op-env-show.ts my-app-dev Personal --reveal
bun run src/op-env-show.ts my-app-dev Personal --json
bun run src/op-env-show.ts my-app-dev Personal --keys
4. Update Environment
bun run src/op-env-update.ts my-app-dev Personal API_KEY=new-key
bun run src/op-env-update.ts my-app-dev Personal --from-file .env.local
bun run src/op-env-update.ts my-app-dev Personal --remove OLD_KEY,DEPRECATED
bun run src/op-env-update.ts my-app-dev Personal NEW_KEY=value --remove OLD_KEY
5. Export Environment
bun run src/op-env-export.ts my-app-dev Personal > .env
bun run src/op-env-export.ts my-app-dev Personal --format docker > .env
bun run src/op-env-export.ts my-app-dev Personal --format op-refs > .env.tpl
bun run src/op-env-export.ts my-app-dev Personal --format json
bun run src/op-env-export.ts azure-config Shared --prefix AZURE_ > .env
6. Delete Environment
bun run src/op-env-delete.ts my-app-dev Personal
bun run src/op-env-delete.ts my-app-dev Personal --force
bun 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:
op read "op://Personal/my-app-dev/variables/API_KEY"
API_KEY=op://Personal/my-app-dev/variables/API_KEY
DB_HOST=op://Personal/my-app-dev/variables/DB_HOST
Integration Patterns
With op run (recommended)
bun run src/op-env-export.ts my-app-dev Personal --format op-refs > .env.tpl
op run --env-file .env.tpl -- ./deploy.sh
op run --env-file .env.tpl -- docker compose up
op run --env-file .env.tpl -- npm start
op run --env-file .env.tpl -- python app.py
With op inject
bun run src/op-env-export.ts my-app-dev Personal --format op-refs > config.tpl
op inject -i config.tpl -o .env
source .env && ./app
With Docker Compose
bun run src/op-env-export.ts my-app-dev Personal --format op-refs > .env.tpl
op run --env-file .env.tpl -- docker compose up -d
In CI/CD (GitHub Actions)
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
uses: 1password/load-secrets-action@v2
with:
export-env: true
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
API_KEY: op://CI-CD/my-app-prod/variables/API_KEY
DB_PASSWORD: op://CI-CD/my-app-prod/variables/DB_PASSWORD
- name: Deploy
run: ./deploy.sh
Current Environments (Barbosa Account)
| Environment | Vault | Description |
|---|
| hypera-azure-rg-hypera-cafehyna-web-dev | - | Azure RG - Cafehyna Web Dev |
| hypera-azure-devops-team-az-cli-pim | - | Azure DevOps Team - CLI PIM |
| devops-team-pim | - | DevOps Team PIM credentials |
| hypera-github-python-devops | - | GitHub - Python DevOps |
| hypera-azure-rg-hypera-cafehyna-web | - | Azure RG - Cafehyna Web Prod |
| repos-github-zsh | - | GitHub - ZSH repository |
| hypera | - | General Hypera infrastructure |
| Azure OpenAI-finops | - | Azure OpenAI FinOps config |
See references/environments/inventory.md for detailed documentation.
Secret Retrieval
Secret Reference Format
The standard format for referencing secrets:
op://<vault>/<item>/<field>
Examples:
op://Development/AWS/access_key_id
op://Production/Database/password
op://Shared/API Keys/github_token
Reading Secrets Directly
op read "op://Development/AWS/access_key_id"
op item get "AWS" --vault Development --format json
op item get "AWS" --vault Development --fields access_key_id
Injecting Secrets into Commands
The op run command injects secrets as environment variables:
op run --env-file=.env.tpl -- ./deploy.sh
Injecting Secrets into Files
The op inject command replaces secret references in template files:
op inject -i config.tpl.yaml -o config.yaml
Item Management
Creating Items
op item create --category login \
--title "My Service" \
--vault Development \
username=admin \
password=secretpassword
op item create --category login \
--title "New Account" \
--generate-password
op 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
op item edit "My Service" password=newpassword
op item edit "My Service" api_key=newkey
op 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:
op service-account create "CI/CD Pipeline" \
--vault Production:read_items
op service-account create "Deployment Bot" \
--vault Production:read_items,write_items
op 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: 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
uses: 1password/load-secrets-action@v2
with:
export-env: true
env:
OP_SERVICE_ACCOUNT_TOKEN: ${{ secrets.OP_SERVICE_ACCOUNT_TOKEN }}
AWS_ACCESS_KEY_ID: op://CI-CD/AWS/access_key_id
AWS_SECRET_ACCESS_KEY: op://CI-CD/AWS/secret_access_key
- name: Deploy
run: ./deploy.sh
GitLab CI
deploy:
image: 1password/op:2
variables:
OP_SERVICE_ACCOUNT_TOKEN: $OP_SERVICE_ACCOUNT_TOKEN
script:
- 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.1
orbs:
onepassword: onepassword/secrets@1
jobs:
deploy:
docker:
- image: cimg/base:stable
steps:
- checkout
- onepassword/exec:
command: ./deploy.sh
env:
AWS_ACCESS_KEY_ID: op://CI-CD/AWS/access_key_id
AWS_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
kubectl create secret generic onepassword-credentials \
--from-file=1password-credentials.json
kubectl create secret generic onepassword-token \
--from-literal=token=your-access-token
Deploy Connect Server
apiVersion: apps/v1
kind: Deployment
metadata:
name: onepassword-connect
spec:
replicas: 1
selector:
matchLabels:
app: onepassword-connect
template:
metadata:
labels:
app: onepassword-connect
spec:
containers:
- name: connect-api
image: 1password/connect-api:latest
ports:
- containerPort: 8080
volumeMounts:
- name: credentials
mountPath: /home/opuser/.op/1password-credentials.json
subPath: 1password-credentials.json
volumes:
- name: credentials
secret:
secretName: onepassword-credentials
---
apiVersion: v1
kind: Service
metadata:
name: onepassword-connect
spec:
selector:
app: onepassword-connect
ports:
- port: 8080
targetPort: 8080
ClusterSecretStore Configuration
apiVersion: external-secrets.io/v1
kind: ClusterSecretStore
metadata:
name: onepassword
spec:
provider:
onepassword:
connectHost: http://onepassword-connect:8080
vaults:
production: 1
staging: 2
auth:
secretRef:
connectTokenSecretRef:
name: onepassword-token
namespace: external-secrets
key: token
ExternalSecret Examples
Basic secret retrieval:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: database-credentials
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
name: database-credentials
creationPolicy: Owner
data:
- secretKey: username
remoteRef:
key: Database
property: username
- secretKey: password
remoteRef:
key: Database
property: password
Using dataFrom with regex:
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: env-config
spec:
refreshInterval: 1h
secretStoreRef:
kind: ClusterSecretStore
name: onepassword
target:
name: app-env
dataFrom:
- find:
path: app-config
name:
regexp: "^[A-Z_]+$"
PushSecret (Kubernetes to 1Password)
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
name: push-generated-secret
spec:
refreshInterval: 1h
secretStoreRefs:
- name: onepassword
kind: ClusterSecretStore
selector:
secret:
name: generated-credentials
data:
- match:
secretKey: api-key
remoteRef:
remoteKey: generated-api-key
property: password
metadata:
apiVersion: kubernetes.external-secrets.io/v1alpha1
kind: PushSecretMetadata
spec:
vault: production
tags:
- 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-charts
helm 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/v1
kind: OnePasswordItem
metadata:
name: database-secret
spec:
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:
AUTO_RESTART=true
apiVersion: v1
kind: Namespace
metadata:
name: production
annotations:
operator.1password.io/auto-restart: "true"
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
operator.1password.io/auto-restart: "true"
Shell Plugins
Shell plugins enable automatic authentication for third-party CLIs.
Available Plugins
op plugin list
Plugin Setup
op plugin init aws
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
op signin
op plugin init gh
Step 2: Configure git credential helper
git config --global --unset-all credential.https://github.com.helper 2>/dev/null
git 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:
source ~/.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:
cd /path/to/work-repo
git config credential.https://github.com.helper '!/opt/homebrew/bin/gh auth git-credential'
[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:
rm ~/.config/op/plugins/used_items/gh.json
op plugin init gh
gh aliased to op plugin run
If gh is aliased to run through 1Password but failing:
which gh
/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:
op whoami
op signin
echo $OP_SERVICE_ACCOUNT_TOKEN | head -c 10
Item not found:
op item list --vault "Vault Name"
op item get --vault Development dh7fjsh3kd8fjs
Permission denied in CI/CD:
op vault list
op service-account ratelimit
External Secrets not syncing:
kubectl describe externalsecret <name>
kubectl logs -l app=onepassword-connect
kubectl 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 reference
references/kubernetes-examples.md - Kubernetes manifest examples
references/python-sdk.md - Python SDK reference and integration guide
references/environments/README.md - Developer Environments guide
references/environments/inventory.md - Current environments inventory
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
cd tools && bun run src/op-env-list.ts --help
cd 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 integration
scripts/setup-service-account.sh - Create and configure a service account
scripts/sync-check.sh - Verify External Secrets synchronization
External Documentation