Kilo
Security model
Assume the trailer is physically reachable.
A surveillance trailer sits unattended on somebody else's site, on a network you do not own, running cameras whose firmware you did not write. Kilo's boundaries are drawn on that assumption.
At a glance
- Reachable Rust gateway only
- Never routed Frigate port 5000
- Inbound ports none on the trailer
- Token ES256 / RS256 · JWKS verified
- Default role viewer (read-only)
- Container non-root 500 · caps dropped
- Secrets in Git schemas and examples only
Trust boundaries
Four boundaries, drawn once.
-
Internet → Kilo
Internet clients can reach only Cloudflare and the Kilo gateway. Nothing else on the trailer is addressable from outside.
-
Gateway → Frigate
Frigate has no published host port. Its internal unauthenticated port
5000must never be routed or exposed. The gateway talks to the authenticated proxy port8971and presents a shared secret with every request. -
Cameras → recorder
The camera network is isolated from the tunnel-facing network. Frigate reads cameras from that side only, and cameras have no route out.
-
Kilo → identity provider
Publishable keys may be present in the gateway. Service-role and secret keys must never be.
Identity & roles
Signatures are verified on the trailer, not trusted.
The gateway verifies every request itself. It does not accept a header from upstream as proof of who somebody is.
About the public demo
- This page describes the shipping identity design. The demo at app.kilo.cam runs a demonstration mode instead: local accounts held in the deployment environment, with a 12-hour symmetric session cookie, and no identity provider attached. Its cameras are simulated feeds rather than camera hardware. Everything else on this page — the boundaries, the header hygiene, the role enforcement, the container hardening — is what the demo actually runs.
-
Signature
Verified against the identity project's JWKS. The signing key must be asymmetric —
ES256orRS256. Any other algorithm is rejected before the claims are read. -
Claims checked
Issuer, audience, expiry and required claims, in addition to the signature. A token that verifies but targets the wrong issuer or audience does not get in.
-
Key cache
JWKS values are cached for ten minutes. That is deliberate: it lets already-issued sessions survive brief WAN interruptions instead of failing closed the moment the uplink flickers.
-
Authorization source
Role comes from
app_metadata.kilo_role, which users cannot edit. User-editable metadata is never used for authorization. Missing or invalid values becomeviewer. -
Role values
vieweris read-only access to configured cameras.adminis full administration. A custom role may use only letters, numbers,.and_, up to 64 characters — so a value likeadmin,vieweris rejected and falls back toviewer. -
Session storage
Access and refresh tokens are stored in HTTP-only cookies with
SameSite=Lax. Secure cookies are on for any deployment served through the HTTPS tunnel; the insecure setting exists only for loopback commissioning. -
Header rewrite
The caller's
Authorizationheader is stripped before proxying. The gateway suppliesX-Forwarded-User,X-Forwarded-GroupsandX-Proxy-Secret, and Frigate validates that secret before honouring the role. -
Weak-secret guard
The proxy secret must be at least 64 characters. The gateway refuses to start otherwise, so a misconfigured trailer fails at boot rather than silently running with a guessable secret.
Runtime hardening
Least privilege at the container level.
Pod and container
Enforced
- Runs as non-root UID/GID
500 RuntimeDefaultseccomp profile- All Linux capabilities dropped
allowPrivilegeEscalation: false- No privileged mode, host network or host ports
- No USB or GPU device in the base deployment
- Bounded CPU and memory requests and limits
- Only the writable runtime paths Frigate needs, as empty volumes — the host stays isolated
Secrets
Out of Git
- Only Secret schemas and examples are committed
- Real secrets come from a secret manager or a direct administrative command
- Camera credentials live in their own Secret and are referenced as variables, never as credential-bearing URLs
- Camera addresses belong in a site-specific overlay
- A repository clone is not sufficient to deploy
- Tunnel token and proxy secret are rotatable after any suspected compromise
Hardware acceleration is opt-in for the same reason: the base mounts no
devices, and the VAAPI overlay adds only
/dev/dri/renderD128 — never card0, and never
privileged mode.
On-site checklist
What the deployment has to do, not the software.
Some of the posture is ours and some of it is the installation's. These are site requirements, and we would rather say so than imply the software covers them.
- Put cameras on a dedicated VLAN with no general internet access, using fixed leases and unique least-privilege accounts with vendor cloud and P2P disabled.
- Bind local gateway access to a specific management address, or leave the default loopback binding in place.
- Turn on secure cookies for anything served through the tunnel. The insecure setting is for loopback commissioning only.
- Use full-disk encryption on the host and on the recording volume.
- Keep access-token lifetimes short and require MFA for administrators.
- Add Cloudflare Access or WAF as an outer policy if it suits the site — as a second layer, never as a replacement for Kilo's own authorization.
- Back up Frigate configuration and database separately from the high-volume recordings.
- Rotate the tunnel token and the proxy secret after any suspected compromise.
Scope note
- Kilo claims no compliance certification, audit attestation or security accreditation.
- Structured metrics, alerting and dependency/image scanning are planned work, not present capabilities.
- Encrypted media, UPS handling and disk-health monitoring are site-level requirements today, not built-in features.
- Object detection is disabled in the current configuration. Kilo performs no video analytics.
Next step
Bring us the hard question.
If there is a boundary here you would draw differently, or a control your sites require, tell us and we will give you a straight answer about whether Kilo does it today.
Sign-in required for the demo.