~bigbes/agents-dev · parade

main · last commit 13 days ago · 7g0stsfu

← Back to the parade

ah-xuc.7 httpapi: Vikunja webhook receiver with HMAC verification Past Stand

status: closed P2 feature @Eugene Blikh
bd reopen ah-xuc.7
Created byEugene Blikh
Ownerbigbes@gmail.com
Created2026-07-13T05:15:43Z
Started2026-07-13T05:44:26Z
Updated2026-07-13T06:22:50Z
Closed2026-07-13T06:22:50Z
Description
POST /webhooks/vikunja as a reconciler poke. Design principle 1: a webhook only triggers an immediate iteration; polling stays the source of truth because Vikunja delivers webhooks once, without retries.

Deps gain WebhookSecret string and a Webhook hook (non-blocking; cmd wires it to Reconciler.Poke). Empty secret = feature disabled: the route is not registered at all. Verification: X-Vikunja-Signature carries hex HMAC-SHA256 over the raw request body; compute over the exact bytes read and compare with hmac.Equal; missing or wrong signature = 401 with a terse body that echoes nothing back; cap the body at 256 KiB. After verification decode {event_name} best-effort for the log line only — the payload is otherwise untrusted and unused. Respond 200 fast, call the hook once per verified delivery. Exposing the loopback listener to Vikunja is infra (ah-k23), not this bead.
Acceptance criteria
go test ./internal/httpapi/... green, go vet clean; tests: a valid computed signature pokes the hook and returns 200; tampered body, wrong secret, and missing header return 401 without invoking the hook; oversized body rejected; unset secret leaves the route absent and existing routes unaffected

Depends on

  • ah-xuc — Stage 2: webhooks, Task Spec, full buckets, Telegram, srht push, watchdog parent-child closed
  • ah-xuc.1 — Stage 2 foundation: domain buckets/outcome, ports contracts, config surface blocks closed

Depended on by

  • ah-xuc.10 — cmd/agenthubd: wire webhook secret and Telegram notifier blocks

Unblocks — everything waiting on this, transitively

  • ah-xuc.10 — cmd/agenthubd: wire webhook secret and Telegram notifier blocks closed
  • ah-xuc.11 — e2e: Stage 2 flows — webhook poke, Triage bounce, skills, publish, watchdog, Telegram blocks closed
  • ah-xuc.12 — docs: sync SPEC with Stage 2 behavior blocks closed

No comments.

Close reason

61400ae; HMAC discipline verified (full-read-before-verify, uniform 401, constant-time compare); review clean
  • Eugene Blikh added under epic ah-xuc · 2026-07-13T08:15:43Z
  • Eugene Blikh created the issue · 2026-07-13T08:15:43Z
  • Eugene Blikh added dependency on ah-xuc.1 · 2026-07-13T08:16:50Z
  • Eugene Blikh ah-xuc.10 now depends on this · 2026-07-13T08:16:54Z
  • Eugene Blikh claimed · 2026-07-13T08:44:25Z
  • Eugene Blikh closed the issue · 2026-07-13T09:22:50Z
    61400ae; HMAC discipline verified (full-read-before-verify, uniform 401, constant-time compare); review clean
  • Eugene Blikh added label milestone:stage-2 · 2026-07-20T03:08:47Z
  • Eugene Blikh removed label milestone:stage-2 · 2026-07-20T03:10:25Z
Stored rows — what this pane was built from, as read
issues 1 row
id ah-xuc.7
content_hash 62a6806491ee4096a8206ec5b958064c69d772d7f8376188ca61bbfc8a354510
title httpapi: Vikunja webhook receiver with HMAC verification
description POST /webhooks/vikunja as a reconciler poke. Design principle 1: a webhook only triggers an immediate iteration; polling stays the source of truth because Vikunja delivers webhooks once, without retries. Deps gain WebhookSecret string and a Webhook hook (non-blocking; cmd wires it to Reconciler.Poke). Empty secret = feature disabled: the route is not registered at all. Verification: X-Vikunja-Signature carries hex HMAC-SHA256 over the raw request body; compute over the exact bytes read and compare with hmac.Equal; missing or wrong signature = 401 with a terse body that echoes nothing back; cap the body at 256 KiB. After verification decode {event_name} best-effort for the log line only — the payload is otherwise untrusted and unused. Respond 200 fast, call the hook once per verified delivery. Exposing the loopback listener to Vikunja is infra (ah-k23), not this bead.
design
acceptance_criteria go test ./internal/httpapi/... green, go vet clean; tests: a valid computed signature pokes the hook and returns 200; tampered body, wrong secret, and missing header return 401 without invoking the hook; oversized body rejected; unset secret leaves the route absent and existing routes unaffected
notes
status closed
priority 2
issue_type feature
assignee Eugene Blikh
estimated_minutes NULL
created_at 2026-07-13T05:15:43Z
created_by Eugene Blikh
owner bigbes@gmail.com
updated_at 2026-07-13T06:22:50Z
closed_at 2026-07-13T06:22:50Z
closed_by_session
external_ref NULL
spec_id
compaction_level 0
compacted_at NULL
compacted_at_commit NULL
original_size NULL
sender
ephemeral 0
wisp_type
pinned 0
is_template 0
mol_type
work_type
source_system
metadata �{}
source_repo
close_reason 61400ae; HMAC discipline verified (full-read-before-verify, uniform 401, constant-time compare); review clean
event_kind
actor
target
payload
await_type
await_id
timeout_ns 0
waiters
hook_bead
role_bead
agent_state
last_activity NULL
role_type
rig
due_at NULL
defer_until NULL
no_history 0
started_at 2026-07-13T05:44:26Z
is_blocked 0
dependencies 3 rows
id 2f0edb7d-9d7d-5865-b263-93db7cce7609
issue_id ah-xuc.7
type parent-child
created_at 2026-07-13T08:15:43Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id ah-xuc
depends_on_wisp_id NULL
depends_on_external NULL
id 37f3de87-cff8-5310-896f-877fce7a1f82
issue_id ah-xuc.7
type blocks
created_at 2026-07-13T08:16:50Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id ah-xuc.1
depends_on_wisp_id NULL
depends_on_external NULL
id f115477d-4fe6-54ee-a5a1-fee946cd310f
issue_id ah-xuc.10
type blocks
created_at 2026-07-13T08:16:54Z
created_by Eugene Blikh
metadata �{}
thread_id
depends_on_issue_id ah-xuc.7
depends_on_wisp_id NULL
depends_on_external NULL
events 5 rows
id 019f59e7-11cc-7d71-a6ba-40ba924b8b16
issue_id ah-xuc.7
event_type created
actor Eugene Blikh
old_value
new_value
comment NULL
created_at 2026-07-13T08:15:43Z
id 019f5a01-5987-77cc-a14e-5139a3efbd20
issue_id ah-xuc.7
event_type claimed
actor Eugene Blikh
old_value {"id":"ah-xuc.7","title":"httpapi: Vikunja webhook receiver with HMAC verification","description":"POST /webhooks/vikunja as a reconciler poke. Design principle 1: a webhook only triggers an immediate iteration; polling stays the source of truth because Vikunja delivers webhooks once, without retries.\n\nDeps gain WebhookSecret string and a Webhook hook (non-blocking; cmd wires it to Reconciler.Poke). Empty secret = feature disabled: the route is not registered at all. Verification: X-Vikunja-Signature carries hex HMAC-SHA256 over the raw request body; compute over the exact bytes read and compare with hmac.Equal; missing or wrong signature = 401 with a terse body that echoes nothing back; cap the body at 256 KiB. After verification decode {event_name} best-effort for the log line only — the payload is otherwise untrusted and unused. Respond 200 fast, call the hook once per verified delivery. Exposing the loopback listener to Vikunja is infra (ah-k23), not this bead.","acceptance_criteria":"go test ./internal/httpapi/... green, go vet clean; tests: a valid computed signature pokes the hook and returns 200; tampered body, wrong secret, and missing header return 401 without invoking the hook; oversized body rejected; unset secret leaves the route absent and existing routes unaffected","status":"open","priority":2,"issue_type":"feature","owner":"bigbes@gmail.com","created_at":"2026-07-13T05:15:43Z","created_by":"Eugene Blikh","updated_at":"2026-07-13T05:15:43Z"}
new_value {"assignee":"Eugene Blikh","status":"in_progress"}
comment NULL
created_at 2026-07-13T08:44:25Z
id 019f5a24-8416-7c7b-92f8-00b2136410d2
issue_id ah-xuc.7
event_type closed
actor Eugene Blikh
old_value
new_value 61400ae; HMAC discipline verified (full-read-before-verify, uniform 401, constant-time compare); review clean
comment NULL
created_at 2026-07-13T09:22:50Z
id 019f7cda-9352-75f7-ab35-d0b10fb89516
issue_id ah-xuc.7
event_type label_added
actor Eugene Blikh
old_value NULL
new_value NULL
comment Added label: milestone:stage-2
created_at 2026-07-20T03:08:47Z
id 019f7cdc-1527-74af-816c-d1050ea95c71
issue_id ah-xuc.7
event_type label_removed
actor Eugene Blikh
old_value NULL
new_value NULL
comment Removed label: milestone:stage-2
created_at 2026-07-20T03:10:25Z