Repository navigation
A private namespace with a signing_key can serve its files through time-limited signed URLs — no auth header, no guessing, and an expiry.
bkn files ns create reports --signing-key auto
bkn files sign reports q3.pdf --ttl 24h
# -> /v1/files/reports/q3.pdf?sig=...&exp=...const url = bkn.files.sign("reports", "q3.pdf", { ttl: "24h" });The signature is HMAC-SHA256(signing_key, "ns/name|exp") in URL-safe base64, compared in constant time. The key is generated with crypto/rand when you pass auto, and carries json:"-" so it is never serialised into an API response — files ns list does not leak it.
The use case is an email gate. A hook stores the lead, signs a URL and returns it. The recipient downloads without an account; the link expires on its own and cannot be forged.
Credit and review
The feature is Devin's. It is released after review — constant-time compare, expiry checked before the signature, migration present for existing databases — and an end-to-end check on a real build: unsigned request 404, signed 200, tampered signature 404, expired URL 404, key absent from ns list.
Also in this release, for anyone on v0.3.0
v0.3.1's two files fixes:
- A name claim was a check followed by a write. Two uploads of the same free name both saw it free and the second silently replaced the first — twelve concurrent writers all reported success against the old code. Now exactly one wins.
--verify-typemakes a namespace decide a file's type from its bytes instead of from what the uploader declared. Off by default.
Upgrading
Two ALTER TABLEs on file_namespaces (verify_type, signing_key), both defaulted, both instant. Existing namespaces behave exactly as before: no signing key means no signed access, and private namespaces still require auth.