Skip to content

fix(#149): sign effort-drift POST + regenerate stale status hooks - #659

Open
bradbrok wants to merge 1 commit into
mainfrom
fix/isolated-hook-signing
Open

fix(#149): sign effort-drift POST + regenerate stale status hooks#659
bradbrok wants to merge 1 commit into
mainfrom
fix/isolated-hook-signing

Conversation

@bradbrok

@bradbrok bradbrok commented Jun 2, 2026

Copy link
Copy Markdown
Owner

Why

Deploying #655 (main) to the POS-Specialists Pi surfaced 401s for the isolated agent ivan on two hook-driven endpoints — POST /agents/ivan/status (6x) and POST /agents/ivan/effort-drift (5x) — that returned 0 on the prior #635 build. Core transport (/transport/*, /heartbeat, inbox, tasks) was unaffected, so this only degraded live-status + effort telemetry, but it's a real regression from the #149 phase-3 isolation tightening (#640 fail-closes the global secret for isolated tenants).

Root cause

Fix

  • _post_drift() now HMAC-signs with PINKY_AGENT_KEY (falling back to PINKY_SESSION_SECRET) and adds x-pinky-timestamp + x-pinky-signature; skips silently when no secret is present.
  • hook_working.py/hook_idle.py now go through _write_hook_if_changed (like the 5 tmux hooks), so ensure_workspace_hooks (runs at streaming-start) regenerates stale hooks with the current per-agent-key template.

Tests

  • effort-drift POST carries an HMAC accepted under allow_global_secret=False (the isolated policy) with the per-agent key; a wrong global secret does not help.
  • no signing secret in env -> hook skips the POST entirely.
  • a stale global-secret-only hook_working.py is rewritten to the per-agent-key template.

Full suite green locally (2701 passed, 1 skipped; nacl tests excluded per local-env gotcha — CI runs them).

Deploy note

Takes effect on an agent's next session start (hook regeneration). The Pi is currently on #655 with this regression live; redeploying this branch + restart will clear ivan's 401s.

Isolated agents (per-agent-key only, global secret rejected per #640) got
401s on two hook-driven endpoints, surfaced deploying #655 to the POS-
Specialists Pi:

- /agents/{name}/effort-drift: hook_verify_effort.py's _post_drift sent NO
  signature (only x-pinky-agent), so verify_internal_request rejected it for
  EVERY agent. Now HMAC-signs (PINKY_AGENT_KEY, falling back to
  PINKY_SESSION_SECRET) over "agent\nPOST\npath\nts" and skips when no secret
  is present (an unsigned request would only 401).

- /agents/{name}/status: hook_working.py/hook_idle.py were written only
  if-missing, so agents created before per-agent-key signing (#623) kept
  stale hooks signing with only the global secret. Route them through
  _write_hook_if_changed so ensure_workspace_hooks regenerates them with the
  current per-agent-key template on the next session start.

Tests: drift POST is signed + verifiable under allow_global_secret=False
(isolated policy); no-secret skips the POST; stale status hook is rewritten.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant