Two open Dependabot alerts, both against github.com/go-git/go-git/v6, a
transitive dependency of github.com/pulumi/pulumi/sdk/v3 by way of
common/workspace:
CVE-2026-71556 (high, 7.1) worktree operations may follow symlinks,
allowing writes outside the worktree
CVE-2026-71557 (medium, 6.3) malicious reference names may resolve
outside the reference storage
Both are fixed in v6.0.0-alpha.5. The Pulumi SDK is already at its latest
release (v3.258.0) and still requires alpha.4, so bumping the direct
dependency does not help; an explicit minimum-version entry is the
remedy. go-billy comes along as a consequence.
Also pins toolchain go1.26.6. govulncheck reported six reachable
standard-library vulnerabilities from building on go1.26.4 -- ASN.1, TLS,
net/url, net/http and os -- all fixed in 1.26.5/1.26.6. Dependabot does
not track the Go standard library, so nothing alerted on these, but they
were reachable from pulumi.Run and dns.LookupManagedZone. Pinning the
floor in go.mod means every build gets a patched stdlib rather than
whatever the build host happens to have.
govulncheck now reports no vulnerabilities.
Not addressed, deliberately: GO-2026-5932 flags golang.org/x/crypto/openpgp
as unmaintained and unsafe by design. It has no fixed version, and our
code does not call it. Upgrading x/crypto to v0.55.0 was tried and does
not clear it, so that change was dropped to keep this diff minimal.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Self-hosted Gitea on a single e2-small AlmaLinux 10 VM in us-east1,
serving gitea.jasonmross.dev.
Runtime is podman quadlets (systemd .container/.network/.volume units).
Both images are built on Debian 13: Gitea from a GPG-verified release
binary, and Caddy from an xcaddy build carrying the Google Cloud DNS
provider (ACME DNS-01) and the Coraza WAF with the OWASP CRS embedded.
Infrastructure is a Pulumi program in Go against a GCS state backend.
Cloud Build handles CI: a push trigger for images, one for infra, and a
weekly scheduled rebuild. Everything Cloud Build touches is 2nd gen.
Notable design decisions, each documented where it lives:
- Quadlets track a floating :prod tag. AutoUpdate=registry compares
digests for a tag, so a digest-pinned image silently disables
auto-updates.
- Git transport and LFS bypass the WAF. With the bypass removed, a plain
git push returns 403 -- packfiles trip CRS reliably.
- gitea:wafMode drives both SecRuleEngine and whether the fail2ban jail
acting on WAF verdicts exists. Banning on detections that were never
blocks would turn a tuning false positive into an nftables ban.
- fail2ban bans at the nftables prerouting hook. Published container
ports are DNAT'd and never traverse INPUT, where the stock actions
install their rules.
- The DNS zone, backup bucket, and Gitea signing secrets are not
Pulumi-owned, so pulumi destroy cannot take them with it.
- The podman subnet is pinned because it is what Gitea's
REVERSE_PROXY_TRUSTED_PROXIES names.
Three update layers: dnf5-automatic for the OS, podman-auto-update with
health-gated rollback for containers, and a weekly image rebuild that
gives the second layer something to pull.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>