Files
AutopilotMonitor/src
Oliver Kieselbach 884b74cb8c reports: ticket-gated download of session-report ZIPs for the MCP (x29 phase 2)
The report ZIP a tenant admin submitted and the preserved diagnostics copy could only be
fetched with a storage key through an az script. They now follow the diagnostics ticket
model: mint under the caller's JWT, download with a short-lived HMAC ticket, bytes proxied
through the backend — a storage SAS never leaves it.

Backend
- DiagnosticsDownloadTicket gains a purpose parameter (default diag-dl-v1, new
  report-dl-v1): a ticket for one download surface is rejected on the other (wrong_purpose).
- POST global/session-reports/download-ticket (GlobalReadOrAdmin, same tier as the portal's
  download-url): flat-name guard, existence check, best-effort size, ticket bound to the
  caller's home tenant; reuses DiagnosticsDownloadTicketResponse (destination SessionReports).
- GET global/session-reports/download (PublicAnonymous, ticket is the sole authority):
  per-IP limit + decode via the new TicketDownloadPrelude (shared with the diagnostics route),
  streamed from the session-reports container with BlobStorageService.OpenReadAsync.
- Constants.BlobContainers.SessionReports replaces three duplicated literals.
- Pins: catalog completeness/JWT-exempt theories, auth-skip, no-store, purpose tests.

MCP
- get_session_report_download (platform scope) mirrors get_session_diagnostics: kind
  (session-report / preserved-diagnostics / diag-files-report), size, download URL, expiry,
  instructions; catalog snapshot updated.

Submodules: session-report-debug skill on the tool, fetch-report-zip.sh deleted; plan/todo.
Tests: backend 5839, MCP 683, solution build green.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-04 14:01:52 +02:00
..