F5-rotate — Operator-initiated + scheduled webhook secret rotation #487

Closed
opened 2026-04-27 21:43:37 +00:00 by claude-desktop · 0 comments
Collaborator

As an operator, I want a one-click "rotate" on any watched repo plus an optional scheduled auto-rotation, so that I can switch from a shared-file secret to a per-repo one and keep secrets fresh on a cadence.

Acceptance criteria

  • POST /watched-repos/{owner}/{name}/rotate-secret: generates a new 32-byte secret, calls editWebhook on the row's forge_type, updates the row. Updates updated_at.

  • Web app shows "Rotate" on every watched-repo row; migrated rows (webhook_id IS NULL) get a red dot + tooltip ("Migrated row — rotate to take ownership of the webhook").

  • agents.json config block:

    "webhook_secret_rotation": {
      "enabled": false,
      "interval_days": 90
    }
    

    Default disabled. When enabled, hourly background tick rotates every row whose webhook_id IS NOT NULL and updated_at older than interval_days. Cannot auto-rotate migrated rows (operator does those manually).

  • Auto-rotation log line: [rotate] forge=<t> repo=<o/n> reason=auto age_days=<n>. Failures retry on next tick.

  • Boot validation: interval_days >= 7 (refuse silly values).

Out of scope

  • Forcing rotation across all forges on a key-encryption rotation (separate manual procedure).

References

  • Spec: docs/specs/forge-auth-repo-selection.md §F5-rotate, §10

Dependencies

  • Blocked by F5 (watch/unwatch + webhook lifecycle)
As an operator, I want a one-click "rotate" on any watched repo plus an optional scheduled auto-rotation, so that I can switch from a shared-file secret to a per-repo one and keep secrets fresh on a cadence. ## Acceptance criteria - [ ] `POST /watched-repos/{owner}/{name}/rotate-secret`: generates a new 32-byte secret, calls `editWebhook` on the row's `forge_type`, updates the row. Updates `updated_at`. - [ ] Web app shows "Rotate" on every watched-repo row; migrated rows (`webhook_id IS NULL`) get a red dot + tooltip ("Migrated row — rotate to take ownership of the webhook"). - [ ] `agents.json` config block: ```json "webhook_secret_rotation": { "enabled": false, "interval_days": 90 } ``` Default disabled. When enabled, hourly background tick rotates every row whose `webhook_id IS NOT NULL` and `updated_at` older than `interval_days`. Cannot auto-rotate migrated rows (operator does those manually). - [ ] Auto-rotation log line: `[rotate] forge=<t> repo=<o/n> reason=auto age_days=<n>`. Failures retry on next tick. - [ ] Boot validation: `interval_days >= 7` (refuse silly values). ## Out of scope - Forcing rotation across all forges on a key-encryption rotation (separate manual procedure). ## References - Spec: `docs/specs/forge-auth-repo-selection.md` §F5-rotate, §10 ## Dependencies - Blocked by F5 (watch/unwatch + webhook lifecycle)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
charles/claude-hooks#487
No description provided.