Security
Threat model.
Container-level isolation between previews. Encrypted secrets at rest. No VM-grade isolation. If your threat model assumes hostile PR code, read the limits below before turning Galley loose on it.
What Galley protects against.
- Cross-preview reach. Each preview gets its own Docker network and named volumes. A container in preview A can't see preview B.
- Cross-project secret leakage. Secrets are scoped per project. Encrypted at rest with a master key the operator controls.
- Build-time privilege. Dockerfile builds run in disposable, unprivileged sandboxes with no daemon socket and the worktree mounted read-only. The autodetect path runs against an unprivileged build engine — no rootful daemon either way.
- Webhook spoofing. GitHub deliveries are HMAC-verified. A failed signature is rejected and logged.
- SSRF from previews. Outbound HTTP from the control plane (image pulls, webhook posts) blocks RFC1918, link-local, and the cloud metadata endpoint.
- Audit gaps. Every admin action lands in an audit log with actor, target, IP, timestamp.
- Stolen agent tokens. Agent bootstrap tokens are SHA-256 hashed in storage and have an expiry; rotation is one click.
What Galley does not protect against.
The isolation boundary is the Linux container. That's enough for trusted code on a shared host; it isn't enough for arbitrary code from external contributors.
- Container escape. A kernel or runtime CVE that escapes the container also escapes Galley. Don't expose previews of untrusted code to the public internet.
- Side channels between co-tenant previews. Co-tenancy is container-level, not hardware-level. Spectre-class attacks aren't mitigated.
- Resource exhaustion. Quotas help but aren't hard walls. A preview that wants to degrade its neighbours can.
- Outbound exfiltration from inside a preview. If the preview has a secret, code in the preview can post it wherever the network reaches. Scope secrets per-project, not globally.
- Drive-by PRs from external contributors. Treating those PRs as hostile is the right default. Galley's v1 isolation doesn't materially change that — VM-grade isolation via Firecracker microVMs was on the design doc and isn't in v1.
How secrets work.
Project secrets are AES-256-GCM enveloped under a master key
you provide at install (GALLEY_MASTER_KEY, 32
bytes). The key never enters the database, has no recovery.
The agent decrypts at deploy time and injects values as env
vars. External secret managers and tmpfs file-mounting are
roadmap.
Containers, not microVMs.
Standard Linux container isolation — namespaces, cgroups, restrictive seccomp on build workers, no host mounts visible to user code, unprivileged build sandboxes. Enough for code from teammates, not enough for code from strangers. VM-grade isolation for hostile PRs isn't in v1.
Reporting vulnerabilities.
Email utibeabasiumanah6@gmail.com with description and repro. Acknowledged within one business day; 90-day disclosure window starts on acknowledgement. Public credit in release notes if you want it. No bounty program yet.