Gateway Guardian On-Prem Deployment
This runbook covers the on-prem shape for Linux amd64 and arm64
deployments while keeping the developer workflow usable from macOS. It provides
two paths:
- Docker Compose demo: a single-host stack with bundled Postgres and RustFS.
- Kubernetes/Helm: a production profile that expects external Postgres and external S3-compatible object storage.
RustFS replaces MinIO for bundled artifact storage. RustFS is S3-compatible,
supports AWS Signature V4, and publishes multi-architecture Docker images. The
demo pins rustfs/rustfs:1.0.0-alpha.94, the newest versioned multi-arch tag
available when this profile was added.
References:
- https://docs.rustfs.com/installation/docker/
- https://docs.rustfs.com/features/s3-compatibility
- https://hub.docker.com/r/rustfs/rustfs/tags
Architecture
Section titled “Architecture”Gateway Guardian uses two persistence layers on-prem:
- PostgreSQL: registry, audit, auth, plugin metadata, and state blobs.
- S3-compatible object storage: immutable plugin WASM artifact bytes.
The current on-prem profile keeps state attestation blobs in Postgres. RustFS is only bundled for plugin artifacts in the Compose demo. Kubernetes deployments should use an operator-managed RustFS/S3 endpoint and an operator-managed Postgres instance.
Docker Compose Demo
Section titled “Docker Compose Demo”Prerequisites:
- Docker Engine with Compose v2 on Linux
amd64orarm64. - Go installed locally if you want to run the demo smoke tests from source.
- Network access to pull third-party base/runtime images unless they are already mirrored locally.
Build the local Guardian images:
just --justfile deploy/onprem/justfile buildStart the stack:
just --justfile deploy/onprem/justfile upup also runs the local image build and then starts services with
--no-build, so the stack uses the images built from the checkout instead of
official images from GHCR.
Endpoints:
- Console and control-plane API:
http://localhost:8080 - Gateway through HAProxy:
http://localhost:10000 - RustFS S3 API:
http://127.0.0.1:9000 - RustFS console:
http://127.0.0.1:9001
Run the demo artifact flow:
just --justfile deploy/onprem/justfile demo-artifactThat publishes an allow-all WASM plugin through the control-plane, stores the artifact in RustFS, restarts the gateway, and checks that the gateway cached the artifact after loading the active snapshot.
Run the demo agent registration flow:
just --justfile deploy/onprem/justfile demo-registrationThat asks the control-plane to mint a short-lived provisioning token, registers
a deterministic local did:key with the gateway, and checks that the
control-plane can list the active agent. To run the full local smoke suite:
just --justfile deploy/onprem/justfile test-e2eStop the stack:
just --justfile deploy/onprem/justfile downRemove volumes when you want a clean slate:
just --justfile deploy/onprem/justfile down-volumesPortable Airgap Bundle
Section titled “Portable Airgap Bundle”Use the airgap packaging flow when the target Linux VM or DPU should not clone
the repository, install Go/Node/Rust, or pull from public registries. The bundle
contains a no-build Compose file, .env.example, HAProxy config, Linux helper
binaries, Docker image archives, a manifest, checksums, and install/test
scripts.
Build an amd64 bundle:
just --justfile deploy/onprem/justfile package-airgap amd64 devBuild an arm64 bundle:
just --justfile deploy/onprem/justfile package-airgap arm64 devThe output is written to:
deploy/onprem/dist/guardian-onprem-dev-linux-<arch>.tar.gzThe target host install flow is:
tar -xzf guardian-onprem-dev-linux-amd64.tar.gzcd guardian-onprem-dev-linux-amd64./bin/load-images.sh./bin/install.sh./bin/test-e2e.shThe target host only needs Docker Engine with Compose v2. It does not need Git, Go, Node, Rust, or registry access after receiving the tarball. For quick local layout validation without creating image archives:
just --justfile deploy/onprem/justfile package-airgap-layout amd64 devCompose Configuration
Section titled “Compose Configuration”The first up creates deploy/onprem/compose/.env from .env.example.
Change these values before sharing the stack:
POSTGRES_PASSWORDGUARDIAN_DB_DSNRUSTFS_ACCESS_KEYRUSTFS_SECRET_KEYGUARDIAN_PLUGIN_SIGNER_*GUARDIAN_REGISTRATION_TOKEN_SECRETGUARDIAN_AGENT_REGISTRATION_*
The demo signer in .env.example is deterministic and only suitable for local
validation. Generate a fresh signer for any shared environment:
SIGNER_SEED=$(just --justfile llm-gateway/justfile gen-key | awk -F= '/seed_b64url/{print $2; exit}')just --justfile llm-gateway/justfile pubkey-from-seed "$SIGNER_SEED"Put the seed in GUARDIAN_PLUGIN_SIGNER_SEED_B64URL for the demo publisher and
put the public key in GUARDIAN_PLUGIN_SIGNER_PUBLIC_KEY for the services.
The Compose file does not pin platform:. On Linux it pulls the host
architecture automatically. On macOS, Docker Desktop still runs the Linux image
variant for the host architecture; set DOCKER_DEFAULT_PLATFORM=linux/amd64 or
DOCKER_DEFAULT_PLATFORM=linux/arm64 only when deliberately testing emulation.
Kubernetes Helm Profile
Section titled “Kubernetes Helm Profile”The on-prem Helm profile is deploy/values-onprem.yaml. It disables the bundled
Postgres and HAProxy ingress dependencies and configures both services for an
external S3-compatible artifact store.
Create the required secrets:
kubectl create namespace guardian
kubectl -n guardian create secret generic guardian-db \ --from-literal=dsn='postgres://guardian:REPLACE@postgres.example.internal:5432/guardian_gateway?sslmode=require'
kubectl -n guardian create secret generic guardian-artifact-s3 \ --from-literal=accessKeyID='REPLACE' \ --from-literal=secretAccessKey='REPLACE'Render or install:
helm dependency build deploy/charts/guardian-stack
helm upgrade --install guardian deploy/charts/guardian-stack \ --namespace guardian \ -f deploy/values-onprem.yaml \ --set llmGateway.image.tag=REPLACE_WITH_RELEASE \ --set controlPlane.image.tag=REPLACE_WITH_RELEASE \ --set guardianUI.image.tag=REPLACE_WITH_RELEASE \ --set llmGateway.plugins.artifactStorage.s3.endpoint=https://s3.example.internal \ --set controlPlane.plugins.artifactStorage.s3.endpoint=https://s3.example.internalReplace the placeholder hosts, TLS secret names, image tags, S3 endpoint, and
trusted plugin signer in deploy/values-onprem.yaml before applying it.
Airgapped Installs
Section titled “Airgapped Installs”For airgapped sites, mirror these images into the customer registry:
ghcr.io/eqtylab/guardian-llm-gatewayfor Helm deployments, or buildguardian-llm-gateway:localfrom this checkout for Compose demosghcr.io/eqtylab/guardian-control-planefor Helm deployments, or buildguardian-control-plane:localfrom this checkout for Compose demosghcr.io/eqtylab/guardian-consolefor Helm deployments, or buildguardian-console:localfrom this checkout for Compose demospostgres:16for the Helm init container and Compose demorustfs/rustfs:1.0.0-alpha.94for the Compose demoamazon/aws-cli:latestfor the Compose bucket initializerhaproxy:3.0-alpinefor the Compose demoalpine:3.20for Compose volume permission helpers
Then set the image repositories in deploy/values-onprem.yaml to the mirrored
registry. For Compose demos, either keep the default local image names and build
on the target host, or set deploy/onprem/compose/.env to preloaded/mirrored
image names. Helm dependencies should be built and vendored before transfer when
the target environment cannot reach public chart repositories.
Operational Notes
Section titled “Operational Notes”- Postgres must be migrated by the gateway before the control-plane is useful. In Compose, both services share one Postgres instance and the gateway applies migrations on startup.
- RustFS is bound to
127.0.0.1in Compose so the S3 API and console stay local to the demo host. - The Helm profile expects the S3 bucket to exist. The Compose demo creates the bucket with an AWS CLI one-shot container.
- The S3 provider uses path-style requests for RustFS.
- OIDC is intentionally disabled in the on-prem profile. Wire customer OIDC as
a follow-up by enabling
controlPlane.auth.bearerand the browser login provider appropriate to the customer environment.