Key Design
Presigned URL Auth
BSS uses presigned URLs for Lambda dispatch endpoints — no JWT, no shared auth sessions. This follows the same pattern as S3 presigned URLs.
Problem
BSS and dreamlake-server use different JWT secrets. The CLI authenticates with dreamlake-server (via vuer-auth login), but BSS can't verify that token. Rather than sharing secrets or adding a token exchange flow, we use HMAC-signed URLs.
Flow
CLI DreamLake Server BSS
│ │ │
├─ 1. Upload file ────────────────────────────────────────→│ (public)
│ │ │
├─ 2. POST /assets/audio ────→│ │
│ (dreamlake JWT) │ │
│ ├─ Register asset │
│ ├─ Generate presigned URL: │
│ │ sig = HMAC-SHA256( │
│ │ secret, │
│ │ "audio-process: │
│ │ audioId=X:exp=T") │
│←── { id, lambdaUrl } ───────│ │
│ │ │
├─ 3. POST lambdaUrl ────────────────────────────────────→│
│ (no auth header) │ │
│ │ Verify: recompute HMAC │
│ │ ├─ Check exp > now │
│ │ ├─ Check sig matches │
│ │ └─ 202 → invoke Lambda │
│←── 202 dispatched ──────────────────────────────────────│Signature Format
sig = HMAC-SHA256(PRESIGN_SECRET, "{action}:{sortedParams}:{exp}")| Component | Example |
|---|---|
action | audio-process |
sortedParams | audioId=69df3ca3fde477c8641d3cbb (all query params except sig/exp, sorted by key) |
exp | 1776240000 (Unix timestamp) |
PRESIGN_SECRET | Shared env var between dreamlake-server and BSS |
The resulting URL:
http://bss:10234/lambdas/audio-process?audioId=69df3ca3...&exp=1776240000&sig=abc123...Which Endpoints Use Presigned Auth
| Endpoint | Auth |
|---|---|
POST /lambdas/hls-split | Presigned URL |
POST /lambdas/audio-process | Presigned URL |
POST /lambdas/text-process | Presigned URL |
POST /lambdas/label-process | Presigned URL |
| Everything else | Public (no auth) |
Why Not JWT
| Approach | Problem |
|---|---|
| Shared JWT secret | Couples BSS and dreamlake-server by secret |
| Token exchange | Extra round trip, expiry during long uploads |
| BSS verifies dreamlake JWT | BSS needs dreamlake-server's key |
| Presigned URLs | Self-contained, no shared state, time-bounded |
Security Properties
- Time-bounded: URL expires (default 1 hour)
- Action-scoped: Signature includes the action name — can't reuse for a different endpoint
- Param-bound: Signature includes all params — can't change the audioId/videoId
- No replay after expiry: Expired URLs are rejected
- No secret exposure: CLI never sees the HMAC secret, only the signed URL
Configuration
Both servers need the same PRESIGN_SECRET in their .env:
PRESIGN_SECRET=dreamlake-presign-secret-devThis is NOT a JWT secret — it's a simple HMAC key for URL signing.