infra(cx2-5): DNS auth/NetPol substrate, air-gap landing, arm64 ARC runner + tenant landing manifests
- fc-dns: add OnePasswordItem CRD for DNS API keys + NetworkPolicy for Phase 0 auth hardening; bump dns-web image tag - fc-landing: rewrite landing HTML to remove CDN dependencies (air-gap safe); add preview.html standalone preview - github-runner: add TOOLCACHE_ARCH to install-ruby-toolcache.sh for arm64 support; add Dockerfile.arm64 for arm64 ARC runner image - docs/gx10-tenant-landing: per-user Deployment+IngressRoute manifests (andrew/dustin/erik/fit/matt) + CUTOVER-RUNBOOK.md Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,20 @@ metadata:
|
||||
spec:
|
||||
itemPath: "vaults/IAmWorkin/items/dns-oidc-client"
|
||||
---
|
||||
# Service X-Api-Key for the cert-manager ACME webhook -> dns-web call path
|
||||
# (Phase 0 auth-flip). The 1Password operator resolves this item into a K8s
|
||||
# Secret of the same name; the `api_key` field becomes Secret key `api_key`.
|
||||
# dns-web reads it as FlowerCore__Auth__ApiKey (FcApiKey scheme, Operator
|
||||
# principal); dns-acme-webhook sends it as the X-Api-Key header. Dormant while
|
||||
# FlowerCore__Auth__Enabled=false (all policies allow-all).
|
||||
apiVersion: onepassword.com/v1
|
||||
kind: OnePasswordItem
|
||||
metadata:
|
||||
name: dns-api-keys
|
||||
namespace: fc-dns
|
||||
spec:
|
||||
itemPath: "vaults/IAmWorkin/items/FlowerCore DNS API Keys"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
@@ -111,7 +125,7 @@ spec:
|
||||
fsGroup: 1654
|
||||
containers:
|
||||
- name: dns-web
|
||||
image: localhost/fc-dns-web:v20260614-wave5-isolation-6124856
|
||||
image: localhost/fc-dns-web:v20260615-phase0-hybrid-f77fb94
|
||||
imagePullPolicy: Never
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
@@ -148,6 +162,16 @@ spec:
|
||||
name: dns-oidc-client
|
||||
key: client_secret
|
||||
optional: true
|
||||
# Service X-Api-Key accepted by the FcApiKey scheme. The standard
|
||||
# key maps to an Operator principal (satisfies OperatorPolicy on the
|
||||
# ACME present/cleanup endpoints). optional:true keeps the pod
|
||||
# starting if the 1P operator has not yet produced the secret.
|
||||
- name: FlowerCore__Auth__ApiKey
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: dns-api-keys
|
||||
key: api_key
|
||||
optional: true
|
||||
- name: FlowerCore__Auth__Enabled
|
||||
value: "false"
|
||||
- name: FlowerCore__Auth__Oidc__Enabled
|
||||
@@ -209,6 +233,54 @@ spec:
|
||||
targetPort: 5320
|
||||
type: ClusterIP
|
||||
---
|
||||
# Defense-in-depth ingress isolation for dns-web (Phase 0). NetworkPolicy is
|
||||
# L3/L4 and cannot path-scope, so it CANNOT restrict only present/cleanup — the
|
||||
# real control on those endpoints is the X-Api-Key + OperatorPolicy. This policy
|
||||
# simply confines who may reach dns-web:5320 to known network zones without
|
||||
# breaking any live path:
|
||||
# * Traefik pods -> UI/API on dns.iamworkin.lan
|
||||
# * same fc-dns namespace -> dns-acme-webhook -> present/cleanup
|
||||
# * cluster pod CIDR (10.42/16) -> in-cluster Prometheus scrape, etc.
|
||||
# * node + LAN CIDRs -> kubelet probes, noc1 host-net Prometheus
|
||||
# Egress is intentionally left unrestricted: dns-web must reach pfSense
|
||||
# (diag_command.php / HTTPS), the K8s API, Authentik OIDC discovery, step-ca,
|
||||
# and DNS — over-tight egress would break the provider + auth paths.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: dns-web-ingress-isolation
|
||||
namespace: fc-dns
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: dns-web
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: traefik-system
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: traefik
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: fc-dns
|
||||
- ipBlock:
|
||||
cidr: 10.42.0.0/16
|
||||
- ipBlock:
|
||||
cidr: 10.0.56.0/24
|
||||
- ipBlock:
|
||||
cidr: 10.0.57.0/24
|
||||
- ipBlock:
|
||||
cidr: 10.0.58.0/24
|
||||
- ipBlock:
|
||||
cidr: 10.0.68.0/27
|
||||
ports:
|
||||
- port: 5320
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
@@ -303,7 +375,7 @@ spec:
|
||||
fsGroup: 1654
|
||||
containers:
|
||||
- name: dns-acme-webhook
|
||||
image: localhost/fc-dns-acme-webhook:v20260614-wave5-isolation-6124856
|
||||
image: localhost/fc-dns-acme-webhook:v20260615-phase0-hybrid-f77fb94
|
||||
imagePullPolicy: Never
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
@@ -322,6 +394,16 @@ spec:
|
||||
value: /tls/tls.key
|
||||
- name: FlowerCore__Dns__AcmeWebhook__ServiceBaseUrl
|
||||
value: http://dns-web:5320
|
||||
# X-Api-Key sent to dns-web on present/cleanup so the webhook
|
||||
# authenticates as an Operator once dns-web auth is enabled.
|
||||
# optional:true keeps the webhook starting before the 1P secret
|
||||
# exists; the header is simply omitted when the value is empty.
|
||||
- name: FlowerCore__Dns__AcmeWebhook__ApiKey
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: dns-api-keys
|
||||
key: api_key
|
||||
optional: true
|
||||
- name: FlowerCore__Dns__AcmeWebhook__GroupName
|
||||
value: acme.flowercore.io
|
||||
- name: FlowerCore__Dns__AcmeWebhook__SolverName
|
||||
|
||||
Reference in New Issue
Block a user