---
name: secrets
description: Manage the project vault and granted org-infra secrets.
---

**Host-native invocation:** Claude `/mmi:secrets` · Codex `$mmi:secrets` · jervcode `/secrets` · Hermes skill_view. A backticked `/name` in this doc names the matching workflow (this skill or a sibling), not a literal command.

# /secrets — two-tier project secrets

**Authority:** a project-admin (`mmi-cli oracle org access role` → `project-admin` + `train`) self-serves their own repo's full vault tree: stageless, `dev`, `rc`, `main`. Project-admin = repo `admin`, or `write`/`maintain` plus the registry `projectAdmins` entry; master = org owner. The backend checks both server-side. Only org-infra grants and cross-project administration are master-only. Every write is attributable (actor + repo + KEY name, never the value). A value is never shown (principle 11).

- **YOUR REPO** — `/mmi-future/<slug>/<KEY>` (stageless canonical, one value for every stage, the path deploys resolve) plus `/mmi-future/<slug>/{dev,rc,main}/*` (per-stage overrides). A staged `dev/<KEY>` WINS for that stage at deploy; `set`/`use` warn (names only) when an override shadows the canonical. The `dev`/non-`dev` `tier` field in older JSON is compatibility metadata, not an authority boundary.
- **ORG-INFRA** — `/mmi-future/{shared,cloudflare,docs,mmi-hub}/*` at every tier. Master-only; a project-admin reaches one only via a master **grant**. For grants (including read-only wildcards), read [reference.md](reference.md) first.

**Declare-first:** the registry catalog is the SSOT; SSM is its projection. A `set` to an undeclared coordinate is rejected (the error names the path and fix); no master bypass. Declare with `mmi-cli oracle org project set <owner/repo> --secrets-file <catalog.json>` (`stages: []` = stageless canonical, `stages: ["dev"]` = override), then retry. See declared keys with `mmi-cli vault secrets catalog` or `secrets list`; ask for a missing key with `mmi-cli vault secrets request <KEY>`. `rm` of an undeclared path stays allowed. Google OAuth is one stageless pair at the slug root, bare `GOOGLE_CLIENT_ID` + `GOOGLE_CLIENT_SECRET` (`org oauth set-creds` writes them; the staged shape is retired).

All ops run through `mmi-cli vault secrets …`, which calls the org backend with the caller's `gh` token; the backend re-verifies project-admin and namespace and does the scoped SSM op. This skill never touches AWS.

## Step 0 — orient

```bash
mmi-cli vault secrets list    # names + tier + * on those you can write; never values
```

`secrets: no registry META` or `Hub API unreachable` → repo unregistered, GitHub auth missing, or Hub down. Run `mmi-cli oracle org project get <owner/repo>` to tell which; a master-admin backfills the registry.

## Step 1 — the verb

Current repo by default; `--repo owner/Name` targets another (you must be its project-admin).

```bash
mmi-cli vault secrets use SCRAPER_API_KEY -- <cmd>            # consume keyless: injected into env, never printed
printf %s "$THE_VALUE" | mmi-cli vault secrets set SCRAPER_API_KEY   # write/rotate: value from stdin, never an argument
mmi-cli vault secrets verify RECALL_API_KEY                   # validate a known provider key
mmi-cli vault secrets rm SCRAPER_API_KEY
```

There is no value argument; confirmation prints name and tier only. On Windows, read [reference.md](reference.md) before wrapping a multiline command. For rotation, org-infra elevation, new-key coordinates, or tier-to-tier copies, read [reference.md](reference.md) first.

Runtime consumes declared keys through its scoped broker token (central deploy injects the declared stage set, no repo `.env`); CI reads keylessly through its OIDC role. Treat every secret as write-once.

## Retro

If this skill's instructions misfired (process only, e.g. a canonical-name or tier mix-up), file one lesson (one per run; if the call fails, note it and continue):
`mmi-cli learning skill-lesson --skill secrets --title "<what misfired>" --body "<what; evidence; proposed amendment>"`
