hermes-vault 0.8.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. hermes_vault-0.8.0/LICENSE +21 -0
  2. hermes_vault-0.8.0/MANIFEST.in +2 -0
  3. hermes_vault-0.8.0/PKG-INFO +384 -0
  4. hermes_vault-0.8.0/README.md +362 -0
  5. hermes_vault-0.8.0/data/oauth-default-providers.yaml +41 -0
  6. hermes_vault-0.8.0/pyproject.toml +47 -0
  7. hermes_vault-0.8.0/setup.cfg +4 -0
  8. hermes_vault-0.8.0/src/hermes_vault/__init__.py +5 -0
  9. hermes_vault-0.8.0/src/hermes_vault/audit.py +132 -0
  10. hermes_vault-0.8.0/src/hermes_vault/backup.py +115 -0
  11. hermes_vault-0.8.0/src/hermes_vault/broker.py +505 -0
  12. hermes_vault-0.8.0/src/hermes_vault/cli.py +2143 -0
  13. hermes_vault-0.8.0/src/hermes_vault/config.py +123 -0
  14. hermes_vault-0.8.0/src/hermes_vault/crypto.py +83 -0
  15. hermes_vault-0.8.0/src/hermes_vault/dashboard.py +704 -0
  16. hermes_vault-0.8.0/src/hermes_vault/dashboard_static/app.js +434 -0
  17. hermes_vault-0.8.0/src/hermes_vault/dashboard_static/assets/hermes-vault-console-brand.png +0 -0
  18. hermes_vault-0.8.0/src/hermes_vault/dashboard_static/index.html +153 -0
  19. hermes_vault-0.8.0/src/hermes_vault/dashboard_static/styles.css +825 -0
  20. hermes_vault-0.8.0/src/hermes_vault/detectors.py +243 -0
  21. hermes_vault-0.8.0/src/hermes_vault/diff.py +107 -0
  22. hermes_vault-0.8.0/src/hermes_vault/health.py +280 -0
  23. hermes_vault-0.8.0/src/hermes_vault/logging_redaction.py +56 -0
  24. hermes_vault-0.8.0/src/hermes_vault/maintenance.py +188 -0
  25. hermes_vault-0.8.0/src/hermes_vault/mcp_server.py +733 -0
  26. hermes_vault-0.8.0/src/hermes_vault/models.py +175 -0
  27. hermes_vault-0.8.0/src/hermes_vault/mutations.py +294 -0
  28. hermes_vault-0.8.0/src/hermes_vault/oauth/__init__.py +11 -0
  29. hermes_vault-0.8.0/src/hermes_vault/oauth/callback.py +104 -0
  30. hermes_vault-0.8.0/src/hermes_vault/oauth/errors.py +42 -0
  31. hermes_vault-0.8.0/src/hermes_vault/oauth/exchange.py +151 -0
  32. hermes_vault-0.8.0/src/hermes_vault/oauth/flow.py +249 -0
  33. hermes_vault-0.8.0/src/hermes_vault/oauth/normalize.py +214 -0
  34. hermes_vault-0.8.0/src/hermes_vault/oauth/oauth_refresh.py +484 -0
  35. hermes_vault-0.8.0/src/hermes_vault/oauth/pkce.py +29 -0
  36. hermes_vault-0.8.0/src/hermes_vault/oauth/providers.py +140 -0
  37. hermes_vault-0.8.0/src/hermes_vault/oauth/state.py +41 -0
  38. hermes_vault-0.8.0/src/hermes_vault/permissions.py +34 -0
  39. hermes_vault-0.8.0/src/hermes_vault/policy.py +280 -0
  40. hermes_vault-0.8.0/src/hermes_vault/policy_doctor.py +538 -0
  41. hermes_vault-0.8.0/src/hermes_vault/scanner.py +150 -0
  42. hermes_vault-0.8.0/src/hermes_vault/service_ids.py +144 -0
  43. hermes_vault-0.8.0/src/hermes_vault/skillgen.py +163 -0
  44. hermes_vault-0.8.0/src/hermes_vault/ui.py +331 -0
  45. hermes_vault-0.8.0/src/hermes_vault/update.py +391 -0
  46. hermes_vault-0.8.0/src/hermes_vault/vault.py +749 -0
  47. hermes_vault-0.8.0/src/hermes_vault/verifier.py +193 -0
  48. hermes_vault-0.8.0/src/hermes_vault.egg-info/PKG-INFO +384 -0
  49. hermes_vault-0.8.0/src/hermes_vault.egg-info/SOURCES.txt +86 -0
  50. hermes_vault-0.8.0/src/hermes_vault.egg-info/dependency_links.txt +1 -0
  51. hermes_vault-0.8.0/src/hermes_vault.egg-info/entry_points.txt +2 -0
  52. hermes_vault-0.8.0/src/hermes_vault.egg-info/requires.txt +12 -0
  53. hermes_vault-0.8.0/src/hermes_vault.egg-info/top_level.txt +1 -0
  54. hermes_vault-0.8.0/tests/test_audit.py +415 -0
  55. hermes_vault-0.8.0/tests/test_backup_recovery.py +111 -0
  56. hermes_vault-0.8.0/tests/test_broker.py +443 -0
  57. hermes_vault-0.8.0/tests/test_cli.py +1098 -0
  58. hermes_vault-0.8.0/tests/test_config.py +39 -0
  59. hermes_vault-0.8.0/tests/test_dashboard.py +687 -0
  60. hermes_vault-0.8.0/tests/test_detectors.py +106 -0
  61. hermes_vault-0.8.0/tests/test_diff.py +193 -0
  62. hermes_vault-0.8.0/tests/test_end_to_end.py +48 -0
  63. hermes_vault-0.8.0/tests/test_governance.py +164 -0
  64. hermes_vault-0.8.0/tests/test_health.py +259 -0
  65. hermes_vault-0.8.0/tests/test_key_management.py +115 -0
  66. hermes_vault-0.8.0/tests/test_maintenance.py +208 -0
  67. hermes_vault-0.8.0/tests/test_mcp_server.py +460 -0
  68. hermes_vault-0.8.0/tests/test_mutations.py +572 -0
  69. hermes_vault-0.8.0/tests/test_oauth.py +254 -0
  70. hermes_vault-0.8.0/tests/test_oauth_exchange.py +252 -0
  71. hermes_vault-0.8.0/tests/test_oauth_flow.py +618 -0
  72. hermes_vault-0.8.0/tests/test_oauth_normalize.py +92 -0
  73. hermes_vault-0.8.0/tests/test_oauth_refresh.py +733 -0
  74. hermes_vault-0.8.0/tests/test_permissions.py +18 -0
  75. hermes_vault-0.8.0/tests/test_policy.py +596 -0
  76. hermes_vault-0.8.0/tests/test_policy_doctor.py +248 -0
  77. hermes_vault-0.8.0/tests/test_policy_preprocessing.py +209 -0
  78. hermes_vault-0.8.0/tests/test_redaction.py +23 -0
  79. hermes_vault-0.8.0/tests/test_refresh.py +317 -0
  80. hermes_vault-0.8.0/tests/test_release_regression.py +249 -0
  81. hermes_vault-0.8.0/tests/test_scanner.py +72 -0
  82. hermes_vault-0.8.0/tests/test_service_ids.py +130 -0
  83. hermes_vault-0.8.0/tests/test_skillgen.py +30 -0
  84. hermes_vault-0.8.0/tests/test_status.py +592 -0
  85. hermes_vault-0.8.0/tests/test_sync_skill.py +224 -0
  86. hermes_vault-0.8.0/tests/test_update.py +208 -0
  87. hermes_vault-0.8.0/tests/test_vault.py +271 -0
  88. hermes_vault-0.8.0/tests/test_verifier.py +57 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tony Simons
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ include data/*.yaml
2
+ recursive-include src/hermes_vault/dashboard_static *
@@ -0,0 +1,384 @@
1
+ Metadata-Version: 2.4
2
+ Name: hermes-vault
3
+ Version: 0.8.0
4
+ Summary: Hermes-native local-first credential broker, scanner, and encrypted vault.
5
+ Author: Tony Simons
6
+ License-Expression: MIT
7
+ Requires-Python: >=3.11
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: cryptography>=42.0.0
11
+ Requires-Dist: mcp>=1.0.0
12
+ Requires-Dist: pydantic>=2.7.0
13
+ Requires-Dist: PyYAML>=6.0.0
14
+ Requires-Dist: rich>=13.7.0
15
+ Requires-Dist: typer>=0.12.0
16
+ Requires-Dist: pathspec>=0.12.1
17
+ Requires-Dist: requests>=2.31.0
18
+ Provides-Extra: dev
19
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
20
+ Requires-Dist: mcp>=1.0.0; extra == "dev"
21
+ Dynamic: license-file
22
+
23
+ # Hermes Vault
24
+
25
+ Hermes Vault is a local-first credential broker and encrypted vault for Hermes agents. It scans for risky plaintext secrets, stores credentials locally, verifies them before re-auth claims, and generates skill contracts that keep agents on the same workflow.
26
+
27
+ ![Hermes Vault CLI banner](assets/hermes-vault.png)
28
+
29
+ ## What It Does
30
+
31
+ - Scans Hermes-relevant files for plaintext secrets, duplicates, and insecure permissions
32
+ - Encrypts credentials in a local SQLite-backed vault
33
+ - Brokers access with per-agent policy and ephemeral environment materialization
34
+ - Verifies credentials before any re-auth recommendation
35
+ - Generates `SKILL.md` files for Hermes agents and sub-agents
36
+ - Provides a token-guarded local dashboard for operator visibility and safe actions
37
+
38
+ ## Install
39
+
40
+ Released CLI installs are safest with an isolated tool manager:
41
+
42
+ ```bash
43
+ uv tool install git+https://github.com/asimons81/hermes-vault.git@vX.Y.Z
44
+ pipx install git+https://github.com/asimons81/hermes-vault.git@vX.Y.Z
45
+ ```
46
+
47
+ For local development, use `uv` or editable `pip`:
48
+
49
+ ```bash
50
+ uv sync --extra dev
51
+ ```
52
+
53
+ Or with pip:
54
+
55
+ ```bash
56
+ python3 -m pip install -e .[dev]
57
+ ```
58
+
59
+ Hermes Vault targets Python 3.11+.
60
+
61
+ ## Update
62
+
63
+ Check for the latest tagged release without changing the environment:
64
+
65
+ ```bash
66
+ hermes-vault update --check
67
+ ```
68
+
69
+ Apply a guarded update:
70
+
71
+ ```bash
72
+ hermes-vault update
73
+ ```
74
+
75
+ `hermes-vault update` currently auto-updates only for `pipx` and `uv tool` installs. Editable/dev installs, generic `pip` installs, and unknown environments receive an explicit manual command instead of an automatic mutation.
76
+
77
+ ## Quick Start
78
+
79
+ ```bash
80
+ export HERMES_VAULT_PASSPHRASE='choose-a-strong-local-passphrase'
81
+ hermes-vault --help
82
+ hermes-vault scan --path ~/.hermes
83
+ hermes-vault import --from-env ~/.hermes/.env --dry-run
84
+ hermes-vault import --from-env ~/.hermes/.env
85
+ hermes-vault verify --all
86
+ hermes-vault generate-skill --all-agents
87
+ ```
88
+
89
+ Default runtime state lives in `~/.hermes/hermes-vault-data`.
90
+
91
+ ## Importing `.env` Files
92
+
93
+ Preview first:
94
+
95
+ ```bash
96
+ hermes-vault import --from-env .env --dry-run
97
+ ```
98
+
99
+ The env importer reports both importable names and skipped names. Known hints and safe suffixes are imported automatically: `*_API_KEY`, `*_TOKEN`, `*_AUTH_TOKEN`, and `*_ACCESS_TOKEN`. Public config such as `NEXT_PUBLIC_*`, broad DB URLs, passwords, JWT/session/app secrets, and unknown names stay skipped unless you explicitly map them.
100
+
101
+ Use repeatable `--map` overrides when a skipped key is intentional:
102
+
103
+ ```bash
104
+ hermes-vault import --from-env .env --map CUSTOM_VENDOR_TOKEN=custom-vendor:personal_access_token
105
+ hermes-vault import --from-env .env --map DATABASE_URL=postgres:connection_url
106
+ ```
107
+
108
+ When `--redact-source` is used, only successfully imported env lines are commented out. Skipped lines remain unchanged and are counted in the summary. `--dry-run --redact-source` never changes the source file.
109
+
110
+ ## Dashboard
111
+
112
+ Start the local Hermes Vault Console:
113
+
114
+ ```bash
115
+ hermes-vault dashboard
116
+ hermes-vault dashboard --no-open
117
+ ```
118
+
119
+ The dashboard binds to `127.0.0.1` and prints a random tokenized URL for the current process. It shows vault health, credential inventory, policy findings, audit activity, MCP binding status, and recovery posture.
120
+
121
+ Dashboard actions are intentionally narrow: run health and policy doctor, verify credentials, refresh OAuth tokens, run maintenance, verify backups, and run restore dry-runs. It does not reveal raw secrets, expose encrypted payloads, edit credentials or policy, run destructive restore, sync to cloud, or bind remotely.
122
+
123
+ ## MCP Server
124
+
125
+ Hermes Vault exposes the broker as an MCP (Model Context Protocol) server so that compatible hosts can request credentials programmatically.
126
+
127
+ ```bash
128
+ hermes-vault mcp
129
+ ```
130
+
131
+ Configure your MCP host (Claude Desktop, Cursor, etc.) to run:
132
+
133
+ ```json
134
+ {
135
+ "mcpServers": {
136
+ "hermes-vault": {
137
+ "command": "hermes-vault",
138
+ "args": ["mcp"],
139
+ "env": {
140
+ "HERMES_VAULT_PASSPHRASE": "your-passphrase"
141
+ }
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ If the MCP server is started without an allowed-agent binding, every tool call still requires a caller-supplied `agent_id`. When the server is launched with both `HERMES_VAULT_MCP_ALLOWED_AGENTS` and `HERMES_VAULT_MCP_DEFAULT_AGENT`, the host may omit `agent_id` and the server uses the configured default agent within that allowed set.
148
+
149
+ Example bound launch:
150
+
151
+ ```bash
152
+ export HERMES_VAULT_MCP_ALLOWED_AGENTS='hermes,claude-desktop'
153
+ export HERMES_VAULT_MCP_DEFAULT_AGENT='claude-desktop'
154
+ hermes-vault mcp
155
+ ```
156
+
157
+ The same `policy.yaml` that gates CLI access also gates MCP access. The bound-agent env vars are a deployment guardrail, not a replacement for policy.
158
+
159
+ ### MCP Tools
160
+
161
+ | Tool | Description | Policy Gate |
162
+ |---|---|---|
163
+ | `list_services` | List credentials visible to the agent | `capability:list_credentials` |
164
+ | `get_credential_metadata` | Fetch credential metadata (no secrets) | `can_read(service)` |
165
+ | `get_ephemeral_env` | Materialise ephemeral env vars | `can_env(service)` |
166
+ | `verify_credential` | Verify a credential against its provider | `can_verify(service)` |
167
+ | `rotate_credential` | Rotate a credential to a new secret | `can_rotate(service)` |
168
+ | `scan_for_secrets` | Scan filesystem for plaintext secrets | `capability:scan_secrets` |
169
+ | `oauth_login` | Initiate PKCE OAuth login (returns auth URL) | `capability:add_credential` |
170
+ | `oauth_refresh` | Refresh an OAuth access token using stored refresh token | `action:rotate` |
171
+
172
+ Raw secrets are **never** transmitted over MCP. The default access pattern is `get_ephemeral_env`.
173
+
174
+ ### OAuth via MCP
175
+
176
+ Hermes Vault can broker OAuth logins so agents never handle raw passwords. `oauth_login` returns an authorization URL and spins up a callback server -- open the URL in a browser, and tokens are stored automatically. `oauth_refresh` renews tokens proactively before expiry. See [docs/mcp-server.md](docs/mcp-server.md) for full tool schemas.
177
+
178
+ ## Common Commands
179
+
180
+ ```bash
181
+ hermes-vault scan
182
+ hermes-vault update --check
183
+ hermes-vault import --from-env ~/.hermes/.env --dry-run
184
+ hermes-vault import --from-env ~/.hermes/.env
185
+ hermes-vault import --from-env ~/.hermes/.env --map CUSTOM_VENDOR_TOKEN=custom-vendor:personal_access_token
186
+ hermes-vault add openai --alias primary
187
+ hermes-vault list
188
+ hermes-vault verify openai
189
+ hermes-vault broker env openai --agent dwight --ttl 900
190
+ hermes-vault audit --agent dwight --since 7d
191
+ hermes-vault status
192
+ hermes-vault status --stale 7d
193
+ hermes-vault status --invalid
194
+ hermes-vault set-expiry openai --alias primary --days 90
195
+ hermes-vault clear-expiry openai --alias primary
196
+ hermes-vault verify --all --format table
197
+ hermes-vault verify --all --report ~/.hermes/hermes-vault-data/reports/verify-latest.json
198
+ hermes-vault health
199
+ hermes-vault health --format json
200
+ hermes-vault maintain --dry-run
201
+ hermes-vault maintain
202
+ hermes-vault maintain --print-systemd
203
+ hermes-vault dashboard --no-open
204
+ hermes-vault policy doctor
205
+ hermes-vault oauth normalize
206
+ hermes-vault backup-verify --input ~/vault-backup.json
207
+ hermes-vault restore --dry-run --input ~/vault-backup.json
208
+ hermes-vault sync-skill --check
209
+ hermes-vault backup --metadata-only --output ~/meta-backup.json
210
+ hermes-vault diff --against ~/meta-backup.json
211
+ hermes-vault rotate-master-key
212
+ hermes-vault oauth login google --alias work
213
+ hermes-vault oauth refresh google --alias work
214
+ hermes-vault oauth providers
215
+ ```
216
+
217
+ ## What's New in 0.8.0 - Hermes Vault Console
218
+
219
+ ### Local dashboard
220
+ `hermes-vault dashboard` serves the Hermes Vault Console from packaged assets on `127.0.0.1` with a random launch token. It gives operators one local view for health, inventory, policy findings, audit activity, MCP binding, operations, and recovery posture.
221
+
222
+ ### Safe action boundary
223
+ The console only calls existing safe service-layer workflows: health, policy doctor, verification, OAuth refresh, maintenance, backup verification, and restore dry-run. Raw secret display, encrypted payload display, credential or policy editing, destructive restore, cloud sync, and remote binding stay out of the dashboard.
224
+
225
+ ### Brand and visual QA
226
+ The release includes bundled brand assets for the console experience. Before release, visual QA should check desktop and mobile widths, the first-run vault-door intro, asset loading, text overflow, and control overlap.
227
+
228
+ ## What's New in 0.7.0 - Operational Autonomy
229
+
230
+ ### Maintenance command
231
+ `hermes-vault maintain` is the v0.7.0 operator entry point for scheduled-safe OAuth refresh, health checks, stale-verification checks, and backup-age warnings. `--dry-run` reports what would happen without mutating tokens. `--format json` is available for automation.
232
+
233
+ ### Policy doctor
234
+ `hermes-vault policy doctor` inspects `policy.yaml` for least-privilege drift, unknown services or actions, legacy capability grants, risky `raw_secret_access` settings, stale generated skills, and OAuth readiness gaps. Use `--strict` to fail CI or scheduled checks on high-risk findings.
235
+
236
+ ### OAuth storage normalization
237
+ v0.7.0 adds `hermes-vault oauth normalize` to migrate older OAuth records to sanitized metadata and alias-scoped refresh pairing. Access-token metadata keeps provider-safe fields such as `token_type`, `provider`, `issued_at`, `expires_at`, and `scopes`. Refresh tokens are stored separately under `refresh:<alias>` with the associated access-token alias recorded in metadata.
238
+
239
+ ### MCP agent binding
240
+ `HERMES_VAULT_MCP_ALLOWED_AGENTS` and `HERMES_VAULT_MCP_DEFAULT_AGENT` let operators bind a running MCP server to a known agent set. In bound mode, `agent_id` can be omitted only when the default agent is configured and allowed; otherwise the host must still supply `agent_id`.
241
+
242
+ ### Backup verification and drill
243
+ v0.7.0 adds `hermes-vault backup-verify --input <backup-file>` and a non-mutating restore drill (`hermes-vault restore --dry-run --input <backup-file>`) so operators can prove recovery before they need it. `maintain` can fold backup-age warnings into the same scheduled run.
244
+
245
+ ### Systemd helper output
246
+ `hermes-vault maintain --print-systemd` emits a safe service/timer example for recurring maintenance without forcing the CLI to install units automatically.
247
+
248
+ ## What's New in 0.6.0 — OAuth PKCE and Token Auto-Refresh
249
+
250
+ ### OAuth PKCE login
251
+ `hermes-vault oauth login <provider>` initiates a browser-based PKCE login flow. Tokens are stored in the vault automatically. Supports `--no-browser`, custom `--scope`, and `--alias`. Built-in providers: `google`, `github`, `openai`. Custom providers can be added via YAML.
252
+
253
+ ### Token auto-refresh engine
254
+ `hermes-vault oauth refresh <service>` detects expired or nearly-expired access tokens (default 5-minute proactive margin) and refreshes them using stored refresh tokens. Supports `--all`, `--dry-run`, and configurable `--margin`. Exponential backoff with configurable `max_retries`.
255
+
256
+ ### MCP OAuth tools
257
+ `oauth_login` and `oauth_refresh` are available as MCP tools when Hermes Vault is registered as an MCP server. Agents can initiate logins and trigger refresh without touching raw tokens.
258
+
259
+ ### Provider registry
260
+ OAuth providers are configured in `~/.hermes/hermes-vault-data/oauth-providers.yaml`. The file seeds itself with baked-in defaults on first use. Add custom providers without code changes.
261
+
262
+ ### Security invariants preserved
263
+ No raw tokens in logs. No browser state leaked. CSRF-protected via timing-safe state comparison. Refresh tokens are stored separately from access tokens. Atomic vault updates via SQLite transactions.
264
+
265
+ ## What's New in 0.5.0 — Health, Governance, and Key Rotation
266
+
267
+ ### Vault health command
268
+ `hermes-vault health` runs a read-only check across stale/invalid/expired credentials
269
+ and backup age. Exit codes: 0 = healthy, 1 = warnings found. JSON and markdown output.
270
+
271
+ ### Master-key rotation
272
+ `hermes-vault rotate-master-key` re-encrypts every credential under a new passphrase
273
+ with atomic rollback. Creates an encrypted pre-rotation backup by default.
274
+
275
+ ### Skill sync with policy hashing
276
+ `hermes-vault sync-skill --check` / `--write` / `--print` keeps the
277
+ `hermes-vault-access` SKILL.md in sync with current policy. Generated skills embed
278
+ a SHA-256 policy hash so stale detection is deterministic.
279
+
280
+ ### Metadata-only backup and vault diff
281
+ `hermes-vault backup --metadata-only` exports metadata without encrypted payloads.
282
+ `hermes-vault diff --against <path>` compares current vault against a backup.
283
+
284
+ ### Governance warnings
285
+ Expiry and backup reminders appear in broker `get_ephemeral_env` decision metadata
286
+ under `warnings[]`. Configurable via `HERMES_VAULT_EXPIRY_WARNING_DAYS` and
287
+ `HERMES_VAULT_BACKUP_REMINDER_DAYS`. Never expose raw secrets.
288
+
289
+ ## What's New in 0.4.0 — Credential Observability
290
+
291
+ ### Audit query CLI
292
+ hermes-vault audit with --agent, --service, --action, --decision,
293
+ --since/--until (relative or ISO date), --format table|json, --limit.
294
+
295
+ ### Credential status CLI
296
+ hermes-vault status with --stale Nd, --invalid, --expiring Nd,
297
+ --format table|json. Credentials with no last_verified_at are always stale.
298
+
299
+ ### Expiry metadata commands
300
+ hermes-vault set-expiry (--days N or --date YYYY-MM-DD) and
301
+ hermes-vault clear-expiry. Both write audit entries. Expiry round-trips
302
+ through backup and restore.
303
+
304
+ ### Verification report output
305
+ hermes-vault verify --all now accepts --format table and --report PATH.
306
+ Default JSON-to-stdout behavior is unchanged.
307
+
308
+ ### Security invariants preserved
309
+ No secrets in audit, status, or verification output. No background
310
+ processes. No auto-rotation. No cloud sync.
311
+
312
+ ## What's New in 0.2.0
313
+
314
+ ### Canonical Service IDs
315
+
316
+ All service names are normalized to canonical IDs automatically. `open_ai`, `open-ai` → `openai`; `gmail`, `google_docs` → `google`; `gh` → `github`. See [docs/operator-guide.md](docs/operator-guide.md) for the full alias table.
317
+
318
+ ### Deterministic Credential Selectors
319
+
320
+ Commands that target a credential accept three forms:
321
+
322
+ - **credential ID** (UUID) — always exact
323
+ - **service + `--alias`** — always exact
324
+ - **service only** — works only when exactly one credential exists for that service
325
+
326
+ If you have multiple credentials for the same service (e.g. `github` with aliases `work` and `personal`), the CLI fails with an `Ambiguous` error and asks for `--alias` or the credential ID.
327
+
328
+ Commands that use selectors: `verify`, `rotate`, `delete`, `show-metadata`.
329
+
330
+ ### Policy v2
331
+
332
+ Policy now supports per-service action permissions:
333
+
334
+ ```yaml
335
+ agents:
336
+ dwight:
337
+ services:
338
+ openai:
339
+ actions: [get_credential, get_env, verify, metadata]
340
+ max_ttl_seconds: 900
341
+ github:
342
+ actions: [get_env, verify, metadata]
343
+ max_ttl_seconds: 900
344
+ ```
345
+
346
+ Legacy flat-list format (`services: [openai, github]`) still works and grants all actions.
347
+
348
+ ### Agent Capabilities
349
+
350
+ Non-service-scoped actions are gated by agent-level capabilities:
351
+
352
+ | Capability | Controls |
353
+ |---|---|
354
+ | `list_credentials` | `broker list` |
355
+ | `scan_secrets` | `scan` |
356
+ | `export_backup` | `backup` |
357
+ | `import_credentials` | `import` |
358
+
359
+ If `capabilities` is omitted from an agent's policy, all capabilities are implicitly granted (backward compatible).
360
+
361
+ ### Centralized Mutation Paths
362
+
363
+ All write/destructive operations (add, rotate, delete, metadata) flow through `VaultMutations` — a centralized, policy-checked, audited mutation layer. The operator CLI path skips policy checks but still produces audit entries.
364
+
365
+ ## Configuration
366
+
367
+ ```bash
368
+ export HERMES_VAULT_HOME=~/.hermes/hermes-vault-data
369
+ export HERMES_VAULT_POLICY=~/.hermes/hermes-vault-data/policy.yaml
370
+ export HERMES_VAULT_NO_BANNER=1
371
+ ```
372
+
373
+ If you need a starting policy, copy `policy.example.yaml` into the runtime home and edit the agent allowlists there.
374
+
375
+ ## Notes
376
+
377
+ - The master key is derived at runtime from `HERMES_VAULT_PASSPHRASE`
378
+ - A separate local salt file is stored beside the vault database
379
+ - If the database exists but the salt is missing, Hermes Vault fails closed instead of silently re-keying the vault
380
+ - Generated skills are review artifacts unless you explicitly install them
381
+
382
+ ## More Detail
383
+
384
+ See [docs/architecture.md](docs/architecture.md), [docs/threat-model.md](docs/threat-model.md), [docs/credential-lifecycle.md](docs/credential-lifecycle.md), [docs/operator-guide.md](docs/operator-guide.md), [docs/migration-0.1-to-0.2.md](docs/migration-0.1-to-0.2.md), [docs/migration-0.5-to-0.6.md](docs/migration-0.5-to-0.6.md), [docs/migration-0.6-to-0.7.md](docs/migration-0.6-to-0.7.md), and [docs/update-workflow.md](docs/update-workflow.md).