Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 25, 2026

Task PDFs are stored in file storage without authentication. Clients need temporary access without direct storage credentials or proxying through the backend.

Implementation

Signed URL utility (package/utils/signed_url.go)

  • HMAC-SHA256 signing with expires and signature query parameters
  • GenerateSignedURLWithTTL() accepts custom TTL, reuses generator instance
  • Verification enforces expiration and detects tampering

Configuration (internal/config/config.go)

  • SIGNED_URL_TTL_SECONDS: Default 300s (5 minutes)
  • SIGNED_URL_SECRET_KEY: Falls back to JWT secret

FileStorageService (package/filestorage/service.go)

GetSignedFileURL(path string, ttlSeconds uint16) (string, error)

TaskService (package/service/task_service.go)

  • Get() now returns signed URL in TaskDetailed.DescriptionURL
  • Fixed 5-minute TTL, authorization checked before generation

API Response

{
  "id": 123,
  "title": "Example Task",
  "descriptionUrl": "https://storage/task/123/description.pdf?expires=1706180400&signature=abc...",
  ...
}

URLs expire after TTL, backend remains sole authorization point, storage credentials never exposed.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • invalid-host
    • Triggering command: /tmp/go-build924877516/b824/queue.test /tmp/go-build924877516/b824/queue.test -test.testlogfile=/tmp/go-build924877516/b824/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build924877516/b709/vet.cfg om/mattn/go-sqli-errorsas go_.o 64/bin/as -p om/mattn/go-sqli-atomic -lang=go1.22 1249549/b497/imp-buildtags ce t�� om/mattn/go-sqli-errorsas oFiles,IgnoredOt-ifaceassert x_amd64/compile pkg/mod/github.c/opt/hostedtoolcache/go/1.24.2/x64/pkg/tool/linux_amd64/vet om/mattn/go-sqli-atomic -lang=go1.23 x_amd64/compile (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Backend — Generate short-lived signed URLs for task PDF access</issue_title>
<issue_description>Description
We need to allow clients to access task description PDFs stored in file storage without introducing authentication at the storage layer.
The backend will remain the single authorization point and will generate short-lived signed URLs that grant temporary, read-only access to a specific PDF.

Context / Motivation

  • Task descriptions are stored as PDF files in file storage
  • Clients must not have direct credentials or long-term access to storage
  • Backend already authenticates users and knows which task they are allowed to access
  • We want scalable file delivery without proxying files through the backend

Proposed Flow

  1. Client requests task details from backend
  2. Backend verifies user authorization for the task
  3. Backend generates a short-lived signed URL for the task’s PDF
  4. Backend returns the signed URL as part of the task response
  5. Client downloads the PDF directly from file storage using the URL

Requirements

  • Signed URL must:

    • Be read-only (GET only)
    • Be scoped to one specific file
    • Have a short TTL (e.g. 1–5 minutes)
  • Backend must:

    • Enforce authorization before generating the URL
    • Never expose storage secret keys to clients
    • Support regeneration of URLs on demand
  • URLs should be returned via JSON response (not cookies, not headers)

API Example

GET /api/v1/tasks/{taskId}

Response:

{
  "taskId": "123",
  "title": "Example task",
  "descriptionPdfUrl": "https://storage.example.com/…signed…"
}

Acceptance Criteria

  • Unauthorized users cannot obtain signed URLs
  • Signed URLs expire and return 403 after TTL
  • Backend does not proxy or stream PDF contents
  • No storage credentials are exposed to frontend

Notes

  • Prefer native signed-URL support from the storage provider if available
  • TTL should be configurable via environment/config</issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits January 25, 2026 11:02
- Add config for signed URL TTL and secret key
- Implement HMAC-based signed URL generator with expiration
- Update FileStorageService to generate signed URLs
- Modify TaskService to return signed URLs instead of direct URLs
- Add comprehensive unit tests for signed URL functionality
- Update initialization to pass new config parameters

Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
- Remove GetSecretKey() method to prevent security risk
- Add GenerateSignedURLWithTTL method to avoid creating new generators
- Refactor GetSignedFileURL to use existing generator with custom TTL
- Improve performance by reusing generator instance

Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Copilot AI changed the title [WIP] Add short-lived signed URLs for task PDF access Add signed URL generation for task PDF access Jan 25, 2026
Copilot AI requested a review from TheRealSeber January 25, 2026 11:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backend — Generate short-lived signed URLs for task PDF access

2 participants