Summary
Fixes the two P1 findings from the internal review on #106.
#209 — sign-in input bounds
LoginBeginvalidates the account name before it reaches the per-account rate limiter or the ceremony store. An invalid name gets the same decoy as an unknown account, under one fixed limiter key, so the response shape does not change and the input cannot decide the table’s size.AddPasskeyBegincaps the label before the ceremony stores it, andvalidateCredentialbounds the label, transports, attachment, and attestation type before the roster stores them.- Rate-limit keys are hashed to a fixed size when longer than 256 bytes; the proxy client-address header is capped at 64 bytes before it is used as a key or written to the log; expired limiter entries are swept every 1024 keys instead of only at the 65,536-key cap.
#210 — private response caching
- A new
downloadCacheControlasks the repository’s ACL: public repositories staypublic, max-age=300, private ones becomeprivate, no-store. - It is applied to release artifacts, source archives, run artifacts, and raw file downloads.
rendernow defaults templated pages toprivate, no-cache; the auth, account, and run-log pages still setno-storeand keep it.docs/operations.mdproduction baseline explains what a caching proxy or CDN may keep and that the directives must not be stripped.
Tests
- New bounds for oversized labels and credential fields, a hashed rate-limit key, a capped client address, and an oversized login name.
- A templated page carries a private cache directive.
- A private repository’s release artifact, archive, and run page/artifact are authorized but not publicly cacheable; a public artifact still is.
vole workflow check and vole workflow run verify pass.