Menu

#281 fix(auth): report challenge timeout distinctly in turn-gate and host-hook logs

closed
nobody
None
2026-08-08
2026-08-06
Anonymous
No

Originally created by: fu351

Slice

  • Feature / Slice: AN-4a (ADR 0046 follow-up) — report a challenge timeout distinctly from a refusal

What this PR does

ADR 0046 gave the AUTH challenge a wall-clock deadline that fails closed: an unanswered
challenge returns non-approved, tagged TIMEOUT_METHOD. But every enforcement site
then collapsed the result to a plain denied, so the audit log and the user's message
could not tell a silent timeout from a deliberate human "no" — exactly the distinction
the deadline exists to record.

This propagates the AuthResult.method to the three sites AN-4a names:

  • turn-gate _enforce (AUTH turns) records auth_result="timeout" with a
    "timed out (auto-denied)" note, distinct from denied;
  • turn-gate _handle_repeat (the TG4 escape hatch) records timeout at the
    turn_repeat_denied stage likewise;
  • host-hook _resolve_auth deny message says the request expired (auto-denied
    after the deadline) instead of the generic "not completed", and keeps the exact
    doberman 2fa setup hint when an un-enrolled 2FA tier is the blocker.

The verdict is unchanged: a timeout still denies (fail closed). This is logging/message
honesty only, not a policy change — raise-only intact.

Tests added (run in CI)

  • tests/integration/test_turn_hook.py: a timed-out AUTH turn records timeout (note +
    persisted auth_result), a refusal still records denied, and a timed-out
    repeat-resubmission records timeout distinctly — all still not released.
  • tests/unit/test_hosthook_auth_challenge.py: a timed-out AUTH denies with the "expired"
    wording, and a timed-out un-enrolled 2FA action still names doberman 2fa setup.
  • The existing 12 deadline-mechanism tests (test_auth_challenge_timeout.py) still pass —
    this change only reads the method those tests already set.

Security checklist

  • [x] Fails closed on error / uncertainty — a timeout still denies, verdict unchanged
  • [x] No secret, full file, or unredacted prompt logged or committed — labels are fixed constants
  • [x] Any guardrail/learning change is raise-only — no policy/verdict change, message + audit label only
  • [x] Every BLOCK/AUTH carries reason codes + a human explanation — the deny message stays actionable
  • [x] Public-release safety: no enterprise refs, no local memory paths

Edge cases covered / Deviations / Risks

  • Refusal vs. timeout are asserted separately so a real "no" is never relabeled timeout.
  • The un-enrolled-2FA hint is preserved in the timeout branch (regression-guarded).
  • No deviations. No new risk — no code path changes its verdict.

Related

Tickets: #296

Discussion

  • Anonymous

    Anonymous - 2026-08-07

    Ticket changed by: fu351

    • status: open --> closed
     
  • Anonymous

    Anonymous - 2026-08-07

    Ticket changed by: fu351

    • status: closed --> open
     
  • Anonymous

    Anonymous - 2026-08-08

    Ticket changed by: fu351

    • status: open --> closed
     

Log in to post a comment.