Eligibility
Stage: using monk.secret.remove to clean up test secrets from the local vault.
Coding agent: Claude Code v0.1.52
Environment: Windows 11 Pro 26200, monk CLI/daemon v3.21.1 (build 0ecb47b4), personal scope, no active cluster.
Summary
monk.secret.remove on a local scope (workspace / global) raises a dashboard approval request, but the MCP call gives up after ~60–90 s while the approval request stays valid for a full 15 minutes. Three separate defects fall out of that mismatch:
- The caller is told the wrong thing. The tool returns
The operation timed out. — it never says an approval is pending. Any reasonable caller concludes the removal failed.
- The destructive request stays armed after the error. When the user approves it minutes later, the secret is deleted — long after the tool reported failure. The deletion is invisible to the caller that requested it.
- The existence check runs after approval, not before. Removing a name that does not exist still raises a
kind: security prompt reading "This cannot be undone", then returns removed: false. Users are asked to authorise irreversible deletions that are guaranteed no-ops.
Because (1) makes retrying the obvious response, an agent naturally issues duplicate destructive prompts for the same secret.
Reproduction (tools only)
1. monk.secret.add { name: "bb-probe-ws", value: "<any>", scope: "workspace" }
-> { ok: true, message: "Secret stored." }
2. monk.secret.list { scope: "workspace" }
-> shows bb-probe-ws
3. monk.secret.remove { name: "bb-probe-ws", scope: "workspace" }
... do NOT touch the dashboard ...
-> ERROR: "The operation timed out." (after ~60-90 s)
4. monk.secret.list { scope: "workspace" }
-> bb-probe-ws is STILL PRESENT
5. Now approve the still-pending prompt in the dashboard.
6. monk.secret.list { scope: "workspace" }
-> bb-probe-ws is GONE
Step 3 reported failure. Step 6 shows the deletion happened anyway. Nothing ever told the caller.
Defect 3, standalone:
monk.secret.remove { name: "BB-COLLIDE", scope: "workspace" }
BB-COLLIDE does not exist (the vault is case-sensitive; only bb-collide exists). A kind: security approval titled Remove Secret "BB-COLLIDE" is raised anyway, with body "Delete the local secret BB-COLLIDE (workspace scope) from this machine's vault. This cannot be undone." After approval the call returns removed: false and no delete is written to the audit log.
Cross-verification (3 independent sources)
1 — MCP tool output
monk.secret.remove returned The operation timed out. for bb-collide (twice) and bb-probe-ws (once). monk.secret.list { scope: "all" } after those errors still listed both secrets.
2 — Approval store, ~/.monk/agent/store/global/requests/approvals.json
2d48a40c | Remove Secret "BB-COLLIDE"
created 2026-08-05T19:52:30.771Z
expires 2026-08-05T20:07:30.771Z <- created + 15m00s
resolved 2026-08-05T19:52:39.338Z approved
a89c2aa9 | Remove Secret "bb-collide"
created 2026-08-05T19:53:04.997Z
expires 2026-08-05T20:08:04.997Z
resolved 2026-08-05T19:58:36.784Z approved
f1a43ca8 | Remove Secret "bb-collide" <- duplicate, same secret
created 2026-08-05T19:54:34.534Z
expires 2026-08-05T20:09:34.534Z
resolved 2026-08-05T19:58:36.422Z approved
2169456e | Remove Secret "bb-probe-ws"
created 2026-08-05T19:55:44.032Z
expires 2026-08-05T20:10:44.032Z
resolved 2026-08-05T19:58:35.981Z approved
Every request carries expiresAt = createdAt + 15m, yet each originating MCP call had already errored out roughly a minute in. All four requests sat status: "pending" and fully actionable after their callers were told the operation had timed out.
3 — Secret audit log, ~/.monk/agent/store/audit/secret-access.json
2026-08-05T19:51:08.448Z write workspace 8db828a6 (bb-probe-ws created)
2026-08-05T19:51:30.988Z write workspace 91765335 (bb-collide created)
2026-08-05T19:58:36.354Z delete workspace 8db828a6 (bb-probe-ws deleted)
2026-08-05T19:58:36.801Z delete workspace 91765335 (bb-collide deleted)
The deletions land at 19:58:36 — about three minutes after the calls that requested them returned The operation timed out.
No audit entry exists for BB-COLLIDE, confirming its approved kind: security prompt authorised nothing.
4 — Vault index, ~/.monk/agent/store/global/credentials/index%…cGVyc29uYWw.json
Before approval: bb-probe-ws, bb-collide, BB-Case-Probe, bb-case-probe.
After approval: BB-Case-Probe, bb-case-probe.
Both secrets are gone from the persisted index, confirming the deferred deletions were real and durable.
bb-collide in the global scope survived throughout — scope targeting itself is correct and is not part of this report.
Root cause
The approval request TTL (15 min, visible as expiresAt in approvals.json) is set independently of, and far longer than, the window the MCP call is willing to block for (~60–90 s observed). When the call gives up, nothing cancels or invalidates the request it created, and the error surfaced to the caller does not distinguish "no decision yet" from "failed".
Separately, secret.remove resolves the approval before it looks the secret up in the vault, so name existence has no bearing on whether a destructive prompt is shown.
Expected vs actual
|
Expected |
Actual |
| Call abandoned while approval pending |
Error names the pending approval, or the call keeps waiting until expiresAt |
The operation timed out. — no mention of an approval |
| Request after the call errors |
Cancelled/invalidated with the call that owns it |
Stays pending and fully actionable for the rest of the 15 min |
| Approval granted after the caller saw an error |
No deletion, or the caller is notified |
Secret is silently deleted ~3 min after "failure" was reported |
| Removing a name that does not exist |
removed: false immediately, no prompt |
kind: security "This cannot be undone" prompt, then removed: false |
| Retry after a reported failure |
Reuses or replaces the pending request |
Creates a second identical destructive prompt for the same secret |
Impact
Broken lifecycle / data-loss. A caller told the operation failed has no way to know the secret was later destroyed. Recovery logic keyed on that error — re-adding the secret, aborting a migration, falling back to a different name — runs against state that silently flips underneath it. Local vault secrets have no undo.
Security-approval integrity. These are kind: security prompts. Two failure modes degrade them at once: identical duplicates for one secret (retry is the natural response to a reported timeout), and prompts for deletions that cannot delete anything. Both train users to approve destructive security prompts without reading them — and here the user genuinely cannot tell the redundant prompt from the one that will destroy data.
Reached through ordinary cleanup of local secrets on a single machine; no cluster, no org, no special configuration.
Dedup check
gh search issues -R monk-io/monk-plugin over approval, secret, secret remove, nonexistent, no-op, vault.
Closest existing issues, all distinct:
None covers an approval outliving its MCP call and executing a destructive local-vault deletion after the caller was told it timed out.
Payout
N/A.
Eligibility
Stage: using
monk.secret.removeto clean up test secrets from the local vault.Coding agent: Claude Code v0.1.52
Environment: Windows 11 Pro 26200, monk CLI/daemon v3.21.1 (build 0ecb47b4), personal scope, no active cluster.
Summary
monk.secret.removeon a local scope (workspace/global) raises a dashboard approval request, but the MCP call gives up after ~60–90 s while the approval request stays valid for a full 15 minutes. Three separate defects fall out of that mismatch:The operation timed out.— it never says an approval is pending. Any reasonable caller concludes the removal failed.kind: securityprompt reading "This cannot be undone", then returnsremoved: false. Users are asked to authorise irreversible deletions that are guaranteed no-ops.Because (1) makes retrying the obvious response, an agent naturally issues duplicate destructive prompts for the same secret.
Reproduction (tools only)
Step 3 reported failure. Step 6 shows the deletion happened anyway. Nothing ever told the caller.
Defect 3, standalone:
BB-COLLIDEdoes not exist (the vault is case-sensitive; onlybb-collideexists). Akind: securityapproval titledRemove Secret "BB-COLLIDE"is raised anyway, with body "Delete the local secret BB-COLLIDE (workspace scope) from this machine's vault. This cannot be undone." After approval the call returnsremoved: falseand no delete is written to the audit log.Cross-verification (3 independent sources)
1 — MCP tool output
monk.secret.removereturnedThe operation timed out.forbb-collide(twice) andbb-probe-ws(once).monk.secret.list { scope: "all" }after those errors still listed both secrets.2 — Approval store,
~/.monk/agent/store/global/requests/approvals.jsonEvery request carries
expiresAt = createdAt + 15m, yet each originating MCP call had already errored out roughly a minute in. All four requests satstatus: "pending"and fully actionable after their callers were told the operation had timed out.3 — Secret audit log,
~/.monk/agent/store/audit/secret-access.jsonThe deletions land at 19:58:36 — about three minutes after the calls that requested them returned
The operation timed out.No audit entry exists for
BB-COLLIDE, confirming its approvedkind: securityprompt authorised nothing.4 — Vault index,
~/.monk/agent/store/global/credentials/index%…cGVyc29uYWw.jsonBefore approval:
bb-probe-ws,bb-collide,BB-Case-Probe,bb-case-probe.After approval:
BB-Case-Probe,bb-case-probe.Both secrets are gone from the persisted index, confirming the deferred deletions were real and durable.
bb-collidein the global scope survived throughout — scope targeting itself is correct and is not part of this report.Root cause
The approval request TTL (15 min, visible as
expiresAtinapprovals.json) is set independently of, and far longer than, the window the MCP call is willing to block for (~60–90 s observed). When the call gives up, nothing cancels or invalidates the request it created, and the error surfaced to the caller does not distinguish "no decision yet" from "failed".Separately,
secret.removeresolves the approval before it looks the secret up in the vault, so name existence has no bearing on whether a destructive prompt is shown.Expected vs actual
expiresAtThe operation timed out.— no mention of an approvalpendingand fully actionable for the rest of the 15 minremoved: falseimmediately, no promptkind: security"This cannot be undone" prompt, thenremoved: falseImpact
Broken lifecycle / data-loss. A caller told the operation failed has no way to know the secret was later destroyed. Recovery logic keyed on that error — re-adding the secret, aborting a migration, falling back to a different name — runs against state that silently flips underneath it. Local vault secrets have no undo.
Security-approval integrity. These are
kind: securityprompts. Two failure modes degrade them at once: identical duplicates for one secret (retry is the natural response to a reported timeout), and prompts for deletions that cannot delete anything. Both train users to approve destructive security prompts without reading them — and here the user genuinely cannot tell the redundant prompt from the one that will destroy data.Reached through ordinary cleanup of local secrets on a single machine; no cluster, no org, no special configuration.
Dedup check
gh search issues -R monk-io/monk-pluginoverapproval,secret,secret remove,nonexistent,no-op,vault.Closest existing issues, all distinct:
workspaceRoot(my own; storage keying, not approvals)monk.secret.list(all)labels organization secrets as account-scoped #170 —secret.list(all)mislabels/drops cluster-scope secrets (listing, not removal)None covers an approval outliving its MCP call and executing a destructive local-vault deletion after the caller was told it timed out.
Payout
N/A.