Secrets Management
1Password CLI integration for secure secrets injection across environments
tx-agent-kit uses 1Password CLI (op) for secrets management across all environments. Secrets are never stored as plaintext in the repository. Instead, committed template files contain op:// URI references that are resolved at runtime.
How it works
The secrets workflow has three components:
- Template files: committed to git, contain
op://URI references instead of actual secret values. - 1Password vaults: store the actual secret values, organized by environment.
op inject: resolvesop://references at deploy time, producing a rendered.envfile.
URI format
op://<vault>/<item>/<field>For example:
DATABASE_URL=op://octospark-services/prod/DATABASE_URL
AUTH_SECRET=op://octospark-services/prod/AUTH_SECRETVault organization
| Vault | Purpose |
|---|---|
octospark-services | All project secrets: dev, staging, and production credentials |
Personal | Personal account logins (not used by the project) |
client-logins | Client-specific credentials |
Within each vault, items are named by environment (dev, staging, prod), and fields match environment variable names exactly.
Template files
Two deploy templates are committed to the repository: deploy/env/staging.env.template for the staging environment and deploy/env/prod.env.template for production.
These templates mix literal values (like NODE_ENV=staging) with op:// references for sensitive values:
# Literal values are committed as-is
NODE_ENV=staging
API_PORT=4000
API_HOST=0.0.0.0
OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
# Secrets reference 1Password vaults
DATABASE_URL=op://octospark-services/staging/DATABASE_URL
AUTH_SECRET=op://octospark-services/staging/AUTH_SECRET
TEMPORAL_ADDRESS=op://octospark-services/staging/TEMPORAL_ADDRESS
GOOGLE_CLOUD_PROJECT=op://octospark-services/staging/GOOGLE_CLOUD_PROJECTLocal development
For local development, secrets are not required from 1Password. The pnpm env:configure script generates a .env file with safe local defaults:
pnpm env:configureThis writes defaults like AUTH_SECRET=local-dev-auth-secret-123456 and DATABASE_URL=postgres://postgres:postgres@localhost:5432/tx_agent_kit.
The .env file is gitignored and never committed.
Deployment workflow
During deployment, op inject renders the template into a usable .env file:
# Render staging secrets
op inject -i deploy/env/staging.env.template -o /tmp/staging.env
# Render production secrets
op inject -i deploy/env/prod.env.template -o /tmp/prod.envThe deploy scripts (pnpm deploy:staging, pnpm deploy:prod) handle this automatically. The rendered file is passed to Docker Compose via DEPLOY_ENV_FILE.
CLI operations
# Read a single secret
op read "op://octospark-services/staging/DATABASE_URL"
# Run a command with injected secrets
op run --env-file=deploy/env/staging.env.template -- <command>
# Inject template into file
op inject -i deploy/env/staging.env.template -o .env.renderedSecurity rules
| Rule | Details |
|---|---|
| No committed secrets | .env files are gitignored. Never commit rendered secrets |
| Templates are safe | .env.template, .env.dev, .env.prod contain only op:// references |
| No direct env reads | Source code must use typed config modules (apps/api config, apps/web/lib/env.ts, apps/worker/src/config/env.ts) |
| CLI guard | Deploy scripts verify that op is available before attempting to inject secrets |