Security Model
This document describes the security boundaries and access controls for the runner infrastructure.
Privilege Boundary
Only the dind runner operates in privileged mode on the baseline shared
surface. This is required for the Docker daemon sidecar and cannot be avoided
for Docker-in-Docker builds. The ordinary docker, tinyland-docker,
tinyland-nix, and nix paths run as unprivileged containers.
Dedicated hardware-backed lanes are an explicit exception path, not part of the
baseline runner contract. The current KVM-oriented lanes (tinyland-nix-kvm
and any remaining owner-scoped compatibility debt that reuses the same device
boundary) use a narrowly scoped /dev/kvm host-device mount plus an explicit
runner-container security context. Those lanes stay additive, pinned to
explicitly labeled nodes, and separate from the ordinary shared Nix pool.
For container builds that do not require a full Docker daemon, consider using
Kaniko on the unprivileged docker runner instead. See
Docker Builds for details.
Namespace Isolation
Current runner namespaces are split by forge surface:
- GitHub ARC runners live in
arc-runners - GitLab compatibility runners live in
gitlab-runners
This keeps runner workloads separate from the cache plane, dashboard, and other infrastructure components.
RBAC
Runners have minimal RBAC permissions scoped to their own namespace family. They should not create, modify, or delete arbitrary resources outside their intended runner surface.
Secrets Management
- Runner registration material: Stored as Kubernetes Secrets in the
relevant runner namespace (
arc-systems/arc-runnersfor GitHub,gitlab-runnersfor GitLab compatibility). - Attic credentials: Nix runners receive Attic connection details via environment variables injected from Kubernetes Secrets.
- No secrets in CI variables: Sensitive values are managed through Kubernetes Secrets and OpenTofu, not GitLab CI/CD variable settings where possible.
Network Access
- Runners can reach the Attic cache server in the
nix-cachenamespace for binary cache operations. - Runners can reach external registries for pulling container images.
- Runners do not have write access to any container registry by default. Push access must be configured explicitly per job via CI/CD credentials.
Container Images
Runner job pods pull images from public registries (Docker Hub, GitLab Container Registry). The runners themselves do not have push access to any registry. Image provenance is determined by the base image specified in the runner configuration (Alpine, Rocky Linux, NixOS).
Host Device Access
If a lane needs host devices, keep the scope narrow:
- prefer host-device mounts over blanket privileged mode
- pin the lane to explicitly labeled nodes
- make the lane additive and opt-in rather than broadening the baseline shared pool
- document the exact device path and runner-container security override in the stack configuration