- Shell 52.4%
- Dockerfile 47.6%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
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> |
||
| .forgejo/workflows | ||
| test | ||
| Dockerfile | ||
| README.md | ||
hitoma-stepca
smallstep/step-ca and the step CLI rebuilt from their latest releases with the current stable Go (golang:alpine) and the latest versions of commonly-flagged modules (golang.org/x/*, grpc, go-jose, pgx, otel, go-pkcs12), on a freshly upgraded alpine:latest, so CVE fixes land without waiting for an upstream image. A drop-in replacement for smallstep/step-ca: same entrypoint (taken from the release tag), step user (uid/gid 1000), /home/step volume, environment variables and healthcheck.
Differences from upstream:
- No
step-kms-plugin, which is only needed for CAs whose keys live in a cloud KMS, an HSM or a YubiKey (kmsinca.json). Software keys on disk don't need it. - No
curlorjqin the runtime image (onlybash,ca-certificatesandtzdata).
docker pull forgejo.hitoma.com/root/hitoma-stepca:latest
Tests
Every build has to pass both of these before it's pushed:
- test/verify-image.sh, which needs no network:
- the image runs as the
stepuser (uid/gid 1000) step-caandstepreport the releases they were built from, andstep-camatches the image's version labelcurlandjqaren't in the image
- the image runs as the
- test/smoke.sh, which lets the entrypoint initialise a throwaway CA with ACME:
- the CA serves on :443 as the non-root user, with Docker's unprivileged low-port allowance turned off, so it relies on the
setcapfrom the build step ca health(the image's healthcheck) passes- the step CLI gets a certificate issued and verifies it against the CA's root
- another container fetches the ACME directory over TLS, trusting only that root
- the logs show no errors
- the CA serves on :443 as the non-root user, with Docker's unprivileged low-port allowance turned off, so it relies on the
Both run locally too: test/verify-image.sh IMAGE, then test/smoke.sh IMAGE. Build with BuildKit (docker buildx): the legacy builder drops the file capability on COPY, and the :443 check then fails.
CI
.forgejo/workflows/build.yml builds on every push to main, weekly (Monday 06:47 UTC, without cache, to pick up Go, module and Alpine updates), and on manual dispatch. Dispatch takes optional ca_version and cli_version inputs to build specific upstream tags; otherwise the latest GitHub releases are used. Pull requests are built and tested but not pushed. The workflow only resolves the upstream tags. Building, testing, scanning and pushing happen in the shared hitoma-image-ci pipeline.
Tags: latest, the step-ca release (e.g. v0.30.2), 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. The run fails when there are fixable HIGH or CRITICAL findings, and a failed run emails whoever triggered it (the repo owner for scheduled runs). The image is still pushed, but the red run shows that a module bump or rebuild is needed.
Go isn't pinned to the releases' go.mod minimums because the latest golang.org/x modules only support the two newest Go releases. The modules bumped to @latest are listed in BUMP_MODULES in the Dockerfile; add to it when a scan flags another one. If a module bump breaks the build, the job fails and latest stays on the last good image.
Setup:
- Repository secrets
REGISTRY_USERandREGISTRY_TOKEN(a Forgejo access token withwrite:packagescope). - A Forgejo runner with the
dockerlabel whose job containers can reach a Docker daemon, such as adocker:dindsidecar throughDOCKER_HOST. - Actions enabled on the repository (Settings → Units → Actions).