hushsecrets your AI agent can use but never readGitHub

How the crypto works

                        ┌─ wrapped for ana ────┐
  vault key (32B) ──────┼─ wrapped for sam ────┼──► .hush/vault.json
        │               └─ wrapped for ci  ──X  (ci is scoped: no vault key)
        │
        └─► AES-256-GCM per value, AAD = "hush/v2|<generation>|<set>|<KEY>"

  "staging" key (32B) ──── wrapped for ana, sam, ci   (a set with a key of its own)

  header { members, roles, sets each may read, key generations, key commitments }
        └─► Ed25519 signature by an admin

The vault file holds ciphertext, public keys, and metadata. That is all:

{
  "scheme": "hush/v3",
  "dek": { "generation": 2, "commit": "9f1c…", "wraps": { "a1b2…": { "epk": "…", "ct": "…" } } },
  "recipients": {
    "a1b2…": { "name": "ana", "pk": "hush_pk_…", "spk": "hush_spk_…", "role": "admin" },
    "c3d4…": { "name": "ci", "pk": "hush_pk_…", "role": "member", "ci": true, "sets": ["staging"] }
  },
  "setKeys": { "staging": { "generation": 1, "commit": "4e07…", "wraps": { "a1b2…": {}, "c3d4…": {} } } },
  "envs": {
    "default": {
      "DATABASE_URL": { "iv": "…", "ct": "…", "tag": "…", "gen": 2, "v": 2,
                        "updatedBy": "ana", "updatedAt": "2026-01-01T00:00:00Z" }
    }
  },
  "signature": { "by": "a1b2…", "sig": "…" }
}