Aller au contenu
login
arrow_backRetour aux issues
fu351/Doberman-Core #399

[bug]: AUTH-tier decisions execute without human confirmation in the Claude Code host-hook path (fail-closed violation)

ecoDébutant bug help wanted level-5

descriptionDescription

## What happened? `AUTH`-tier decisions produced by the **Claude Code host-hook** integration (`doberman hook pre`, `src/doberman/hosthooks/claude_code.py`) appear to resolve as *approved* without any human ever answering a confirmation channel: no GUI dialog, no terminal prompt, no `doberman dash` pending-approval entry. The gated tool call (e.g. a `Write` to a path matched by `DEFAULT_SENSITIVE_GLOBS`, reason code `sensitive_path_access`, tier `local_auth`) simply executes immediately, and the decision log records `AUTH ... auth=executed`. Expected: a `local_auth`-tier `AUTH` should block the tool call until `run_auth_challenge()` gets a real answer from `GuiPrompter`/`TtyPrompter` (`src/doberman/auth/challenge.py`, `src/doberman/auth/gui_prompter.py`, `src/doberman/auth/tty_prompter.py`), and every channel in that chain is written to **fail closed** (raise/deny) when it can't reach a human -- never to silently approve. Got: the tool call always proceeds, with zero observable pause, regardless of `doberman enforcement` state. ### Confirmed NOT the cause - **`enforcement` dial**: reproduced identically under `monitor` and under `enforce` (`doberman enforcement` confirmed `enforce` was active for the later repros). `acted_verdict()`'s monitor-softening (`src/doberman/policy/drift.py`, function `acted_verdict`) only applies to `_DISCRETIONARY_SOFT` codes under `monitor`/`off` -- it does not apply under `enforce`, yet the behavior is the same. - **Stale/uncommitted code**: `git status` clean, local `main` HEAD matches both `origin/main` and `upstream/main` exactly (`git diff upstream/main` empty). This is current `main`, not a stale branch. - **A rogue auth-provider plugin**: `pip list` shows only `doberman-core` installed (editable, pointing at this exact checkout); its `entry_points.txt` registers only the `doberman` console script, no `doberman.auth_providers` entry point. `discover_auth_providers()` (`src/doberman/engine/registry.py`) therefore returns `[]` and `active_provider()` (`src/doberman/auth/provider.py`) falls through to the built-in `LOCAL_PROVIDER`, not a third-party stub. - **Not a total hook bypass**: `BLOCK` verdicts on the same integration path are enforced correctly and consistently -- e.g. writing to `.env`/`.env.*` (`protected_path_blocked`, on `DEFAULT_BLOCKED_GLOBS`) is hard-blocked every single time, both in this session and throughout the historical decision log. So the hook itself, and the objective-floor BLOCK path, are working; the bug is specifically scoped to the `AUTH` challenge-resolution path. ### Historical evidence this isn't a one-off `doberman log` across the full local history (2026-07-14 through today) shows 21 `AUTH` decisions, 20 of which resolved `auth=executed` (the remaining 2 lines, both `git_op`, are missing the `auth=` suffix entirely and may be a separate, unrelated logging gap). Zero ever resolved to a denial or a timeout, across multiple independent sessions/days and multiple reason codes (`sensitive_path_access`, `environment_dump_command`, `possible_high_entropy_secret`, `egress_requires_auth`). That consistency across days argues against a transient fluke (e.g. a display server hiccup) and for something structural in how the challenge resolves in this integration. ## Steps to reproduce 1. Install the Claude Code host hook (`doberman install-hooks` or equivalent), confirm `doberman enforcement` reports `enforce`. 2. From inside a Claude-Code-hooked session, write a file under a `DEFAULT_SENSITIVE_GLOBS` path, e.g. `migrations/anything.sql` (any content). This should classify `file_write` -> `sensitive_path_access` -> `local_auth` tier. 3. Observe: the write succeeds immediately, no dialog appears anywhere on screen, no terminal prompt appears, `doberman dash`'s pending-approval queue (if running) never shows an entry for it. 4. Check `doberman log --last 5` / `doberman status`: the decision is recorded as `AUTH ... auth=executed`. (Note: `dober
codeOuvre sur GitHub