# Credential Vault Templates (ADR-017)

Three starting templates for adopting the credential vault model. Copy the snippet
that matches your tenancy needs into your project's `.ontoref/project.ncl` and
`.ontology/manifest.ncl`. None is mandatory — the schema fields are optional and
projects can declare them ad-hoc.

## Pick one

| Template | When to use |
|---|---|
| **single-team** | One team, no tenant separation. CI uses same credentials as developers. |
| **multi-tenant** | Multiple clients/projects share the same vault but must not see each other's credentials. |
| **agent-first** | AI agents (MCP) consume credentials with strict RO scope; humans operate normally. |

## Layout

```text
single-team/
  project.ncl.snippet     ← paste into <your-project>/.ontoref/project.ncl
  manifest.ncl.snippet    ← paste into <your-project>/.ontology/manifest.ncl
multi-tenant/
  project.ncl.snippet
  manifest.ncl.snippet
agent-first/
  project.ncl.snippet
  manifest.ncl.snippet
```

## Snippet conventions

- `<placeholder>` — replace with project-specific value
- `age1...` — generate via `age-keygen -o ~/.age/keys/<name>.key.txt`, copy
  the public key from the line `# public key: ...`
- All paths in `credential_sops` / `credential_sops_rw` are relative to the
  src-vault root (i.e. `~/.config/ontoref/vaults/<vault_id>/src-vault/`)

## Migration from one template to another

Templates only differ in `recipient_groups` + `recipient_rules` and the
`credential_sops` paths. To switch:

1. Edit `project.ncl::sops.recipient_groups` + `recipient_rules`
2. Edit `manifest.ncl::registry_provides.registries[].credential_sops*`
3. `ore secrets rekey` — regenerates `<vault>/.sops.yaml` and re-encrypts
4. `ore secrets close` — pushes the updated state

## No template: legacy minimal

If none of the templates fits, the minimal viable path is:

```ncl
sops = {
  enabled            = true,
  vault_id           = "<your-slug>",
  master_key_path    = "/path/to/.kage",
  vault_backend      = 'restic,
  registry_endpoint  = "<your-zot-host>",
  actor_key_bindings = { developer = "developer" },
}
```

`recipient_groups` + `recipient_rules` left absent. The bootstrap will require
`SOPS_AGE_RECIPIENTS` env var listing all recipient public keys. Same recipients
across all encrypted files. Path A in the FAQ.
