Skip to content

Commit d868822

Browse files
committed
fix(runtime): gate DHI mirrors by supported architecture
1 parent 23557cd commit d868822

14 files changed

Lines changed: 59 additions & 26 deletions

File tree

.github/workflows/mirror-hardened-images.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,13 @@ jobs:
3030
target: ghcr.io/terion-name/terrarium-dhi-oauth2-proxy:7.15.2-debian13
3131
package: terrarium-dhi-oauth2-proxy
3232
digest: sha256:8f4e89762735e7ec7c3f1bbdd5da4dcd55358db8c3278bfbc2e46a7f86ab7d9e
33-
arches: amd64,arm64
33+
arches: amd64
3434
- name: postgres
3535
source: dhi.io/postgres:17.9-alpine3.22-fips@sha256:ae0f0ac1f942ff7898bb217e599cc488b5c7a2611a0957daae44c00584a59714
3636
target: ghcr.io/terion-name/terrarium-dhi-postgres:17.9-alpine3.22-fips
3737
package: terrarium-dhi-postgres
3838
digest: sha256:ae0f0ac1f942ff7898bb217e599cc488b5c7a2611a0957daae44c00584a59714
39-
arches: amd64,arm64
39+
arches: amd64
4040
env:
4141
REGISTRY_AUTH_FILE: /tmp/terrarium-containers-auth.json
4242
HAS_DOCKERHUB_CREDS: ${{ secrets.DOCKERHUB_USERNAME != '' && secrets.DOCKERHUB_TOKEN != '' }}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Terrarium provisions the host with:
4444
- [OpenZFS](https://github.com/openzfs/zfs)
4545
- [sanoid and syncoid](https://github.com/jimsalterjrs/sanoid)
4646
- [Traefik](https://github.com/traefik/traefik) with the built-in dashboard for public management endpoints
47-
- [oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) for management OIDC gatekeeping, preferring Docker Hardened Images directly when registry credentials are present and Terrarium's GHCR mirror otherwise
47+
- [oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) for management OIDC gatekeeping, preferring supported Docker Hardened Images directly when registry credentials are present and Terrarium's GHCR mirror otherwise
4848
- Optional self-hosted [ZITADEL](https://github.com/zitadel/zitadel) at `auth.<domain>`, running as a Terrarium-managed LXD system instance
4949
- External OIDC issuer support when you do not want to self-host the IDP
5050
- [devsec.hardening](https://github.com/dev-sec/ansible-collection-hardening) OS and SSH hardening

ansible/roles/idp_zitadel/defaults/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ terrarium_zitadel_version: v4.13.0
1313
terrarium_docker_registry_config_path: /root/.docker/config.json
1414
terrarium_docker_hardened_images: auto
1515
terrarium_docker_hardened_image_mirrors: true
16+
terrarium_docker_hardened_image_arch_supported: "{{ (ansible_architecture | default('x86_64')) in ['x86_64', 'amd64'] }}"
1617
terrarium_zitadel_postgres_image: ""
1718
terrarium_zitadel_postgres_image_hardened: "dhi.io/postgres:17.9-alpine3.22-fips@sha256:ae0f0ac1f942ff7898bb217e599cc488b5c7a2611a0957daae44c00584a59714"
1819
terrarium_zitadel_postgres_image_mirror: "ghcr.io/terion-name/terrarium-dhi-postgres:17.9-alpine3.22-fips@sha256:ae0f0ac1f942ff7898bb217e599cc488b5c7a2611a0957daae44c00584a59714"

ansible/roles/idp_zitadel/tasks/main.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,16 +179,20 @@
179179
else (
180180
terrarium_zitadel_postgres_image_hardened
181181
if (
182-
(terrarium_docker_hardened_images | string | lower) in ['true', 'yes', '1']
183-
or (
184-
(terrarium_docker_hardened_images | string | lower) == 'auto'
185-
and (terrarium_zitadel_docker_registry_config.stat.exists | default(false))
182+
(terrarium_docker_hardened_image_arch_supported | bool)
183+
and (
184+
(terrarium_docker_hardened_images | string | lower) in ['true', 'yes', '1']
185+
or (
186+
(terrarium_docker_hardened_images | string | lower) == 'auto'
187+
and (terrarium_zitadel_docker_registry_config.stat.exists | default(false))
188+
)
186189
)
187190
)
188191
else (
189192
terrarium_zitadel_postgres_image_mirror
190193
if (
191-
(terrarium_docker_hardened_images | string | lower) not in ['false', 'no', '0']
194+
(terrarium_docker_hardened_image_arch_supported | bool)
195+
and (terrarium_docker_hardened_images | string | lower) not in ['false', 'no', '0']
192196
and (terrarium_docker_hardened_image_mirrors | string | lower) in ['true', 'yes', '1', 'auto']
193197
)
194198
else terrarium_zitadel_postgres_image_fallback

ansible/roles/oauth2_proxy/defaults/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ terrarium_oauth2_proxy_dir: "{{ terrarium_state_dir }}/oauth2-proxy"
33
terrarium_docker_registry_config_path: /root/.docker/config.json
44
terrarium_docker_hardened_images: auto
55
terrarium_docker_hardened_image_mirrors: true
6+
terrarium_docker_hardened_image_arch_supported: "{{ (ansible_architecture | default('x86_64')) in ['x86_64', 'amd64'] }}"
67
terrarium_oauth2_proxy_image: ""
78
terrarium_oauth2_proxy_image_hardened: "dhi.io/oauth2-proxy:7.15.2-debian13@sha256:8f4e89762735e7ec7c3f1bbdd5da4dcd55358db8c3278bfbc2e46a7f86ab7d9e"
89
terrarium_oauth2_proxy_image_mirror: "ghcr.io/terion-name/terrarium-dhi-oauth2-proxy:7.15.2-debian13@sha256:8f4e89762735e7ec7c3f1bbdd5da4dcd55358db8c3278bfbc2e46a7f86ab7d9e"

ansible/roles/oauth2_proxy/tasks/main.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,20 @@
4242
else (
4343
terrarium_oauth2_proxy_image_hardened
4444
if (
45-
(terrarium_docker_hardened_images | string | lower) in ['true', 'yes', '1']
46-
or (
47-
(terrarium_docker_hardened_images | string | lower) == 'auto'
48-
and (terrarium_oauth2_proxy_docker_registry_config.stat.exists | default(false))
45+
(terrarium_docker_hardened_image_arch_supported | bool)
46+
and (
47+
(terrarium_docker_hardened_images | string | lower) in ['true', 'yes', '1']
48+
or (
49+
(terrarium_docker_hardened_images | string | lower) == 'auto'
50+
and (terrarium_oauth2_proxy_docker_registry_config.stat.exists | default(false))
51+
)
4952
)
5053
)
5154
else (
5255
terrarium_oauth2_proxy_image_mirror
5356
if (
54-
(terrarium_docker_hardened_images | string | lower) not in ['false', 'no', '0']
57+
(terrarium_docker_hardened_image_arch_supported | bool)
58+
and (terrarium_docker_hardened_images | string | lower) not in ['false', 'no', '0']
5559
and (terrarium_docker_hardened_image_mirrors | string | lower) in ['true', 'yes', '1', 'auto']
5660
)
5761
else terrarium_oauth2_proxy_image_fallback

ansible/site.yml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
terrarium_docker_registry_config_path: /root/.docker/config.json
5353
terrarium_docker_hardened_images: auto
5454
terrarium_docker_hardened_image_mirrors: true
55+
terrarium_docker_hardened_image_arch_supported: "{{ ansible_architecture in ['x86_64', 'amd64'] }}"
5556
terrarium_oauth2_proxy_image: ""
5657
terrarium_oauth2_proxy_image_hardened: "dhi.io/oauth2-proxy:7.15.2-debian13@sha256:8f4e89762735e7ec7c3f1bbdd5da4dcd55358db8c3278bfbc2e46a7f86ab7d9e"
5758
terrarium_oauth2_proxy_image_mirror: "ghcr.io/terion-name/terrarium-dhi-oauth2-proxy:7.15.2-debian13@sha256:8f4e89762735e7ec7c3f1bbdd5da4dcd55358db8c3278bfbc2e46a7f86ab7d9e"
@@ -147,22 +148,33 @@
147148
path: "{{ terrarium_docker_registry_config_path }}"
148149
register: terrarium_docker_registry_config
149150
no_log: true
151+
- name: Assert hardened images support this host architecture
152+
ansible.builtin.assert:
153+
that:
154+
- terrarium_docker_hardened_image_arch_supported | bool
155+
fail_msg: "Pinned Docker Hardened Images currently support Terrarium's selected oauth2-proxy and Postgres variants on linux/amd64 only. Use terrarium_docker_hardened_images: auto or false, or set explicit image overrides, on this host architecture."
156+
when:
157+
- (terrarium_docker_hardened_images | string | lower) in ['true', 'yes', '1']
150158
- name: Resolve hardened image preference
151159
ansible.builtin.set_fact:
152160
terrarium_docker_hardened_images_effective: >-
153161
{{
154-
(terrarium_docker_hardened_images | string | lower) in ['true', 'yes', '1']
155-
or (
156-
(terrarium_docker_hardened_images | string | lower) == 'auto'
157-
and terrarium_docker_registry_config.stat.exists
162+
(terrarium_docker_hardened_image_arch_supported | bool)
163+
and (
164+
(terrarium_docker_hardened_images | string | lower) in ['true', 'yes', '1']
165+
or (
166+
(terrarium_docker_hardened_images | string | lower) == 'auto'
167+
and terrarium_docker_registry_config.stat.exists
168+
)
158169
)
159170
}}
160171
no_log: true
161172
- name: Resolve hardened image mirror preference
162173
ansible.builtin.set_fact:
163174
terrarium_docker_hardened_image_mirrors_effective: >-
164175
{{
165-
(terrarium_docker_hardened_images | string | lower) not in ['false', 'no', '0']
176+
(terrarium_docker_hardened_image_arch_supported | bool)
177+
and (terrarium_docker_hardened_images | string | lower) not in ['false', 'no', '0']
166178
and (terrarium_docker_hardened_image_mirrors | string | lower) in ['true', 'yes', '1', 'auto']
167179
}}
168180
no_log: true

docs/getting-started/installation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ Terrarium also verifies the most failure-prone integrations while you configure
9999
Terrarium pins the oauth2-proxy and local ZITADEL Postgres images by digest. The default source order is:
100100

101101
- upstream Docker Hardened Images from `dhi.io` when Docker registry credentials exist on the host
102-
- Terrarium's GHCR mirror of those same DHI multi-arch indexes when upstream DHI credentials are not present
102+
- Terrarium's GHCR mirror of those same DHI image indexes when upstream DHI credentials are not present
103103
- the pinned public upstream images when `terrarium_docker_hardened_images` or `terrarium_docker_hardened_image_mirrors` is disabled
104104

105-
The GHCR mirror is refreshed by CI with Docker Hub credentials, copies every platform in the pinned index, and verifies the copied index and required `linux/amd64` and `linux/arm64` manifests before publishing.
105+
The GHCR mirror is refreshed by CI with Docker Hub credentials, copies every platform in the pinned index, and verifies the copied index and required platform manifests before publishing. The current pinned DHI variants are linux/amd64 catalog images; non-amd64 hosts use the pinned public fallbacks unless you provide explicit image overrides.
106106

107107
In interactive mode, failed verification sends you back to the relevant prompts. In non-interactive mode, install exits with an error instead of persisting broken settings.
108108

docs/reference/services-and-endpoints.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ Terrarium provisions the host with:
1111
- [OpenZFS](https://github.com/openzfs/zfs)
1212
- [sanoid and syncoid](https://github.com/jimsalterjrs/sanoid)
1313
- [Traefik](https://github.com/traefik/traefik) with the built-in dashboard
14-
- [oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy), preferring Docker Hardened Images directly when registry credentials are present and Terrarium's GHCR mirror otherwise
15-
- Optional self-hosted [ZITADEL](https://github.com/zitadel/zitadel), running as the `terrarium-idp` LXD system instance with a Postgres sidecar that uses the same upstream-DHI, GHCR-mirror, public-fallback image order
14+
- [oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy), preferring supported Docker Hardened Images directly when registry credentials are present and Terrarium's GHCR mirror otherwise
15+
- Optional self-hosted [ZITADEL](https://github.com/zitadel/zitadel), running as the `terrarium-idp` LXD system instance with a Postgres sidecar that uses the same supported upstream-DHI, GHCR-mirror, public-fallback image order
1616
- Open vSwitch/OVN for the Terrarium LXD workload network
1717
- [devsec.hardening](https://github.com/dev-sec/ansible-collection-hardening)
1818

scripts/terrarium-traefik-sync.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ const OAUTH2_PROXY_COOKIE_SECRET_PATH = "/etc/terrarium/secrets/oauth2_proxy_coo
1313
const ROUTE_AUTH_DIR = "/var/lib/terrarium/oauth2-proxy-routes";
1414
const ROUTE_AUTH_COMPOSE_PATH = `${ROUTE_AUTH_DIR}/docker-compose.yml`;
1515
const ROUTE_AUTH_BASE_PORT = 4181;
16-
const DEFAULT_OAUTH2_PROXY_IMAGE =
16+
const OAUTH2_PROXY_MIRROR_IMAGE =
1717
"ghcr.io/terion-name/terrarium-dhi-oauth2-proxy:7.15.2-debian13@sha256:8f4e89762735e7ec7c3f1bbdd5da4dcd55358db8c3278bfbc2e46a7f86ab7d9e";
18+
const OAUTH2_PROXY_FALLBACK_IMAGE =
19+
"quay.io/oauth2-proxy/oauth2-proxy:v7.15.2@sha256:aa0bd8dd5ab0c78e4c91c92755ad573a5f92241f88138b4141b8ec803463b4fd";
20+
const DEFAULT_OAUTH2_PROXY_IMAGE = process.arch === "x64" ? OAUTH2_PROXY_MIRROR_IMAGE : OAUTH2_PROXY_FALLBACK_IMAGE;
1821
const OAUTH2_PROXY_UID = 65532;
1922
const OAUTH2_PROXY_GID = 65532;
2023
const ROUTE_AUTH_READY_ATTEMPTS = 12;

0 commit comments

Comments
 (0)