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
19 changes: 11 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

# Base image pinned by digest so builds are reproducible. Override
# BASE_IMAGE to rebuild on a newer base. hadolint ignore=DL3006
ARG BASE_IMAGE="ubuntu:26.04@sha256:3131b4cc82a783df6c9df078f86e01819a13594b865c2cad47bd1bca2b7063bb"
ARG BASE_IMAGE="ubuntu:26.04@sha256:f144425ff09be612d6d9ad965196e9cdc23dae1f42110a8a11a3e9a8198759f7"
ARG VERSION="dev"
ARG COMMIT=""

Expand All @@ -66,9 +66,10 @@ LABEL openvpn.features="DCO,TLS1.3,AEAD,4G-optimized,OIDC-SSO"

ARG DEBIAN_FRONTEND=noninteractive
ARG OPENVPN_MIN_VERSION="2.7.0"
ARG OPENVPN_AUTH_OAUTH2_VERSION="2.2.0"
ARG OPENVPN_AUTH_OAUTH2_SHA256_AMD64="a4871c30666afd5cd6504501ae83653dfcb2c31a147f3450ba8092a471203e3c"
ARG OPENVPN_AUTH_OAUTH2_SHA256_ARM64="d33fdf6b8a5f701f689bd427df476209f2f8b70ff96b726a2ec67fd5f64f9508"
ARG OPENVPN_AUTH_OAUTH2_VERSION="2.2.2"
# Public release checksums. BuildKit's SecretsUsedInArgOrEnv check flags these two only for the AUTH in their name.
ARG OPENVPN_AUTH_OAUTH2_SHA256_AMD64="56bb8edcd61dfd559af188e1bd51653cfd184fff17c599529b78a1cf0e041164"
ARG OPENVPN_AUTH_OAUTH2_SHA256_ARM64="f9eecf48b3c06b11607d402d71904db101f287734518fc08d1101e27030c157a"

# openvpn from the project's signed apt repo. The downloaded keyring must carry
# EXACTLY ONE primary key and its fingerprint must be the pinned one, so neither
Expand Down Expand Up @@ -154,8 +155,10 @@ RUN ARCH=$(dpkg --print-architecture) \
# the lockfile; regenerate on any uv.lock change with:
# uv export --frozen --no-dev --no-emit-project --extra otel \
# --format requirements-txt -o requirements-docker.txt
# The image has no venv by design, so pip's warning about installing as root
# into the system site-packages is switched off.
COPY requirements-docker.txt /tmp/requirements-docker.txt
RUN pip3 install --no-cache-dir --break-system-packages \
RUN pip3 install --no-cache-dir --break-system-packages --root-user-action=ignore \
--require-hashes -r /tmp/requirements-docker.txt \
&& rm /tmp/requirements-docker.txt

Expand All @@ -166,9 +169,9 @@ ENV ENV_PREFIX=CULVERT
# There is no apt repo, and the upstream container image's binary links
# against a glibc newer than the base image's, so the tarball is the only
# option that runs here. BSD-3-Clause Rust binary.
ARG WSTUNNEL_VERSION="10.6.2"
ARG WSTUNNEL_SHA256_AMD64="db6064cca0515b67f8652e201cff8e27553b8cbb7216b2e19241311e34868e6e"
ARG WSTUNNEL_SHA256_ARM64="26bb36b856948255bec7cd71a39df5f8912acdd7a47a9ccd4044a9b80ced108d"
ARG WSTUNNEL_VERSION="10.7.1"
ARG WSTUNNEL_SHA256_AMD64="fa842ed53fbb14b1c69cd98829f9895d7f8a6b0d562c57c1175851a52cea9ea2"
ARG WSTUNNEL_SHA256_ARM64="99f9506d01d1b4073254609600ec5056dab8dc58aec75c32f6eb0508335a8fd2"
RUN ARCH=$(dpkg --print-architecture) \
&& case "${ARCH}" in \
amd64) WSTUNNEL_SHA256="${WSTUNNEL_SHA256_AMD64}" ;; \
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.test-client
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
# Base image: Override with --build-arg UBUNTU_VERSION=xx.xx
# Default: the same 26.04 LTS digest the server image pins.

ARG UBUNTU_VERSION=26.04@sha256:3131b4cc82a783df6c9df078f86e01819a13594b865c2cad47bd1bca2b7063bb
ARG UBUNTU_VERSION=26.04@sha256:f144425ff09be612d6d9ad965196e9cdc23dae1f42110a8a11a3e9a8198759f7
FROM ubuntu:${UBUNTU_VERSION}

LABEL maintainer="HyperI <opensource@hyperi.io>"
Expand Down
4 changes: 2 additions & 2 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,10 @@ services:
# Disable: Set WATCHTOWER_ENABLED=false in .env
watchtower:
# Note: containrrr/watchtower was archived Dec 2025 and broken with Docker 29+
# Using maintained fork (pinned): https://github.com/nickfedor/watchtower
# Using maintained fork (pinned): https://github.com/nicholas-fedor/watchtower
# SECURITY: mounting docker.sock hands this container root-equivalent
# control of the HOST - keep this profile opt-in and the tag pinned.
image: nickfedor/watchtower:1.20.3
image: nickfedor/watchtower:1.22.3@sha256:2f8f2a9bd21a195b3b650409532a20f6aada8ef5834f00d0d7a999dee0779a81
container_name: watchtower
restart: unless-stopped
profiles:
Expand Down
2 changes: 1 addition & 1 deletion docs/scalo-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ In `pyproject.toml` (granular extras - one per backend culvert actually
uses, not the blanket `[secrets]`):

```toml
dependencies = ["scalo[metrics,secrets-vault,secrets-aws]>=2.29.11,<3"]
dependencies = ["scalo[metrics,secrets-vault,secrets-aws]>=2.31.1,<3"]
```

The container installs the full runtime tree (scalo + those extras +
Expand Down
14 changes: 7 additions & 7 deletions docs/supply-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ GitHub releases during image build:

| Dependency | Source | Pinned version |
|------------|--------|----------------|
| Base image | `ubuntu:24.04` | pinned by `sha256` digest in `BASE_IMAGE` |
| `openvpn-auth-oauth2` | [github.com/jkroepke/openvpn-auth-oauth2](https://github.com/jkroepke/openvpn-auth-oauth2) | `2.2.0`, `sha256`-verified per arch |
| `wstunnel` | [github.com/erebe/wstunnel](https://github.com/erebe/wstunnel) | `10.6.2`, `sha256`-verified per arch |
| Base image | `ubuntu:26.04` | pinned by `sha256` digest in `BASE_IMAGE` |
| `openvpn-auth-oauth2` | [github.com/jkroepke/openvpn-auth-oauth2](https://github.com/jkroepke/openvpn-auth-oauth2) | `2.2.2`, `sha256`-verified per arch |
| `wstunnel` | [github.com/erebe/wstunnel](https://github.com/erebe/wstunnel) | `10.7.1`, `sha256`-verified per arch |
| `openvpn` (server) | [build.openvpn.net](https://build.openvpn.net) (official APT repo) | stable channel, 2.7.x+ |
| `easy-rsa` | Ubuntu archive | System package (from digest-pinned base) |
| `stunnel4` | Ubuntu archive | System package (from digest-pinned base) |
| `scalo` (HyperI-own) | PyPI | image installs `==2.29.11` from the hash-pinned `requirements-docker.txt`; source range is `>=2.29.11,<3`; ships immediately (no cooldown); `uv.lock` pins the dev/CI tree with hashes |
| `scalo` (HyperI-own) | PyPI | image installs `==2.31.1` from the hash-pinned `requirements-docker.txt`; source range is `>=2.31.1,<3`; ships immediately (no cooldown); `uv.lock` pins the dev/CI tree with hashes |

External dependencies track "latest stable released at least 7 days ago"
-- the org `minimumReleaseAge` cooldown, a buffer against fresh-release
Expand Down Expand Up @@ -62,9 +62,9 @@ downloaded binaries are `sha256`-verified per architecture before
install:

```dockerfile
ARG BASE_IMAGE="ubuntu:24.04@sha256:..." # base image pinned by digest
ARG OPENVPN_AUTH_OAUTH2_VERSION="2.2.0" # + SHA256_AMD64 / SHA256_ARM64
ARG WSTUNNEL_VERSION="10.6.2" # + SHA256_AMD64 / SHA256_ARM64
ARG BASE_IMAGE="ubuntu:26.04@sha256:..." # base image pinned by digest
ARG OPENVPN_AUTH_OAUTH2_VERSION="2.2.2" # + SHA256_AMD64 / SHA256_ARM64
ARG WSTUNNEL_VERSION="10.7.1" # + SHA256_AMD64 / SHA256_ARM64
```

## Updating Dependencies
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ license = {text = "Apache-2.0"}
# [secrets] extra would drag in ansible-vault + GCP + Azure (~180MB) that
# no culvert backend uses.
dependencies = [
"scalo[metrics,secrets-vault,secrets-aws]>=2.29.14,<3",
"scalo[metrics,secrets-vault,secrets-aws]>=2.31.1,<3",
# Imported directly in lib/oauth2.py (yaml.safe_dump) and for the profile
# cascade; also a transitive dep of dynaconf, pinned here so it is declared.
"pyyaml>=6,<7",
Expand All @@ -43,7 +43,7 @@ dev = [
"cryptography>=50,<51",
# Deployment-contract generators (Helm chart, compose fragment). Pulls in
# pydantic. Dev/CI-only: culvert's runtime never imports scalo.deployment.
"scalo[deployment]>=2.29.14,<3",
"scalo[deployment]>=2.31.1,<3",
]

# culvert is distributed as a container image, not a Python package.
Expand All @@ -59,7 +59,7 @@ extra-paths = ["scripts"]

[tool.ruff]
line-length = 88
target-version = "py312"
target-version = "py314"

[tool.ruff.lint]
select = ["E", "F", "I", "N", "UP"]
Expand Down
Loading
Loading