Menu

#250 feat: add password-gated doberman uninstall command

closed
nobody
2026-08-15
2026-08-05
Anonymous
No

Originally created by: QY-25123

Problem

Today the only removal-related command is doberman uninstall-hooks, which (per
docs/SETUP.md) only removes Doberman's entries from .claude/settings.json — it doesn't touch
.doberman/ (policy, decision DB, fingerprint key, 2FA/password enrollment) or fully disable
Doberman. There's no single command that fully uninstalls Doberman, and — more importantly —
nothing stops a protected agent from fully disabling its own security layer if it can reach a
shell, since removal isn't gated behind any authentication.

Proposal

Add a doberman uninstall command that:

  • Removes Doberman's hook entries (same as uninstall-hooks) and the local .doberman/
    control plane (policy, decision DB, keys) for the target repo/device, per the
    --path/scope conventions the rest of the CLI already uses.
  • Requires the enrolled possession factor before doing anything — the same password
    (doberman password set) or TOTP (doberman 2fa setup) tier already used to gate other
    weakening actions (mode, prefs, enforcement, 2fa, password, revoke per
    docs/SETUP.md's shell-protection section). If neither is enrolled, fail closed: refuse to
    uninstall until one is set, rather than silently allowing an unauthenticated removal.
  • Is added to the same shell-layer-protected verb list as those other auth-mutating verbs, so a
    raw rm -rf .doberman or an unauthenticated doberman uninstall invocation from within an
    agent session is blocked the same way doberman uninstall-hooks already is today — the new
    command must not become a bypass of that existing protection.
  • Prints a clear summary of exactly what will be removed before prompting for the password/TOTP
    code (explainability — no silent scope creep), and exits non-zero without changing anything if
    authentication fails or is declined.

Security considerations

  • Fail closed: any error during auth or removal must abort with nothing partially removed, or at
    minimum leave the system in a clearly-reported state (never a silent partial uninstall).
  • No secrets in output/logs: the confirmation summary lists path classes/what's being removed,
    never raw key material.
  • This is a destructive, hard-to-reverse local action — it should require an explicit
    confirmation step in addition to the password/TOTP check (e.g. type the repo name, or --yes
    for non-interactive use only when the auth factor is also supplied non-interactively).

Suggested tests

  • Uninstall refuses to run with no password/TOTP enrolled.
  • Uninstall refuses to run with a wrong password/TOTP code, and nothing is removed.
  • Successful uninstall removes exactly the expected files/entries and nothing else.
  • A shell command that tries to invoke doberman uninstall or delete .doberman/ directly from
    within a protected agent session is still blocked pre-auth, same as existing control-plane
    tampering protections.

Scope clarification

Added after digging into the actual storage layout while reviewing this: this should be a
project-level command only. It removes the hook entries and this repo's .doberman/ (policy

  • decision DB), scoped by --path like the rest of the CLI — nothing more.

Correcting my own proposal above: password hash, TOTP secret, and the fingerprint key are not
stored inside .doberman/ — they live in a per-user config dir (~/.config/doberman/ or the
Windows equivalent), shared across every repo Doberman protects on that machine. So a
project-scoped uninstall should not touch them by default. Wiping those as a side effect of
removing one project's protection would deauthorize 2FA/password for every other repo on the
same machine — a much bigger blast radius than intended, and out of step with this proposal's own
"no silent scope creep" requirement above. If a full device-level wipe is ever wanted, that
belongs in a separate, distinctly-named command — not this one.

Related

Tickets: #251
Tickets: #372
Tickets: #375
Tickets: #376

Discussion

  • Anonymous

    Anonymous - 2026-08-10

    Originally posted by: fu351

    This is a sharp proposal, and you caught the real gap. uninstall-hooks leaves .doberman/ in place (policy, decision DB, keys, 2FA enrollment), and nothing gates full removal, so a protected agent that reaches a shell could tear down its own security layer. Making the new verb fail closed (refuse when no factor is enrolled) and folding it into the same shell-protected verb list as the other weakening actions is exactly right. That's the detail that stops the command from becoming the bypass it's meant to prevent.

    I tagged it enhancement, help wanted, level-5. It reaches into the auth-gate and control-plane internals, so it's a step up from a starter rather than a first issue. If you want to build toward it, landing a smaller one first is a good on-ramp (#249, which you also filed, is a clean starter). Then this is a great next piece to pick up.

    Thanks for thinking about the self-protection angle, not just the convenience one.

     
  • Anonymous

    Anonymous - 2026-08-15

    Ticket changed by: fu351

    • status: open --> closed
     

Log in to post a comment.