fix: sign template Follow target resolution #317

Merged
erik merged 1 commit from fix/task-6e0ed12f-signed-follow-resolution into main 2026-11-04 11:08:30 -06:00
Owner

Summary

Port the website's signed outbound Follow target resolution to the SlugKit template without replacing its constrained fetch wrapper or changing the existing compatible signature identity.

Task

  • task-6e0ed12f — Port signed follow resolution to the SlugKit template.
  • Website prerequisite: task-b5f8d008, completed in erik/erikvancraddock.com PR #25 (implementation c394f999aa43cccaeab429576ecfb6e5c2932e55, merge 185a498).

Changes

  • Lazily select the configured primary actor and existing persisted keys; reuse the site-local acct: sender and Fedify signRequest for initial, canonical and stored-profile-alias actor GETs. WebFinger remains unsigned. No resolution-time key generation/rotation or unsigned fallback.
  • Preserve HTTPS/private-host, credential omission/rejection, five-second abort through body reading, existing response-size bound and redirect rejection. Sanitize retrieval diagnostics to kind/hostname/status or a generic reason.
  • Add intercepted cryptographic and failure-path tests for URLs/handles/aliases, signing material, remote rejection, no persistence/queueing on failure, URL credentials, redirect policy, timeout and size.
  • Document template adoption and the helper boundary: Fedify already supplies signing; package sender derives #multikey-1 and is not substituted. src/federation/loaders.ts stays unchanged. No package/dependency/contract version change or release is required.
  • With explicit additional user approval, fix the pre-existing Makefile dotenv-port fallback by evaluating before export, and fix the existing Follow/Undo fixture's unmocked outgoing Accept/retry loop. The fixture verifies outgoing Accept signatures, blocks unexpected network access, consumes ready work once and does not execute scheduled retries. No production Undo or timeout change.

Testing

  • Focused signed-follow/alias suites: 77 passing tests; Follow/Undo fixture suite: 18 passing tests (all six newer-Follow Undo cases included).
  • ./scripts/pre-pr.sh: passed build/API artifact validation, generated CSS, formatting, lint, types and all 1,539 workspace tests.
  • Local npm run test:ci: 1,343 tests passed; integration tests remain excluded in workflows. Hosted CI run 577 (build-lint-test) succeeded for head 0fbf1967d6616a6ca1367852263876127eae86a1.
  • Started actual local dev services using make dev. App and Garage are running at http://localhost:3000; homepage, /health and /api/v1/health return 200. CLI config generated to a temporary destination matches port 3000. CSS watcher paused during verification to avoid generated-output races.
  • git diff --check passes. Dependencies, package versions and lockfile unchanged.

Verification history: earlier checks exposed the independently reproduced dotenv-port bug and six Undo fixture timeouts; both are addressed under the user's explicit approval. One subsequent full run timed out in the unchanged signed-Accept response test; that six-test suite passed in isolation, and a fresh complete pre-PR run passed. No timeout was increased or failing test excluded.

Safety and limits

No real accounts, live social-server Follow submissions, publishing, deployment or production mutations were used. Tests use generated actors/keys and intercepted fixtures. Pending persistence and one queued Follow are not evidence of remote acceptance. The existing hostname/literal policy is not complete DNS-rebinding protection; response-size enforcement remains a post-read character limit, not a streaming byte bound.

Checklist

  • ./scripts/pre-pr.sh passes
  • Documentation updated
  • Additional baseline fixes explicitly approved; no other scope added
  • Hosted CI green — run 577 for head 0fbf1967
  • Independent read-only review complete — PASS, no actionable findings; supplied checks not independently rerun
  • Explicit human merge approval received; merged as b4b01c2. Post-merge main CI run 578 also succeeded.
## Summary Port the website's signed outbound Follow target resolution to the SlugKit template without replacing its constrained fetch wrapper or changing the existing compatible signature identity. ## Task - `task-6e0ed12f` — Port signed follow resolution to the SlugKit template. - Website prerequisite: `task-b5f8d008`, completed in erik/erikvancraddock.com PR #25 (implementation `c394f999aa43cccaeab429576ecfb6e5c2932e55`, merge `185a498`). ## Changes - Lazily select the configured primary actor and existing persisted keys; reuse the site-local `acct:` sender and Fedify `signRequest` for initial, canonical and stored-profile-alias actor GETs. WebFinger remains unsigned. No resolution-time key generation/rotation or unsigned fallback. - Preserve HTTPS/private-host, credential omission/rejection, five-second abort through body reading, existing response-size bound and redirect rejection. Sanitize retrieval diagnostics to kind/hostname/status or a generic reason. - Add intercepted cryptographic and failure-path tests for URLs/handles/aliases, signing material, remote rejection, no persistence/queueing on failure, URL credentials, redirect policy, timeout and size. - Document template adoption and the helper boundary: Fedify already supplies signing; package sender derives `#multikey-1` and is not substituted. `src/federation/loaders.ts` stays unchanged. No package/dependency/contract version change or release is required. - With explicit additional user approval, fix the pre-existing Makefile dotenv-port fallback by evaluating before export, and fix the existing Follow/Undo fixture's unmocked outgoing Accept/retry loop. The fixture verifies outgoing Accept signatures, blocks unexpected network access, consumes ready work once and does not execute scheduled retries. No production Undo or timeout change. ## Testing - [x] Focused signed-follow/alias suites: 77 passing tests; Follow/Undo fixture suite: 18 passing tests (all six newer-Follow Undo cases included). - [x] `./scripts/pre-pr.sh`: passed build/API artifact validation, generated CSS, formatting, lint, types and all 1,539 workspace tests. - [x] Local `npm run test:ci`: 1,343 tests passed; integration tests remain excluded in workflows. Hosted CI run 577 (`build-lint-test`) succeeded for head `0fbf1967d6616a6ca1367852263876127eae86a1`. - [x] Started actual local dev services using `make dev`. App and Garage are running at `http://localhost:3000`; homepage, `/health` and `/api/v1/health` return 200. CLI config generated to a temporary destination matches port 3000. CSS watcher paused during verification to avoid generated-output races. - [x] `git diff --check` passes. Dependencies, package versions and lockfile unchanged. Verification history: earlier checks exposed the independently reproduced dotenv-port bug and six Undo fixture timeouts; both are addressed under the user's explicit approval. One subsequent full run timed out in the unchanged signed-Accept response test; that six-test suite passed in isolation, and a fresh complete pre-PR run passed. No timeout was increased or failing test excluded. ## Safety and limits No real accounts, live social-server Follow submissions, publishing, deployment or production mutations were used. Tests use generated actors/keys and intercepted fixtures. Pending persistence and one queued Follow are not evidence of remote acceptance. The existing hostname/literal policy is not complete DNS-rebinding protection; response-size enforcement remains a post-read character limit, not a streaming byte bound. ## Checklist - [x] `./scripts/pre-pr.sh` passes - [x] Documentation updated - [x] Additional baseline fixes explicitly approved; no other scope added - [x] Hosted CI green — run 577 for head `0fbf1967` - [x] Independent read-only review complete — PASS, no actionable findings; supplied checks not independently rerun - [x] Explicit human merge approval received; merged as `b4b01c2`. Post-merge main CI run 578 also succeeded.
fix: sign template Follow target resolution
All checks were successful
CI / build-lint-test (pull_request) Successful in 1m39s
0fbf1967d6
Task: #task-6e0ed12f
Author
Owner

Independent review and pipeline state

Reviewed head: 0fbf1967d6616a6ca1367852263876127eae86a1.

No actionable correctness, security, or regression findings at head 0fbf1967.

Acceptance criteria are satisfied by the code and supplied evidence:

  • Signed retrieval: API wiring uses the configured primary actor’s persisted keys and existing acct: identity; no key generation or rotation (template/site/src/api/routes/following.ts:109, template/site/src/federation/keys.ts:59).
  • Canonical/alias paths and safety: signer propagation covers all actor GETs; WebFinger remains unsigned. Constrained fetching, redaction, no unsigned retry, and resolution-before-persistence ordering are preserved (template/site/src/following/following.ts:118,350,417,486).
  • Tests: fixtures cryptographically verify signatures and cover failure/no-write/no-queue behavior. The Follow/Undo fixture blocks unexpected requests and rejects outbox retries rather than silently hiding delivery failures.
  • Helper boundary: loaders.ts remains compatible and unchanged; package documentation correctly explains why template-local wiring is sufficient.
  • Delivery evidence: documentation links the website prerequisite and explains adoption and operational limits. Supplied verification reports all 1,539 local tests passing and hosted CI run 577 successful for this head.

Verification limits: static, read-only review; no checks rerun or CI independently queried. No network, account, deployment, or merge actions performed. Existing hostname-only checks and post-read character limits remain documented limitations, not complete SSRF/resource protection.

Review result: PASS — no blockers found; not merge authorization.
Next: Await separate explicit human merge approval.

Pipeline evidence: complete local ./scripts/pre-pr.sh passed with 1,539 tests; hosted CI run 577 succeeded for this head. No real accounts, live social-server Follow submission, release, deployment or merge. Human merge approval is still required.

## Independent review and pipeline state Reviewed head: `0fbf1967d6616a6ca1367852263876127eae86a1`. No actionable correctness, security, or regression findings at head `0fbf1967`. Acceptance criteria are satisfied by the code and supplied evidence: - **Signed retrieval:** API wiring uses the configured primary actor’s persisted keys and existing `acct:` identity; no key generation or rotation (`template/site/src/api/routes/following.ts:109`, `template/site/src/federation/keys.ts:59`). - **Canonical/alias paths and safety:** signer propagation covers all actor GETs; WebFinger remains unsigned. Constrained fetching, redaction, no unsigned retry, and resolution-before-persistence ordering are preserved (`template/site/src/following/following.ts:118,350,417,486`). - **Tests:** fixtures cryptographically verify signatures and cover failure/no-write/no-queue behavior. The Follow/Undo fixture blocks unexpected requests and rejects outbox retries rather than silently hiding delivery failures. - **Helper boundary:** `loaders.ts` remains compatible and unchanged; package documentation correctly explains why template-local wiring is sufficient. - **Delivery evidence:** documentation links the website prerequisite and explains adoption and operational limits. Supplied verification reports all 1,539 local tests passing and hosted CI run **577 successful** for this head. Verification limits: static, read-only review; no checks rerun or CI independently queried. No network, account, deployment, or merge actions performed. Existing hostname-only checks and post-read character limits remain documented limitations, not complete SSRF/resource protection. **Review result: PASS — no blockers found; not merge authorization.** **Next:** Await separate explicit human merge approval. Pipeline evidence: complete local `./scripts/pre-pr.sh` passed with 1,539 tests; hosted [CI run 577](https://forge.caradoc.com/erik/slugkit/actions/runs/577/jobs/0) succeeded for this head. No real accounts, live social-server Follow submission, release, deployment or merge. Human merge approval is still required.
erik merged commit b4b01c2d3c into main 2026-11-04 11:08:30 -06:00
erik deleted branch fix/task-6e0ed12f-signed-follow-resolution 2026-11-04 11:08:30 -06:00
Sign in to join this conversation.
No reviewers
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
erik/slugkit!317
No description provided.