Provision the E2E memory secret into the local vault
`nap gateway vault setup` unwraps the project memory secret once (prompt on a terminal, or the existing argument/env paths) and stores the secret, never the passphrase, in memory-secrets.vault.json under the existing 0600 local vault key. The CLI and MCP workers load it automatically and MCP never prompts, per /decisions/local-gateway-no-interactive-unlock and /decisions/2026-09-29-memory-secret-local-vault. Older versions stay readable; a rotated active version reports memory_secret_rotated with the setup next action. `vault forget` revokes local access, including for running workers. Env passphrases still work, are persisted into the vault, and are reported as deprecated. Search warns e2e_index_not_provisioned instead of e2e_index_locked. Local key creation is 0600 from the start and never replaces a published key. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
611a4571f3
commit
eed1d1d3f2
@@ -1042,8 +1042,12 @@ def print_gateway_help(topic=None):
|
||||
nap gateway schedule delete [ID | --schedule ID]""")
|
||||
return 0
|
||||
if topic == "vault":
|
||||
print("Usage: nap gateway vault [status|process|rotate-secret] [--kind memory] [--all] [--project-id ID] [--vault-passphrase TEXT]")
|
||||
print(" status Show local gateway state and pending setup requests.")
|
||||
print("Usage: nap gateway vault [status|setup|forget|process|rotate-secret] [--kind memory] [--all] [--project-id ID] [--vault-passphrase TEXT]")
|
||||
print(" status Show local gateway state, memory secret provisioning, and pending setup requests.")
|
||||
print(" setup Store the project memory secret in local encrypted storage for this worktree.")
|
||||
print(" Prompts once for the project vault passphrase; the passphrase is never stored.")
|
||||
print(" The CLI and MCP workers then load the secret automatically.")
|
||||
print(" forget Remove the locally stored memory secret for this worktree.")
|
||||
print(" process Upload opaque client-wrapped key bundle records for backend-owned HashiCorp storage.")
|
||||
print(" rotate-secret Rotate the memory project secret from the gateway worker path.")
|
||||
return 0
|
||||
@@ -1054,6 +1058,7 @@ def print_gateway_help(topic=None):
|
||||
print(" nap gateway repair Create dedicated gateway worker credentials.")
|
||||
print(" nap gateway terminal help Show terminal lifecycle commands.")
|
||||
print(" nap gateway schedule help Show schedule lifecycle commands.")
|
||||
print(" nap gateway vault setup Store the E2E memory secret locally (prompts once).")
|
||||
print(" nap gateway vault help Show vault commands.")
|
||||
return 0
|
||||
|
||||
@@ -1308,6 +1313,10 @@ def mcp_runtime_probe(timeout_seconds=6):
|
||||
"verified": False,
|
||||
},
|
||||
"remote_project_access": "not_tested",
|
||||
"memory_secret": (local_payload or {}).get("memory_secret"),
|
||||
"deprecations": [
|
||||
item.get("code") for item in (local_payload or {}).get("deprecations") or [] if isinstance(item, dict)
|
||||
],
|
||||
}
|
||||
except Exception as exc:
|
||||
return {
|
||||
@@ -1417,6 +1426,18 @@ def doctor_status():
|
||||
else "inspect the failed_stage field and local project binding"
|
||||
),
|
||||
})
|
||||
if probe.get("memory_secret") == "rotated":
|
||||
setup.append({
|
||||
"code": "memory_secret_rotated",
|
||||
"message": "the project memory secret was rotated after it was stored locally",
|
||||
"next": "nap gateway vault setup",
|
||||
})
|
||||
if "vault_passphrase_env_deprecated" in (probe.get("deprecations") or []):
|
||||
setup.append({
|
||||
"code": "vault_passphrase_env_deprecated",
|
||||
"message": "NAPSEER_VAULT_PASSPHRASE / NAPSEER_MASTER_PASSPHRASE are deprecated for agents; store the memory secret locally instead",
|
||||
"next": "nap gateway vault setup",
|
||||
})
|
||||
status = "repair_required" if issues else ("setup_available" if setup else "ok")
|
||||
return {
|
||||
"status": status,
|
||||
|
||||
Reference in New Issue
Block a user