using-sops
jssblck/agents
Manage encrypted secrets in repos using sops and age identities.
What is using-sops?
Use sops-encrypted dotenv files (dev.env, prod.env) with age identities for secrets management. Decrypt and manage secrets via `pnpm secrets` wrapper without needing a secrets service or login. Supports dev, personal, and prod scopes with per-project production keys.
- Show, get, set, or unset encrypted secrets in dev and prod environments
- Execute commands with decrypted secrets injected into the environment
- Elevate to production secrets via documented 1Password or vault integration
- Manage multiple identities (agent, personal, prod) with different scopes and access levels
- Validate production access before attempting decryption
How to install using-sops
npx skills add https://github.com/jssblck/agents --skill using-sops- Repository configured with .sops.yaml and encrypted secrets/dev.env and/or secrets/prod.env files
- pnpm secrets wrapper (tools/secrets.ts) installed in the repo
- Age private key in ~/.config/sops/age/keys.txt (agent identity) or SOPS_AGE_KEY environment variable
- 1Password CLI (op) installed if using vault-based production key elevation
How to use using-sops
- 1.Run `pnpm secrets show dev` to view all decrypted dev secrets
- 2.Use `pnpm secrets get dev KEY_NAME` to retrieve a single secret value
- 3.Run `pnpm secrets set dev KEY_NAME value` to add or update a dev secret
- 4.Execute `pnpm secrets exec dev -- command` to run a command with decrypted secrets in its environment
- 5.For production access, run `pnpm secrets exec prod -- true` to check if you have access
- 6.If prod access fails, read the repo's secrets guide to find the documented vault location, then run `op read 'op://VAULT/ITEM/FIELD' --account ACCOUNT | pnpm secrets elevate` to store the key
- 7.After elevation, confirm with `pnpm secrets exec prod -- true`, then proceed with prod tasks
Use cases
- Decrypt and inject dev secrets into a local worker or service startup
- Retrieve a single secret value (e.g., API key) for use in a script
- Add a new environment variable to all encrypted secret files in a project
- Gain temporary production secret access by elevating with a vault-stored key
- Verify production secret access is available before running a deployment task
- Developers working in repos using sops-encrypted secrets
- Agents and automation running in cloud sandboxes with age keys
- Teams managing per-project production credentials with key rotation
- Users needing to access secrets without a centralized secrets service or login session
using-sops FAQ
agent is a user-wide key in ~/.config/sops/age/keys.txt used for dev secrets across all projects; personal is a user-wide key stored in a password manager for files listing its public key; prod is a per-project key stored in that project's production platform, so a leaked prod secret only exposes one project.
Always use `pnpm secrets` (the wrapper in tools/secrets.ts) if the repo has one. Do not call sops directly.
Add it to the env schema, then run `pnpm secrets set dev VARIABLE_NAME value` for dev and repeat for prod if you can decrypt it. If you cannot decrypt prod, note that in the PR; the typed env check will fail prod boot until the value is set.
Check the repo's secrets guide and .sops.yaml to identify the correct 1Password account, vault, and item. Use `op account list`, `op vault list`, and `op item list` to locate the key, then pipe it to `pnpm secrets elevate`. Never print the key itself.
No. Elevation is per checkout and lasts until .age/elevated is deleted. Do not copy it between worktrees.
Full instructions (SKILL.md)
Source of truth, from jssblck/agents.
name: using-sops description: "Use for secrets or key setup in a repo with .sops.yaml, encrypted environment files, or a pnpm secrets script."
Using sops
Repositories that use this layout commit their secrets to git as sops-encrypted
dotenv files, one per deployment environment: secrets/dev.env, secrets/prod.env. The
files decrypt with age identities. There is no .env, no secrets service, and no session
to log in to. Every checkout, worktree, and cloud sandbox has the encrypted files at
clone; the only input anywhere is an age private key.
pnpm secrets (tools/secrets.ts) is the only interface. Do not call sops directly in a
repo that has the wrapper.
Identities
| Identity | Scope | Where the private key lives | Decrypts |
|---|---|---|---|
agent | user-wide | ~/.config/sops/age/keys.txt on every machine agents run on; SOPS_AGE_KEY in cloud sandboxes | dev.env |
personal | user-wide | the user's password manager | files listing its public key |
prod | per project | that project's production platform and documented password-manager item | prod.env |
.sops.yaml lists recipients by public key. Encrypting needs no private key; decrypting
or editing needs one recipient's private key. agent and personal are local-development
keys shared by every project; prod is minted per project so one leaked deploy variable
exposes one project. These are conventions, not guaranteed recipients. Existing repos
may use only shared dev and prod keys. Read the repository's secrets guide and
.sops.yaml before choosing a key; the encrypted file's recipient metadata determines
which identities can decrypt it.
Agent workflow
Dev secrets are yours to manage without asking:
pnpm secrets show dev # everything, decrypted
pnpm secrets get dev STRIPE_KEY
pnpm secrets set dev STRIPE_KEY sk_test_1
pnpm secrets unset dev STRIPE_KEY
pnpm secrets exec dev -- node apps/worker/src/main.ts
exec puts the decrypted values in the child's environment (over the shell's), removes
SOPS_AGE_KEY* from it, forwards signals, and exits with the child's status.
When an authorized task needs production secrets, perform elevation yourself. Do not ask the user to run the command or reconfirm an already authorized task.
- Check access with
pnpm secrets exec prod -- true, which prints no secret values. An existing.age/elevatedfile alone does not prove that its key can decrypt prod. - If access fails, read the repo's secrets guide and recipient configuration. Use the
documented account, vault, item, and field for a matching key. Do not assume a
Personalvault, anage-personalrecipient, or the CLI's default account. - Run the documented read yourself, piping the key directly into the wrapper:
op read 'op://VAULT/ITEM/FIELD' --account ACCOUNT | pnpm secrets elevate. Replace the placeholders with the discovered identifiers; never print the key. - Confirm decryption with
pnpm secrets exec prod -- true, then continue the task.
When the documented 1Password location is missing, use op account list --format json
and op vault list --account ACCOUNT --format json to identify the correct account and
vault. Search item metadata in that vault for the documented key name with
op item list --account ACCOUNT --vault VAULT --format json; inspect only matching
items. Pass --account on subsequent reads. Private, Personal, and Shared are
distinct names, not interchangeable aliases. If a key is found but cannot decrypt,
compare its public key with the file's recipients instead of repeatedly trying vault
names. Keep private keys out of tool output.
Ask the user only when progress requires their interaction, such as unlocking
1Password or granting unavailable access. State the actual blocker. Elevation is per
checkout and lasts until .age/elevated is deleted; do not copy it into another worktree.
When you add a variable, add it to the env schema and to every secrets/<env>.env you can
decrypt. If you cannot decrypt prod, say so in the PR: the typed env check fails the prod
boot until the value is set, which is the intended signal.
Never write an AGE-SECRET-KEY-... into a tracked file, a log, or a commit. Never put personal or prod in a cloud
environment.
Human setup
For the one-time steps (generating keys, installing sops and age, wiring the agent
key into agent tools and cloud sandboxes, configuring the prod platform, and rotating
keys), read references/setup.md. When the user asks
to be reminded of the steps, walk them through that file in order.
For the sops and age behavior the design relies on (identity union, updatekeys,
exec-env limitations, dotenv quirks), read references/sops-notes.md.
Related skills
More from jssblck/agents and the wider catalog.

code-craft
Apply established engineering conventions for architecture, typing, error handling, and abstraction decisions.

gh-stack
GitHub CLI extension for managing stacked branches and dependent pull requests.

merge-open-prs
Merge multiple open pull requests in dependency order without creating stacks.

parallel-agents
Coordinate concurrent agent work and prevent merge conflicts in shared codebases.

markitdown
Convert PDFs, Word, PowerPoint, Excel, images, audio, and web content to Markdown for LLM pipelines.

brief-to-tasks
Break design briefs into ordered, independently buildable tasks using vertical slices.