DELETE /api/me/credentials/:upstreamId/:field removes only the SQLite ref row; the secret itself (gw-user-<principalSlug>-<upstreamId>-<field>) stays in the store forever. Re-registering overwrites it (deterministic name), so this is hygiene, not a correctness bug — but orphaned personal credentials accumulating in the platform vault is exactly the kind of residue the self-service flow was meant to avoid.
Scope
- On credential delete, also delete the secret from the configured store (
SecretStore gets a delete(path/name) method: Key Vault beginDeleteSecret, OpenBao KV v2 metadata delete, memory store for tests).
- Deletion failures should not block removing the ref (log + proceed) — the ref row is the source of truth for what the gateway will use.
- Ops prerequisite (NDR): the gateway MI on
ndr-mspstack-kv currently has secrets get/list/set (set added 2026-07-17 for registration); add delete when this ships.
- Consider the same for upstream removal: per-user secrets for a deleted upstream are also orphaned (
gw-user-*-<upstreamId>-* sweep needs a list-by-prefix, KV supports it).
🤖 Generated with Claude Code
DELETE /api/me/credentials/:upstreamId/:fieldremoves only the SQLite ref row; the secret itself (gw-user-<principalSlug>-<upstreamId>-<field>) stays in the store forever. Re-registering overwrites it (deterministic name), so this is hygiene, not a correctness bug — but orphaned personal credentials accumulating in the platform vault is exactly the kind of residue the self-service flow was meant to avoid.Scope
SecretStoregets adelete(path/name)method: Key VaultbeginDeleteSecret, OpenBao KV v2 metadata delete, memory store for tests).ndr-mspstack-kvcurrently has secretsget/list/set(set added 2026-07-17 for registration); adddeletewhen this ships.gw-user-*-<upstreamId>-*sweep needs a list-by-prefix, KV supports it).🤖 Generated with Claude Code