Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ Gatekeeper is a standalone credential-injecting TLS-intercepting proxy. It trans

Gatekeeper is pre-1.0. The configuration schema and credential source interface may change between minor versions.

## v0.22.1 — 2026-09-03

### Changed

- **The release image now runs as a non-root user by default** (`cmd/gatekeeper/Dockerfile`) — the final stage moves from `gcr.io/distroless/static-debian12` to its `:nonroot` variant, so the container starts as distroless's `nonroot` user (UID/GID 65532) instead of root. Gatekeeper needs no root privilege: it binds a high port, reads its config and key material from mounts, and writes nothing to the image filesystem. The change matters most under orchestrators that enforce `runAsNonRoot` — a pod-level policy rejected the previous image at start unless the deployment pinned an explicit `runAsUser`, and an image-level default is the right place for an invariant every consumer wants. Deployments that already pin UID 65532, or that set a pod/container user of their own, keep working unchanged. The one flow this changes is a plain `docker run` of the documented example setup: `gen-ca.sh` generates `ca.key` as `0600` under the invoking user, a bind mount preserves that ownership, and UID 65532 cannot read it — so the [Docker deployment guide](docs/content/guides/12-docker-deployment.md)'s examples now pass `--user "$(id -u):$(id -g)"` (Compose: `user:`), running the container as the key's owner rather than loosening the key's mode

## v0.22.0 — 2026-09-03

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion cmd/gatekeeper/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ COPY . .
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
go build -ldflags="-X main.version=${VERSION}" -o /gatekeeper ./cmd/gatekeeper

FROM gcr.io/distroless/static-debian12
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /gatekeeper /gatekeeper
EXPOSE 9080
ENTRYPOINT ["/gatekeeper"]
7 changes: 7 additions & 0 deletions docs/content/guides/12-docker-deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ log:

```bash
docker run -d --name gatekeeper \
--user "$(id -u):$(id -g)" \
-p 127.0.0.1:9080:9080 \
-v "$(pwd)/gatekeeper.yaml:/etc/gatekeeper/gatekeeper.yaml:ro" \
-v "$(pwd)/ca.crt:/etc/gatekeeper/ca.crt:ro" \
Expand All @@ -73,6 +74,8 @@ docker run -d --name gatekeeper \
ghcr.io/majorcontext/gatekeeper:0.17.0
```

`--user "$(id -u):$(id -g)"` runs the container as *your* user. The image defaults to distroless's `nonroot` (UID 65532), which cannot read the `0600` `ca.key` that `gen-ca.sh` generates under your ownership — bind mounts keep host ownership and permission bits. Running as the key's owner keeps the key private and the container non-root; loosening the key's mode instead would work but leaves the interception CA readable to every local user.

`-p 127.0.0.1:9080:9080` publishes the proxy port to the host's loopback interface only. Widen this (or route it through a load balancer — see [Deploying Behind a TCP Load Balancer](./11-load-balancer-proxy-protocol.md)) only once the port's exposure is deliberate.

## Wiring clients
Expand Down Expand Up @@ -143,6 +146,7 @@ postgres:

```bash
docker run -d --name gatekeeper \
--user "$(id -u):$(id -g)" \
-p 127.0.0.1:9080:9080 \
-p 127.0.0.1:5432:5432 \
-v "$(pwd)/gatekeeper.yaml:/etc/gatekeeper/gatekeeper.yaml:ro" \
Expand Down Expand Up @@ -181,6 +185,9 @@ services:
GATEKEEPER_CONFIG: /etc/gatekeeper/gatekeeper.yaml
GITHUB_TOKEN: ${GITHUB_TOKEN}
OTEL_SDK_DISABLED: "true"
# Your host uid:gid, so the container can read the 0600 ca.key it
# bind-mounts -- see the note above.
user: "1000:1000"
restart: unless-stopped
```

Expand Down
Loading