Skip to content

Secure Downloads

Releasy issues short-lived download tokens and resolves them to presigned GET URLs. Tokens are stored hashed and are tied to a customer, artifact, and TTL.

Configuration

Set the maximum TTL (seconds) for download tokens:

bash
RELEASY_DOWNLOAD_TOKEN_TTL_SECONDS=600

Downloads also require artifact storage to be configured (see docs/artifacts.md).

Issue a Download Token

http
POST /v1/downloads/token

Headers:

  • x-releasy-api-key: <api_key> (must include downloads:token scope)

Notes:

  • Supports Idempotency-Key (see docs/api-conventions.md).

Request body:

json
{
  "artifact_id": "<artifact-uuid>",
  "purpose": "ci",
  "expires_in_seconds": 300
}

Notes:

  • expires_in_seconds is optional and must be > 0 and <= RELEASY_DOWNLOAD_TOKEN_TTL_SECONDS.
  • The release must be published and the customer must have an active entitlement for the release product.

Response body:

json
{
  "download_url": "https://example.com/v1/downloads/<token>",
  "expires_at": 1735300000
}

Example:

bash
curl -X POST \
  -H "x-releasy-api-key: $RELEASY_API_KEY" \
  -H "content-type: application/json" \
  -d '{"artifact_id":"...","expires_in_seconds":300}' \
  http://localhost:8080/v1/downloads/token

Resolve a Download Token

http
GET /v1/downloads/{token}

Returns a 302 Found redirect to a presigned GET URL. The redirect response includes Cache-Control: no-store.

Example:

bash
curl -v http://localhost:8080/v1/downloads/<token>

Entitlements

Download tokens require an active entitlement record for the customer and release product. Entitlements are stored in the entitlements table and are considered active when starts_at <= now and ends_at is NULL or in the future.

Error Responses

Issue Token Errors

StatusMessageCause
401 UnauthorizedunauthorizedMissing or invalid API key
403 Forbiddenmissing scopeAPI key lacks downloads:token scope
403 Forbiddenrelease not publishedRelease is still in draft status
403 Forbiddenentitlement requiredCustomer has no active entitlement
404 Not Foundartifact not foundArtifact ID does not exist

Resolve Token Errors

StatusMessageCause
404 Not Founddownload token not foundToken invalid or customer suspended
404 Not Founddownload token expiredToken TTL exceeded
404 Not Foundrelease not availableRelease unpublished or no entitlement