No description
  • Dockerfile 48.6%
  • Shell 26.4%
  • Python 25%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Shawn McNaughton 47453639c7
All checks were successful
Build and publish image / upstream (push) Successful in 2s
Build and publish image / image (push) Successful in 0s
Describe the runner's Docker daemon accurately
Jobs reach a docker:dind sidecar over DOCKER_HOST rather than a host
Docker socket.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 23:15:18 -04:00
.forgejo/workflows Queue overlapping builds instead of running them together 2026-10-12 22:23:26 -04:00
test Describe the runner's Docker daemon accurately 2026-10-12 23:15:18 -04:00
.gitignore Rebuild authentik on a Wolfi userland 2026-10-12 16:34:29 -04:00
Dockerfile Rebuild authentik on a Wolfi userland 2026-10-12 16:34:29 -04:00
README.md Describe the runner's Docker daemon accurately 2026-10-12 23:15:18 -04:00

hitoma-authentik

vulnerabilities

goauthentik/authentik moved onto a Wolfi userland. It's built from the latest release in a pinned series. Upstream's server image is based on Debian trixie and has around 60 HIGH/CRITICAL findings in OS packages that Authentik doesn't use. This image takes the finished app from ghcr.io/goauthentik/server and installs only the runtime libraries it links against, all from Wolfi. Differences from upstream:

  • Wolfi instead of Debian. No apt, util-linux or other Debian userland. Wolfi uses glibc, so upstream's compiled code runs unchanged.
  • Not FIPS. Python and OpenSSL come from Wolfi instead of upstream's FIPS builds of each.
  • Rebuilt native extensions. cryptography, lxml and xmlsec are compiled here against Wolfi's OpenSSL 4 and libxml2 2.15, at the versions in upstream's uv.lock. Upstream's builds target Debian's OpenSSL 3 and libxml2 2.13, which aren't binary-compatible with Wolfi's.
  • Patched Python packages. Packages with known fixes that upstream's lock doesn't have yet are bumped (SECURITY_OVERRIDES in the Dockerfile). Each override applies only while upstream's version is older, and the build log says when one can be removed. Upstream pins PyJWT exactly, so the PyJWT override goes against that pin.
  • No debug mode extras. With AUTHENTIK_DEBUGGER set, upstream installs debugging packages with apt and uv. Neither exists here.

Ports, volumes, environment variables, the authentik user (uid 1000), the entrypoint and the healthcheck all match upstream. This is a drop-in replacement for ghcr.io/goauthentik/server for both the server and worker commands, including a worker running as root.

docker pull forgejo.hitoma.com/root/hitoma-authentik:2026.8

Only the server image is rebuilt. The embedded outpost inside the server covers proxy and forward-auth. Standalone outposts (ghcr.io/goauthentik/proxy, ldap, radius, rac) still come from upstream.

Tests

Every build has to pass both of these before it's pushed:

  • test/verify-image.sh, which needs no database:
    • every native extension and the authentik binary find all their shared libraries
    • Python and cryptography load the same OpenSSL, and lxml and xmlsec the same libxml2
    • psycopg uses its C implementation
    • the root startup path can drop privileges with setpriv
  • test/smoke.sh, against Postgres, with the server and a root worker:
    • both containers become healthy, and the logs show no errors
    • the login page loads and the embedded outpost answers
    • passwords are checked, and an RS256 JWT round-trips (as in OIDC)
    • SAML metadata is signed, the signature verifies, and tampering is detected

Both run locally too: test/verify-image.sh IMAGE, then test/smoke.sh IMAGE.

CI

.forgejo/workflows/build.yml builds on every push to main, weekly (Monday 07:17 UTC, without cache, so Wolfi updates are picked up), and on manual dispatch. Dispatch takes an optional version input to build a specific release. Pull requests are built and tested but not pushed. The workflow only resolves the authentik version. Building, testing, scanning and pushing happen in the shared hitoma-image-ci pipeline.

  • Authentik version: the newest non-prerelease release in AUTHENTIK_SERIES (currently 2026.8). A new series is never picked up automatically, because it runs database migrations that can't be rolled back. Bump AUTHENTIK_SERIES in the workflow to move to it, after reading upstream's release notes.
  • Architecture: whatever the runner is. The image isn't built multi-arch.
  • Memory: native extensions build one at a time, so a builder with 2 GB of RAM is enough.

If a Wolfi update breaks a rebuilt extension, the build, verify or smoke step fails and nothing is pushed. latest stays on the last good image.

Tags: latest, the series (2026.8), the upstream release (e.g. 2026.8.3), YYYYMMDD, and sha-<short>.

Each build is scanned with Trivy after it passes the tests. Builds of main force-push the badge above and the full JSON report to the single-commit badges branch.

  • When the run fails: a fixable HIGH or CRITICAL finding fails the run, and a failed run emails whoever triggered it (the repo owner for scheduled runs). The image is still pushed, but the red run shows an update is needed. For a Python package, add the minimum fixed version to SECURITY_OVERRIDES.
  • What doesn't fail it: findings with no fix available are counted on the badge only.

Setup:

  • Repository secrets REGISTRY_USER and REGISTRY_TOKEN (a Forgejo access token with write:package scope).
  • A Forgejo runner with the docker label whose job containers can reach a Docker daemon, such as a docker:dind sidecar through DOCKER_HOST. The smoke test starts its own containers on that daemon.
  • Actions enabled on the repository (Settings → Units → Actions).