sso: fix vault OIDC bootstrap and render zot oidc config

This commit is contained in:
Brad Stein 2025-12-08 23:23:21 -03:00
parent c8254d6eec
commit dba4d270ff
5 changed files with 127 additions and 14 deletions

View File

@ -10,3 +10,4 @@ resources:
- middleware.yaml
- serverstransport.yaml
- oauth2-proxy-vault.yaml
- oidc-bootstrap-job.yaml

View File

@ -61,8 +61,8 @@ spec:
- --cookie-refresh=20m
- --cookie-expire=168h
- --insecure-oidc-allow-unverified-email=true
- --upstream=https://vault-ui.vault.svc.cluster.local:8200
- --ssl-insecure-skip-verify=true
# Vault UI is served over HTTP on the service endpoint.
- --upstream=http://vault.vault.svc.cluster.local:8200
- --http-address=0.0.0.0:4180
- --skip-provider-button=true
- --skip-jwt-bearer-tokens=true

View File

@ -0,0 +1,79 @@
# services/vault/oidc-bootstrap-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: vault-oidc-bootstrap
namespace: vault
labels:
app: vault-oidc-bootstrap
spec:
backoffLimit: 0
ttlSecondsAfterFinished: 86400
template:
metadata:
labels:
app: vault-oidc-bootstrap
spec:
restartPolicy: Never
containers:
- name: configure-oidc
image: hashicorp/vault:1.20.4
imagePullPolicy: IfNotPresent
env:
- name: VAULT_ADDR
value: http://vault.vault.svc.cluster.local:8200
- name: VAULT_TOKEN
valueFrom:
secretKeyRef:
name: vault-oidc-admin-token
key: token
- name: OIDC_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: oauth2-proxy-vault-oidc
key: client_secret
- name: VAULT_CLIENT_TIMEOUT
value: "30s"
command:
- /bin/sh
- -c
- |
set -euo pipefail
vault status
# Enable OIDC auth (idempotent)
vault auth enable oidc >/dev/null 2>&1 || vault auth tune -description="Keycloak OIDC" oidc
# Configure Keycloak OIDC
vault write auth/oidc/config \
oidc_discovery_url="https://sso.bstein.dev/realms/atlas" \
oidc_client_id="oauth2-proxy" \
oidc_client_secret="$OIDC_CLIENT_SECRET" \
default_role="admin" \
bound_issuer="https://sso.bstein.dev/realms/atlas" \
allowed_redirect_uris="https://secret.bstein.dev/ui/vault/auth/oidc/oidc/callback"
# Admin policy (wide permissions)
vault policy write vault-admin - <<'EOF'
path "*" {
capabilities = ["create", "read", "update", "delete", "list", "sudo"]
}
EOF
# Role mapping admin group -> vault-admin policy
cat >/tmp/role.json <<'EOF'
{
"user_claim": "sub",
"groups_claim": "groups",
"bound_audiences": "oauth2-proxy",
"allowed_redirect_uris": "https://secret.bstein.dev/ui/vault/auth/oidc/oidc/callback",
"claim_mappings": {
"email": "email",
"name": "name"
},
"token_policies": ["vault-admin"],
"oidc_scopes": ["profile", "email", "groups"],
"bound_claims": { "groups": ["admin"] }
}
EOF
vault write auth/oidc/role/admin @/tmp/role.json
echo "vault OIDC bootstrap complete"

View File

@ -20,20 +20,34 @@ data:
"realm": "zot-registry",
"compat": ["docker2s2"],
"auth": {
"htpasswd": { "path": "/etc/zot/htpasswd" }
"openid": {
"providers": [
{
"name": "keycloak",
"issuer": "https://sso.bstein.dev/realms/atlas",
"clientID": "zot",
"clientSecret": "__CLIENT_SECRET__",
"scopes": ["openid", "profile", "email", "groups"],
"redirectURL": "https://registry.bstein.dev/oidc/callback",
"adminGroup": "admin",
"groupClaim": "groups"
}
]
}
},
"externalUrl": "https://registry.bstein.dev",
"accessControl": {
"repositories": {
"**": {
"policies": [
{ "users": ["bstein"], "actions": ["read", "create", "update", "delete"] }
{ "groups": ["admin", "image-pusher"], "actions": ["read", "create", "update", "delete"] }
],
"defaultPolicy": [],
"anonymousPolicy": []
}
},
"adminPolicy": {
"users": ["bstein"],
"groups": ["admin"],
"actions": ["read", "create", "update", "delete"]
}
}

View File

@ -38,14 +38,10 @@ spec:
ports:
- { name: http, containerPort: 5000 }
volumeMounts:
- name: cfg
- name: cfg-rendered
mountPath: /etc/zot/config.json
subPath: config.json
readOnly: true
- name: htpasswd
mountPath: /etc/zot/htpasswd
subPath: htpasswd
readOnly: true
- name: zot-data
mountPath: /var/lib/registry
readinessProbe:
@ -60,13 +56,36 @@ spec:
periodSeconds: 10
resources:
requests: { cpu: "50m", memory: "64Mi" }
initContainers:
- name: render-config
image: busybox:1.36
command:
- /bin/sh
- -c
- |
set -eu
if [ -z "${ZOT_CLIENT_SECRET:-}" ]; then
echo "ZOT_CLIENT_SECRET is empty; ensure zot-oidc-client secret exists" >&2
exit 1
fi
sed "s|__CLIENT_SECRET__|${ZOT_CLIENT_SECRET}|g" /config-src/config.json > /config/config.json
env:
- name: ZOT_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: zot-oidc-client
key: client_secret
volumeMounts:
- name: cfg-src
mountPath: /config-src
- name: cfg-rendered
mountPath: /config
volumes:
- name: cfg
- name: cfg-src
configMap:
name: zot-config
- name: htpasswd
secret:
secretName: zot-htpasswd
- name: cfg-rendered
emptyDir: {}
- name: zot-data
persistentVolumeClaim:
claimName: zot-data