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:
@@ -54,6 +54,14 @@ JWT_SECRET=change-me-to-a-random-32-byte-secret
|
|||||||
JWT_ACCESS_TTL=15m
|
JWT_ACCESS_TTL=15m
|
||||||
JWT_REFRESH_TTL=720h
|
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,
|
# 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
|
# 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
|
# covers loopback and the Docker bridge ranges a host nginx reaches the container
|
||||||
|
|||||||
+38
-1
@@ -350,7 +350,11 @@ paths:
|
|||||||
required: false
|
required: false
|
||||||
schema:
|
schema:
|
||||||
type: string
|
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:
|
responses:
|
||||||
'200':
|
'200':
|
||||||
description: File binary
|
description: File binary
|
||||||
@@ -392,6 +396,39 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/components/schemas/Error'
|
$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:
|
/files/{file_id}/thumbnail:
|
||||||
get:
|
get:
|
||||||
tags: [Files]
|
tags: [Files]
|
||||||
|
|||||||
Reference in New Issue
Block a user