[SECRETS]
op owns permanent local and session custody. Doppler owns project configuration and explicit process delivery.
Topology — projects, environments, configs, service tokens, directory scopes — lives as IaC rows in Parametric_Forge/services/topology.ts, materialized by estate.ts and applied by driver.ts over the Pulumi Automation API. doppler reads and writes secret values against declared configs; doppler run and owner-specific downloads inject values at the consuming process; ~/.doppler holds CLI scope and authentication state.
[01]-[ROUTING]
- [01]-PATTERNS: pattern doctrine — template rendering, mounts, multi-command wrappers, plan-gated features.
[02]-[RESOLUTION]
~/.doppler is the CLI config dir; scopes ride ~/.doppler/.doppler.yaml, written by doppler configure set through the driver's scopes apply.
- A repo-local
doppler.yaml is vendor setup guidance, not the estate scope owner; the estate carries none.
- Precedence, highest first: a service token's embedded project/config, runtime flags, env vars, config-file scope.
- Config-file scope resolves an exact directory match before the nearest ancestor.
- Scope env vars:
DOPPLER_TOKEN, DOPPLER_PROJECT, DOPPLER_CONFIG, DOPPLER_CONFIG_DIR, DOPPLER_PASSPHRASE.
- Agents pass
--project/--config explicitly; env carries only token custody.
- An ambient
DOPPLER_TOKEN outranks flags and represents one config; strip it with env -u DOPPLER_TOKEN when fetching more than one source.
[03]-[DOPPLER_CLI]
| [INDEX] |
[TASK] |
[COMMAND] |
| [01] |
Binary and version proof |
doppler --version |
| [02] |
Effective options, token stripped |
doppler configure debug --json | jq 'with_entries(.value |= del(.token))' |
| [03] |
Every scope row, token stripped |
doppler configure --all --json | jq 'with_entries(.value |= del(.token))' |
| [04] |
One directory's scope |
doppler configure get project config --scope <dir> --json |
| [05] |
Set a scope row |
doppler configure set project=<p> config=<c> --scope <dir> |
| [06] |
Unset a scope row |
doppler configure unset project config --scope <dir> |
| [07] |
Key inventory |
doppler secrets download --project <p> --config <c> --no-file --format json | jq 'keys' |
| [08] |
Inject env into a process |
doppler run --project <p> --config <c> --command '<cmd>' |
| [09] |
Render a template |
doppler secrets substitute <template> |
- One directory's scope keys land as
enclave.project, enclave.config; the set is driver-owned and scope / stays untouched.
- Secret downloads pipe to
jq 'keys' or jq 'length'; configure reads strip the root token with del(.token), since a bare configure debug or configure --all prints it.
- Receipts, transcripts, and logs carry key names and counts, never values or tokens.
[04]-[OP_CLI]
op reads the local store directly; the field suffix is token, credential, or password per item. An exported OP_SERVICE_ACCOUNT_TOKEN pins op to the Tokens vault, so Personal (the SSH key) resolves only under env -u OP_SERVICE_ACCOUNT_TOKEN.
| [INDEX] |
[TASK] |
[COMMAND] |
| [01] |
Auth proof |
op whoami |
| [02] |
Vault inventory |
op vault list |
| [03] |
Tokens item names |
op item list --vault Tokens --format json | jq -r '.[].title' |
| [04] |
Read one secret |
op read "op://Tokens/<ITEM>/<token|credential|password>" |
| [05] |
Resolve the rebuild template |
op inject -i ~/.config/op/env.template -o <out> |
| [06] |
Personal-vault SSH item |
env -u OP_SERVICE_ACCOUNT_TOKEN op item get "Forge SSH Key" --vault Personal |
| [07] |
Rename an item to its real name |
op item edit "<old-title>" title="<official-name>" --vault Tokens |
op serves the SSH key to ssh, git, WezTerm, Yazi, and rclone through the 1Password agent socket; the item ref lives in 1Password/ssh/agent.toml, never a private key on disk.
- Read a secret only to verify presence or wire a one-off; standing local consumption rides the activation-generated session cache.
[05]-[SESSION_CUSTODY]
op inject resolves ~/.config/op/env.template into the mode-600 ~/.config/hm-op-session.sh cache on every forge-redeploy --switch. Interactive shells source that cache through forge-session-secrets.sh; gui-op-secrets projects the same names into the launchd GUI domain for newly spawned applications. Process-specific Doppler consumers fetch their material explicitly with the owning project and config.
~/.config/op/env.template owns the local session key set; activation keeps values outside the Nix store.
forge-session-secrets.sh is the shell source path; gui-op-secrets is the GUI projection path.
- Doppler delivery stays at the process boundary through
doppler run or an owner-specific doppler secrets download.
[06]-[CUSTODY]
Local custody is op, never the OS keychain: every service and IaC token and the SSH key live in a Tokens or Personal vault item. A personal doppler login is the one credential Doppler keeps in the keychain, used for the operator's ad-hoc interactive work alone — no rail depends on it.
| [INDEX] |
[CLASS] |
[CUSTODY] |
[USE] |
| [01] |
Config-scoped service token |
Pulumi stack secret output |
Explicit runtime reads |
| [02] |
IaC admin token |
op://Tokens/DOPPLER_IAC_TOKEN/token |
Topology writes via Pulumi only |
| [03] |
Pulumi stack passphrase |
op://Tokens/PULUMI_FORGE_SERVICES/password |
Stack state decryption |
| [04] |
Provider PATs (GitHub and peers) |
op://Tokens items, mirrored into configs |
Activation or process injection |
- Config-scoped service token: minted by topology rows; static Developer-plan tokens are revoked and reminted, never rotated in place.
- IaC admin token and stack passphrase: brokered by
driver.ts; an ambient DOPPLER_TOKEN or PULUMI_CONFIG_PASSPHRASE short-circuits the op read per run.
- Provider PATs are never topology identity.
[07]-[LAW]
- One item, one official name: an item carries the credential's real published name, never a handrolled synonym; a consumer needing a different env-var name renames the item at the source and repoints every reader, never adds a second item or a duplicate export aliasing the same secret. A naming mistake is fixed by renaming in
op and Doppler, never papered over.
- A new project lands as project/config rows in
Parametric_Forge/services/topology.ts and a directory scope row, then pulumi up; retiring it deletes its rows.
- A repo carries zero Doppler files; its agents resolve through scope and hook automatically.
- Rendered secret material is ephemeral:
--mount/--mount-template over durable renders; plaintext binds only where the target owner requires it.
1---2name: secrets3description: Owns secret custody over 1Password and Doppler — op the permanent local store and SSH-key custodian, Doppler the runtime backend. Use when creating a secret, token, or env key or when one fails to resolve, creating and managing them, the op agent key, a tool or code logic needs a scoped token, or a config file needs secret material. Minting tokens and creating projects, configs, or scopes is Pulumi topology in Parametric_Forge/services/topology.ts — the pulumi skill.4---56# [SECRETS]78`op` owns permanent local and session custody. Doppler owns project configuration and explicit process delivery.910Topology — projects, environments, configs, service tokens, directory scopes — lives as IaC rows in `Parametric_Forge/services/topology.ts`, materialized by `estate.ts` and applied by `driver.ts` over the Pulumi Automation API. `doppler` reads and writes secret values against declared configs; `doppler run` and owner-specific downloads inject values at the consuming process; `~/.doppler` holds CLI scope and authentication state.1112## [01]-[ROUTING]1314- [01]-[PATTERNS](references/patterns.md): pattern doctrine — template rendering, mounts, multi-command wrappers, plan-gated features.1516## [02]-[RESOLUTION]1718- `~/.doppler` is the CLI config dir; scopes ride `~/.doppler/.doppler.yaml`, written by `doppler configure set` through the driver's `scopes apply`.19- A repo-local `doppler.yaml` is vendor setup guidance, not the estate scope owner; the estate carries none.20- Precedence, highest first: a service token's embedded project/config, runtime flags, env vars, config-file scope.21- Config-file scope resolves an exact directory match before the nearest ancestor.22- Scope env vars: `DOPPLER_TOKEN`, `DOPPLER_PROJECT`, `DOPPLER_CONFIG`, `DOPPLER_CONFIG_DIR`, `DOPPLER_PASSPHRASE`.23- Agents pass `--project`/`--config` explicitly; env carries only token custody.24- An ambient `DOPPLER_TOKEN` outranks flags and represents one config; strip it with `env -u DOPPLER_TOKEN` when fetching more than one source.2526## [03]-[DOPPLER_CLI]2728| [INDEX] | [TASK] | [COMMAND] |29| :-----: | :-------------------------------- | :----------------------------------------------------------------------------------------- |30| [01] | Binary and version proof | `doppler --version` |31| [02] | Effective options, token stripped | `doppler configure debug --json \| jq 'with_entries(.value \|= del(.token))'` |32| [03] | Every scope row, token stripped | `doppler configure --all --json \| jq 'with_entries(.value \|= del(.token))'` |33| [04] | One directory's scope | `doppler configure get project config --scope <dir> --json` |34| [05] | Set a scope row | `doppler configure set project=<p> config=<c> --scope <dir>` |35| [06] | Unset a scope row | `doppler configure unset project config --scope <dir>` |36| [07] | Key inventory | `doppler secrets download --project <p> --config <c> --no-file --format json \| jq 'keys'` |37| [08] | Inject env into a process | `doppler run --project <p> --config <c> --command '<cmd>'` |38| [09] | Render a template | `doppler secrets substitute <template>` |3940- One directory's scope keys land as `enclave.project`, `enclave.config`; the set is driver-owned and scope `/` stays untouched.41- Secret downloads pipe to `jq 'keys'` or `jq 'length'`; configure reads strip the root token with `del(.token)`, since a bare `configure debug` or `configure --all` prints it.42- Receipts, transcripts, and logs carry key names and counts, never values or tokens.4344## [04]-[OP_CLI]4546`op` reads the local store directly; the field suffix is `token`, `credential`, or `password` per item. An exported `OP_SERVICE_ACCOUNT_TOKEN` pins `op` to the `Tokens` vault, so `Personal` (the SSH key) resolves only under `env -u OP_SERVICE_ACCOUNT_TOKEN`.4748| [INDEX] | [TASK] | [COMMAND] |49| :-----: | :------------------------------ | :----------------------------------------------------------------------------- |50| [01] | Auth proof | `op whoami` |51| [02] | Vault inventory | `op vault list` |52| [03] | Tokens item names | `op item list --vault Tokens --format json \| jq -r '.[].title'` |53| [04] | Read one secret | `op read "op://Tokens/<ITEM>/<token\|credential\|password>"` |54| [05] | Resolve the rebuild template | `op inject -i ~/.config/op/env.template -o <out>` |55| [06] | Personal-vault SSH item | `env -u OP_SERVICE_ACCOUNT_TOKEN op item get "Forge SSH Key" --vault Personal` |56| [07] | Rename an item to its real name | `op item edit "<old-title>" title="<official-name>" --vault Tokens` |5758- `op` serves the SSH key to `ssh`, `git`, WezTerm, Yazi, and rclone through the 1Password agent socket; the item ref lives in `1Password/ssh/agent.toml`, never a private key on disk.59- Read a secret only to verify presence or wire a one-off; standing local consumption rides the activation-generated session cache.6061## [05]-[SESSION_CUSTODY]6263`op inject` resolves `~/.config/op/env.template` into the mode-600 `~/.config/hm-op-session.sh` cache on every `forge-redeploy --switch`. Interactive shells source that cache through `forge-session-secrets.sh`; `gui-op-secrets` projects the same names into the launchd GUI domain for newly spawned applications. Process-specific Doppler consumers fetch their material explicitly with the owning project and config.6465- `~/.config/op/env.template` owns the local session key set; activation keeps values outside the Nix store.66- `forge-session-secrets.sh` is the shell source path; `gui-op-secrets` is the GUI projection path.67- Doppler delivery stays at the process boundary through `doppler run` or an owner-specific `doppler secrets download`.6869## [06]-[CUSTODY]7071Local custody is `op`, never the OS keychain: every service and IaC token and the SSH key live in a `Tokens` or `Personal` vault item. A personal `doppler login` is the one credential Doppler keeps in the keychain, used for the operator's ad-hoc interactive work alone — no rail depends on it.7273| [INDEX] | [CLASS] | [CUSTODY] | [USE] |74| :-----: | :------------------------------- | :------------------------------------------- | :------------------------------ |75| [01] | Config-scoped service token | Pulumi stack secret output | Explicit runtime reads |76| [02] | IaC admin token | `op://Tokens/DOPPLER_IAC_TOKEN/token` | Topology writes via Pulumi only |77| [03] | Pulumi stack passphrase | `op://Tokens/PULUMI_FORGE_SERVICES/password` | Stack state decryption |78| [04] | Provider PATs (GitHub and peers) | `op://Tokens` items, mirrored into configs | Activation or process injection |7980- Config-scoped service token: minted by topology rows; static Developer-plan tokens are revoked and reminted, never rotated in place.81- IaC admin token and stack passphrase: brokered by `driver.ts`; an ambient `DOPPLER_TOKEN` or `PULUMI_CONFIG_PASSPHRASE` short-circuits the op read per run.82- Provider PATs are never topology identity.8384## [07]-[LAW]8586- One item, one official name: an item carries the credential's real published name, never a handrolled synonym; a consumer needing a different env-var name renames the item at the source and repoints every reader, never adds a second item or a duplicate export aliasing the same secret. A naming mistake is fixed by renaming in `op` and Doppler, never papered over.87- A new project lands as project/config rows in `Parametric_Forge/services/topology.ts` and a directory scope row, then `pulumi up`; retiring it deletes its rows.88- A repo carries zero Doppler files; its agents resolve through scope and hook automatically.89- Rendered secret material is ephemeral: `--mount`/`--mount-template` over durable renders; plaintext binds only where the target owner requires it.