Files
red/.planning/phases/07-audit-trail-and-download/07-01-SUMMARY.md
Chandler Copeland 36069cb1ef docs(07-01): complete agent download token and route plan
- 07-01-SUMMARY.md: execution summary with decisions and file references
- STATE.md: position updated to Phase 7 Plan 1 complete; two decisions logged
- ROADMAP.md: Phase 7 progress updated (1/3 plans complete)
- REQUIREMENTS.md: SIGN-07 and LEGAL-03 marked complete
2026-03-21 10:36:19 -06:00

4.8 KiB

phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
phase plan subsystem tags requires provides affects tech-stack key-files key-decisions patterns-established requirements-completed duration completed
07-audit-trail-and-download 01 api
jwt
jose
pdf
download
security
next.js
phase provides
06-signing-flow token.ts with createDownloadToken/verifyDownloadToken pattern and SIGNING_JWT_SECRET
phase provides
04-pdf-ingest uploads/ directory and path traversal guard pattern
createAgentDownloadToken (purpose:'agent-download', 5-min TTL) in src/lib/signing/token.ts
verifyAgentDownloadToken in src/lib/signing/token.ts
GET /api/documents/[id]/download?adt=[token] — agent-authenticated signed PDF streaming
07-02 (audit trail plan will likely link download events to this route)
document detail page (will need createAgentDownloadToken server-side to generate adt links)
added patterns
Agent download token — purpose:'agent-download', 5-min TTL, no DB record (mirrors client download pattern)
Route-level document ID cross-check — token documentId must match route [id] param (403 on mismatch)
Path traversal guard
absPath.startsWith(UPLOADS_DIR) before every readFile from uploads/
new Uint8Array(fileBuffer) for Response BodyInit compatibility in Next.js 16 TypeScript strict mode
created modified
teressa-copeland-homes/src/app/api/documents/[id]/download/route.ts
teressa-copeland-homes/src/lib/signing/token.ts
Agent download token uses same SIGNING_JWT_SECRET as other tokens, purpose:'agent-download' claim distinguishes it
5-min TTL for agent-download (shorter than 15-min client download) — agent generates token on demand per LEGAL-03
No Auth.js session check in download route — short-lived JWT is the credential (same as client download pattern)
Token documentId vs route [id] cross-check added as defense-in-depth against token reuse across documents
Agent download token pattern: createAgentDownloadToken server-side → adt query param → GET /api/documents/[id]/download
Path traversal guard: always check absPath.startsWith(UPLOADS_DIR) before readFile, no exceptions
SIGN-07
LEGAL-03
2min 2026-03-21

Phase 7 Plan 01: Agent Download Token and Authenticated PDF Download Route Summary

agent-download JWT (5-min TTL, purpose:'agent-download') added to token.ts plus new GET /api/documents/[id]/download route that streams signed PDFs behind presigned tokens with path traversal guard and document ID cross-check

Performance

  • Duration: 2 min
  • Started: 2026-03-21T15:53:23Z
  • Completed: 2026-03-21T15:55:10Z
  • Tasks: 2
  • Files modified: 2

Accomplishments

  • Added createAgentDownloadToken and verifyAgentDownloadToken to src/lib/signing/token.ts — all 6 exports intact, no existing exports modified
  • Created GET /api/documents/[id]/download route with complete security surface: 401 for missing/expired token, 403 for ID mismatch, 403 for path traversal, 404 for unsigned/missing files
  • tsc --noEmit and npm run build both pass with zero errors after both changes

Task Commits

Each task was committed atomically:

  1. Task 1: Add agent download token functions to token.ts - cd4cb75 (feat)
  2. Task 2: Create GET /api/documents/[id]/download route - ebc47ae (feat)

Files Created/Modified

  • teressa-copeland-homes/src/lib/signing/token.ts - Appended createAgentDownloadToken (5-min TTL, purpose:'agent-download') and verifyAgentDownloadToken (throws if purpose mismatch)
  • teressa-copeland-homes/src/app/api/documents/[id]/download/route.ts - New agent-authenticated download endpoint streaming signed PDFs via adt query param JWT

Decisions Made

  • Agent download token reuses SIGNING_JWT_SECRET with a distinct purpose:'agent-download' claim — consistent with existing token pattern, no new secret needed
  • 5-min TTL (shorter than 15-min client download token) satisfies LEGAL-03 requirement for presigned URLs
  • No Auth.js session check in the download route — the short-lived JWT is the sole credential (established Phase 6 client download pattern)
  • documentId !== id cross-check as defense-in-depth: a valid token for document A cannot download document B

Deviations from Plan

None - plan executed exactly as written.

Issues Encountered

None.

User Setup Required

None - no external service configuration required.

Next Phase Readiness

  • createAgentDownloadToken is ready for use in the document detail server component (generate adt URL server-side, render download link)
  • Download route is live at /api/documents/[id]/download?adt=[token] — ready to be linked from agent portal document pages
  • Phase 7 plan 02 (audit trail) can log download events against this endpoint

Phase: 07-audit-trail-and-download Completed: 2026-03-21