Pull the image
latest, and X.Y.Z for each release. Images are multi-architecture (linux/amd64, linux/arm64), each built natively.
Published when a
vX.Y.Z tag is pushed. Before the first release, build locally: docker build -t warden:local .The package is built from a private repository, so it inherits private visibility, and GitHub offers no API to change that — the setting exists only in the web UI. Make it public once, at
https://github.com/users/Abhishek-Mallick/packages/container/warden/settings; every later release inherits the setting. Until then docker pull needs a ghcr.io login, and an anonymous pull reports that the package does not exist.Run it
The image runs as UID 65532 and contains no shell. A named volume mounted at the state directory inherits the right ownership on first use; a bind mount from the host does not, so
chown 65532:65532 it first.
The whole stack, with a database beside it
The demo stack — Warden plus a seeded PostgreSQL, one command — lives in the source repository, which is private. With access to it:Without access, compose your own: the image above, a PostgreSQL service, and the configuration from the quickstart. The only thing the demo adds is seed data.
- Do not publish the database port. Agents reach it through Warden or not at all, which is the arrangement Warden exists to create.
- Publish Warden’s port to loopback unless TLS is configured. Warden refuses a non-loopback listener without TLS unless told otherwise.
Production notes
- TLS. Warden refuses a non-loopback listener without TLS unless
allow_insecure_listen: trueis set — appropriate only when something in front terminates TLS. Mount the certificate and key and settls.cert/tls.key. See TLS and state. - Secrets. The configuration file holds a database DSN. Mount it from a secret store rather than baking it into an image, and prefer
key_hash/token_hashover plaintext credentials — the gateway warns when it finds plaintext. - Health.
GET /healthis unauthenticated and reports process liveness and how many connections are configured, and nothing about what it governs. Use it as the container health check. - Restarts. With
data_diron a volume, the audit chain, leases, and idempotency keys survive. A pending async approval does not: it never ran, and the agent is told the outcome is unknown if it retries the same key.