Documentation
¶
Index ¶
Constants ¶
const ( DefaultAgentBuilderImage = "ghcr.io/airlockrun/airlock-agent-builder:v" + airlock.Version DefaultAgentBaseImage = "ghcr.io/airlockrun/airlock-agent-base:v" + airlock.Version )
Default toolserver/runtime images. Pinned to airlock.Version so every airlock release references the matched pair built+published by the same release tag — drift becomes impossible in prod. Self-host operators can still override via AGENT_BUILDER_IMAGE / AGENT_BASE_IMAGE if they need a custom build.
const ( LabelAgentNetworkAccess = "run.airlock.agent-network-access" LabelAgentNetworkAliases = "run.airlock.agent-network-aliases" )
LabelAgentNetworkAccess marks trusted containers that Airlock may attach to managed per-agent networks. The value is the owning InstanceID. Aliases are supplied per endpoint because aliases from the seed network do not carry over when Docker connects a container to another network.
const LabelInstance = "run.airlock.instance"
LabelInstance is the Docker label key stamped on every container and agent image with its owning airlock instance (InstanceID). It is the source of truth for ownership: container/image list+prune calls filter on it, so instances sharing a daemon never see or remove each other's resources. Defined here (imported by both container and builder) so the build-time --label and the prune-time filter can never drift apart.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct {
// --- Core ---
DatabaseURL string // Airlock's own Postgres connection
JWTSecret string
ServerAddr string
// --- S3 / Object Storage ---
// Two audiences: Airlock process and public internet. Agents never hit
// S3 directly — their storage goes through airlock's /api/agent/storage
// API, and presigned shares use S3URLPublic over internet egress.
S3URL string // Airlock process → MinIO (e.g. "http://localhost:9090")
S3URLPublic string // Public internet → MinIO via reverse proxy (e.g. "https://s3.dev.airlock.run")
S3AccessKey string
S3SecretKey string
S3Bucket string
S3Region string
// --- Database (agent schemas) ---
// Airlock creates per-agent Postgres schemas. Connections are built from parts
// because Airlock process and agent containers reach Postgres via different hosts.
DBHost string // Airlock process → Postgres (e.g. "localhost")
DBHostAgent string // Agent containers → Postgres via Docker network (e.g. "postgres")
DBPort string
DBPortAgent string // Agent containers → Postgres/relay port
DBName string
DBSSLMode string // "disable" for dev, "require" for prod
// --- Networking ---
PublicURL string // Public base URL (OAuth callbacks, auth links, e.g. "https://dev.airlock.run")
TLSMode string // optional deployment ingress mode: local, wildcard, tunnel, manual, or proxy
APIURLAgent string // Agent containers → Airlock API (e.g. "http://host.docker.internal:8080"). Intentionally independent of PublicURL/AgentDomain — it's the internal container→airlock callback, not a public URL.
AgentDomain string // Subdomain routing (e.g. "dev.airlock.run" → {slug}.dev.airlock.run)
// AgentScheme/AgentPort are derived once from PublicURL (see Load).
// Together with AgentDomain they form the single source of truth for
// per-agent external route URLs — use AgentBaseURL(slug), never
// re-derive these elsewhere.
AgentScheme string // "http" | "https"
AgentPort string // explicit non-default port, else ""
DockerNetwork string // Docker network for infra + toolserver/build containers (e.g. "airlock-dev")
// AgentNetwork is the trusted dependency-discovery network when managed
// per-agent networking is enabled. Shared/native mode attaches runtimes to
// it directly. It defaults to DockerNetwork when AGENT_NETWORK is unset.
AgentNetwork string
// AgentNetworkPerAgent creates an internal Docker network for each runtime
// and attaches only trusted dependencies discovered on AgentNetwork. Native
// development leaves this false because the Airlock process runs on the host.
AgentNetworkPerAgent bool
// AgentHTTPPrivateCIDRs controls which non-public addresses Airlock may dial
// for brokered agent HTTP, connection, MCP, and outbound OAuth calls. Public
// HTTPS addresses are always allowed; link-local, multicast, and unspecified
// addresses are blocked. Loopback is available only on a localhost
// development instance.
AgentHTTPPrivateCIDRs []netip.Prefix
// --- Encryption ---
// AES-256-GCM for provider API keys, webhook secrets, tokens at rest.
// Generate with: openssl rand -hex 32
EncryptionKey string // hex-encoded 32-byte key (required)
EncryptionKeyOld string // hex-encoded 32-byte key (optional, for rotation)
EncryptionKeyRewrap bool // re-encrypt persisted values during an explicit stop-all key rotation
// --- Containers ---
ContainerRuntime string // "docker"
ContainerImage string // toolserver image name
// InstanceID namespaces every Docker resource this airlock owns —
// agent/builder container names, agent image labels, and build-cache
// volume names. All container/image list+prune calls filter on the
// run.airlock.instance=<InstanceID> label, so instances sharing a
// daemon never touch each other's resources. Required (AIRLOCK_INSTANCE_ID):
// the compose/.env files supply it (default "airlock"); co-locating
// instances on one daemon means giving each a DISTINCT value.
InstanceID string
// AgentRuntime is the OCI runtime for agent containers — "" = the
// Docker default (runc), "runsc" = gVisor. Set via AGENT_SANDBOX
// (gvisor → runsc). The HostConfig hardening (cap drop, no-new-privs,
// limits) applies on either runtime; gVisor adds a userspace-kernel
// sandbox on top.
AgentRuntime string
// AgentMemoryLimitBytes caps each agent container's memory (0 =
// unlimited). Optional because the host's size is unknown; OomScoreAdj
// makes agents the first OOM victim regardless, so the host survives
// collective pressure without a per-agent cap. Set via
// AGENT_MEMORY_LIMIT (e.g. "512m", "2g").
AgentMemoryLimitBytes int64
// AgentHostGateway lets agent containers resolve host.docker.internal
// when Airlock itself runs on the host rather than in Compose.
AgentHostGateway bool
// --- Build pipeline ---
// AgentReposPath is the base directory holding per-agent git repos.
// Each agent's source lives at <AgentReposPath>/<agentID>/ with its
// own .git/. The 003_split_monorepo migration moves any pre-multirepo
// install (single monorepo with agents/{id}/ subdirs) from the legacy
// AGENT_MONOREPO_PATH location into this layout on first startup
// after upgrade.
AgentReposPath string
AgentBuilderImage string // toolserver sandbox image (default: DefaultAgentBuilderImage)
AgentBaseImage string // agent runtime base image
AgentRegistryURL string // Docker registry for agent images (empty = local only)
// BuildkitHost, when set (e.g. unix:///run/buildkit/buildkitd.sock),
// routes agent image builds through a remote buildx builder backed by a
// rootless buildkitd — so the agent's untrusted setup.sh runs as root
// inside buildkitd (unprivileged on the host), not on the host's root
// dockerd. Empty = legacy `docker build` on the host daemon (dev).
BuildkitHost string
AgentLibsPath string // path containing agentsdk/ goai/ sol/ dirs (the libs we own). Set after startup either to the user-supplied AGENT_LIBS_PATH (dev) or the extracted cache dir (prod). Always non-empty by the time the build pipeline runs.
AgentLibsExtPath string // path containing goose/ templ/ dirs (third-party libs always sourced from the agent-builder image's baked /libs/). Set at startup by EnsureLibs; not read from env.
AgentLibsCacheDir string // base dir where extracted /libs/ from agent-builder image is cached. Subdir per image digest.
// AgentLibsPathExplicit is true iff the operator set AGENT_LIBS_PATH as
// an env var (i.e. dev mode, where AgentLibsPath points at a live source
// tree we want overlaid into toolservers). False in prod (where
// AgentLibsPath holds the extracted cache dir, used only for the
// per-agent docker build's --build-context — overlaying the extracted
// cache onto the toolserver's image-baked /libs/ would just mask the
// authoritative content with itself, and risks shadowing files if the
// extraction is mid-way or partial).
AgentLibsPathExplicit bool
// AgentCodegenPath is where the build pipeline creates per-build temp
// directories for sparse checkouts and cache-warming scaffolds.
// AgentCodegenVolume is the Docker volume name that contains
// AgentCodegenPath and is also mounted into spawned sibling
// containers — required for docker-in-docker (airlock-in-container)
// deployments where bind-mounts of host paths don't work because
// airlock's filesystem is the container overlay, not the host.
//
// Both unset: dev-on-host behavior (MkdirTemp under /tmp, bind mount
// the resulting host path into siblings — daemon and airlock share
// the FS, so it just works).
//
// Both set: docker-compose mode. MkdirTemp goes inside the named
// volume, sibling containers mount the same volume by name. The
// daemon resolves both ends through the same managed volume so
// the absolute path airlock writes is the same path the sibling
// reads.
AgentCodegenPath string
AgentCodegenVolume string
// --- Reverse proxy ---
ReverseProxyAuthSecret string // shared only with the deployment's Caddy process
ReverseProxyTrustedPeers string // comma-separated immediate-peer CIDRs
ReverseProxyLimit int // exact rightmost X-Forwarded-For hop to use (default: 1)
CaddyTrustedProxies string // space-separated external ingress CIDRs for TLS_MODE=proxy
// --- Optional ---
WorkDir string // temp directory for agent tool execution
LLMProxyURL string // route LLM calls through this proxy (e.g. telescope -watch)
ActivationCodeFile string // path to write the first-run activation code to (so `docker compose` users can `cat` it)
ForceInlineAttachments bool // dev escape hatch: force base64 delivery to LLMs even when the provider supports URLs (public URL unreachable from provider)
// --- OIDC (optional) ---
OIDCIssuerURL string
OIDCClientID string
OIDCClientSecret string
OIDCRedirectURL string
}
func (*Config) AgentBaseURL ¶ added in v0.4.0
AgentBaseURL is the external base URL for an agent's registered HTTP routes: {scheme}://{slug}.{AgentDomain}[:port], no trailing slash. The one place that assembles it — handlers and the container-env builder read this, never re-derive scheme/domain/port.