docs(project): document the content-token endpoint and CONTENT_TOKEN_TTL

Add POST /files/{file_id}/content-token to the spec, note that the content
GET's access_token parameter also accepts a content token, and document the
CONTENT_TOKEN_TTL knob (default 6h) and its leak/revocation trade-off.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-15 17:53:30 +03:00
parent 35b1b2e6d5
commit 6fba04cd00
2 changed files with 46 additions and 1 deletions
+8
View File
@@ -54,6 +54,14 @@ JWT_SECRET=change-me-to-a-random-32-byte-secret
JWT_ACCESS_TTL=15m
JWT_REFRESH_TTL=720h
# How long a content token is valid. It's a single-file capability the client
# puts in a media URL to open/stream an original by link (e.g. a long video in a
# new tab), so playback survives the short access-token expiry and session
# rotation. Longer = fewer interruptions but a wider window in which a leaked URL
# can read that one file; it can't be revoked before expiry. Keep it roughly as
# long as a viewing session lasts.
CONTENT_TOKEN_TTL=6h
# Reverse-proxy hops (comma-separated CIDRs/IPs) whose X-Forwarded-For is trusted,
# so the auth rate limiter sees real client IPs instead of the proxy's. The default
# covers loopback and the Docker bridge ranges a host nginx reaches the container
+38 -1
View File
@@ -350,7 +350,11 @@ paths:
required: false
schema:
type: string
description: Access token, as an alternative to the Authorization header (GET only).
description: >
Access token or a file-scoped content token (obtained from POST
/files/{file_id}/content-token), as an alternative to the
Authorization header (GET only). A content token outlives the
access token, so long media keeps streaming past access-token expiry.
responses:
'200':
description: File binary
@@ -392,6 +396,39 @@ paths:
schema:
$ref: '#/components/schemas/Error'
/files/{file_id}/content-token:
post:
tags: [Files]
summary: Mint a content token for opening/streaming the original by URL
description: >
Returns a short-lived, single-file capability token to place in the
access_token query parameter of GET /files/{file_id}/content. Unlike the
access token it is scoped to this one file and is session-independent, so
it survives access-token expiry and refresh rotation — letting a long
video opened in a new tab keep streaming. Requires view permission on the
file. The token is a bearer credential for that file until it expires.
parameters:
- $ref: '#/components/parameters/file_id'
responses:
'200':
description: Content token
content:
application/json:
schema:
type: object
required: [token, expires_in]
properties:
token:
type: string
description: Capability token for the access_token query parameter.
expires_in:
type: integer
description: Token lifetime in seconds.
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
/files/{file_id}/thumbnail:
get:
tags: [Files]