# authentik proxy outpost from the official 2026.8.4 release archive. # Proxy is Rust (2026.8 rewrite); LDAP/RADIUS remain Go and are out of this image. # Official runtime is FIPS Debian (USER 1000). This recipe is scratch + collected # glibc libraries + CA certs + UID 65532 so the Debian-base C/H set never ships. ARG RUST_IMAGE=docker.io/library/rust:1.97.1-bookworm@sha256:0e2bcaef56d041a486784e54104a81aebe0da44bd03019bd70bc0401e42e4a97 FROM ${RUST_IMAGE} AS build LABEL io.thepeoples.hardened.build-owner="hardened-batch4" ARG SOURCE_URL=https://github.com/goauthentik/authentik/archive/refs/tags/version/2026.8.4.tar.gz ARG SOURCE_SHA256=3a94c98c8dc7a24f4b6be28d962a084928f8ada0fcb1d7781b36822a912fbf91 ARG SOURCE_COMMIT=410f46e5cf18f97a1f0056b30984a145242df55d ARG VERSION=2026.8.4 ENV DEBIAN_FRONTEND=noninteractive \ CARGO_TERM_COLOR=never \ CARGO_INCREMENTAL=0 \ AWS_LC_FIPS_SYS_CC=clang WORKDIR /src # cmake/clang/golang are required by aws-lc-rs FIPS (proxy feature). rustc 1.97.1 # is already in the builder; rust-toolchain extra components are dropped so # rustup does not fetch clippy/rust-analyzer during the proxy-only build. RUN apt-get update \ && apt-get install -y --no-install-recommends ca-certificates wget cmake clang golang \ && rm -rf /var/lib/apt/lists/* RUN wget -q -O /tmp/upstream.tar.gz "${SOURCE_URL}" \ && printf '%s %s\n' "${SOURCE_SHA256}" /tmp/upstream.tar.gz | sha256sum -c - \ && tar -xzf /tmp/upstream.tar.gz --strip-components=1 -C /src \ && printf '[toolchain]\nchannel = "1.97.1"\n' > rust-toolchain.toml # Stable cache IDs share caches across builds, rather than retaining a cache per slice. RUN --mount=type=cache,id=hardened-cargo-registry,target=/usr/local/cargo/registry \ --mount=type=cache,id=hardened-cargo-git,target=/usr/local/cargo/git \ --mount=type=cache,id=hardened-cargo-target,target=/src/target \ mkdir -p /out/records /out/source /out/rootfs/tmp /out/rootfs/etc \ && cp Cargo.lock /out/records/upstream.Cargo.lock \ && cp rust-toolchain.toml /out/records/rust-toolchain.toml \ && cargo vendor --locked vendor \ && printf '\n[source.crates-io]\nreplace-with = "vendored-sources"\n[source.vendored-sources]\ndirectory = "vendor"\n' >> .cargo/config.toml \ && cargo build --package authentik --no-default-features --features proxy --locked --release --offline \ && cp target/release/authentik /out/authentik \ && rustc -vV > /out/records/rustc-version.txt \ && cargo --version > /out/records/cargo-version.txt \ && cp Cargo.lock /out/records/effective.Cargo.lock \ && cp LICENSE /out/records/ \ && printf '%s\n' "${SOURCE_COMMIT}" > /out/records/upstream-commit \ && ldd /out/authentik > /out/records/ldd.txt \ && printf 'nonroot:x:65532:65532:nonroot:/:/sbin/nologin\n' > /out/rootfs/etc/passwd \ && printf 'nonroot:x:65532:\n' > /out/rootfs/etc/group \ && printf 'passwd: files\ngroup: files\nshadow: files\nhosts: files dns\nnetworks: files\nprotocols: files\nservices: files\n' > /out/rootfs/etc/nsswitch.conf \ && printf '127.0.0.1 localhost\n::1 localhost ip6-localhost ip6-loopback\n' > /out/rootfs/etc/hosts \ && chmod 1777 /out/rootfs/tmp \ && ldd /out/authentik | awk '$3 ~ /^\// { print $3 } $1 ~ /^\// { print $1 }' | sort -u | while read -r lib; do \ [ -e "$lib" ] || continue; \ mkdir -p "/out/rootfs$(dirname "$lib")"; \ cp -aL "$lib" "/out/rootfs$lib"; \ done \ && for nss in /lib/x86_64-linux-gnu/libnss_*.so* /lib/x86_64-linux-gnu/libresolv.so*; do \ [ -e "$nss" ] || continue; \ mkdir -p "/out/rootfs$(dirname "$nss")"; \ cp -aL "$nss" "/out/rootfs$nss"; \ done \ && cp /tmp/upstream.tar.gz /out/source/authentik-${VERSION}.tar.gz \ && cp -R /out/records /out/source/records \ && tar -czf /out/source/vendor.tar.gz vendor \ && cd /out/source && sha256sum *.tar.gz records/* > SHA256SUMS FROM scratch AS source LABEL io.thepeoples.hardened.build-owner="hardened-batch4" COPY --from=build /out/source/ / FROM scratch ARG RUST_IMAGE COPY --from=build --chown=65532:65532 /out/rootfs/ / COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=build --chmod=0755 /out/authentik /authentik COPY --from=build /out/records/ /usr/share/tp-hardened/authentik-proxy/ USER 65532:65532 WORKDIR / ENV TMPDIR=/dev/shm/ \ RUST_BACKTRACE=full EXPOSE 9000 9300 9443 HEALTHCHECK --interval=5s --retries=20 --start-period=3s CMD ["/authentik", "healthcheck", "proxy"] ENTRYPOINT ["/authentik", "proxy"] LABEL org.opencontainers.image.version="2026.8.4" \ org.opencontainers.image.source="https://github.com/goauthentik/authentik" \ org.opencontainers.image.revision="410f46e5cf18f97a1f0056b30984a145242df55d" \ org.opencontainers.image.licenses="MIT" \ io.thepeoples.hardened.upstream="ghcr.io/goauthentik/proxy:2026.8.4@sha256:70bd1eb19dfb0d15efa12f2d3377a7dd2655a2aca06ffb8e221199ae323a6e57" \ io.thepeoples.hardened.ladder="b+minimize" \ io.thepeoples.hardened.toolchain="${RUST_IMAGE}" \ io.thepeoples.hardened.source-status="upstream release tarball plus this Containerfile and recorded crate vendor"