sso: fix vault OIDC bootstrap and render zot oidc config
This commit is contained in:
parent
c8254d6eec
commit
dba4d270ff
@ -10,3 +10,4 @@ resources:
|
|||||||
- middleware.yaml
|
- middleware.yaml
|
||||||
- serverstransport.yaml
|
- serverstransport.yaml
|
||||||
- oauth2-proxy-vault.yaml
|
- oauth2-proxy-vault.yaml
|
||||||
|
- oidc-bootstrap-job.yaml
|
||||||
|
|||||||
@ -61,8 +61,8 @@ spec:
|
|||||||
- --cookie-refresh=20m
|
- --cookie-refresh=20m
|
||||||
- --cookie-expire=168h
|
- --cookie-expire=168h
|
||||||
- --insecure-oidc-allow-unverified-email=true
|
- --insecure-oidc-allow-unverified-email=true
|
||||||
- --upstream=https://vault-ui.vault.svc.cluster.local:8200
|
# Vault UI is served over HTTP on the service endpoint.
|
||||||
- --ssl-insecure-skip-verify=true
|
- --upstream=http://vault.vault.svc.cluster.local:8200
|
||||||
- --http-address=0.0.0.0:4180
|
- --http-address=0.0.0.0:4180
|
||||||
- --skip-provider-button=true
|
- --skip-provider-button=true
|
||||||
- --skip-jwt-bearer-tokens=true
|
- --skip-jwt-bearer-tokens=true
|
||||||
|
|||||||
79
services/vault/oidc-bootstrap-job.yaml
Normal file
79
services/vault/oidc-bootstrap-job.yaml
Normal 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"
|
||||||
@ -20,20 +20,34 @@ data:
|
|||||||
"realm": "zot-registry",
|
"realm": "zot-registry",
|
||||||
"compat": ["docker2s2"],
|
"compat": ["docker2s2"],
|
||||||
"auth": {
|
"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": {
|
"accessControl": {
|
||||||
"repositories": {
|
"repositories": {
|
||||||
"**": {
|
"**": {
|
||||||
"policies": [
|
"policies": [
|
||||||
{ "users": ["bstein"], "actions": ["read", "create", "update", "delete"] }
|
{ "groups": ["admin", "image-pusher"], "actions": ["read", "create", "update", "delete"] }
|
||||||
],
|
],
|
||||||
"defaultPolicy": [],
|
"defaultPolicy": [],
|
||||||
"anonymousPolicy": []
|
"anonymousPolicy": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"adminPolicy": {
|
"adminPolicy": {
|
||||||
"users": ["bstein"],
|
"groups": ["admin"],
|
||||||
"actions": ["read", "create", "update", "delete"]
|
"actions": ["read", "create", "update", "delete"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,14 +38,10 @@ spec:
|
|||||||
ports:
|
ports:
|
||||||
- { name: http, containerPort: 5000 }
|
- { name: http, containerPort: 5000 }
|
||||||
volumeMounts:
|
volumeMounts:
|
||||||
- name: cfg
|
- name: cfg-rendered
|
||||||
mountPath: /etc/zot/config.json
|
mountPath: /etc/zot/config.json
|
||||||
subPath: config.json
|
subPath: config.json
|
||||||
readOnly: true
|
readOnly: true
|
||||||
- name: htpasswd
|
|
||||||
mountPath: /etc/zot/htpasswd
|
|
||||||
subPath: htpasswd
|
|
||||||
readOnly: true
|
|
||||||
- name: zot-data
|
- name: zot-data
|
||||||
mountPath: /var/lib/registry
|
mountPath: /var/lib/registry
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
@ -60,13 +56,36 @@ spec:
|
|||||||
periodSeconds: 10
|
periodSeconds: 10
|
||||||
resources:
|
resources:
|
||||||
requests: { cpu: "50m", memory: "64Mi" }
|
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:
|
volumes:
|
||||||
- name: cfg
|
- name: cfg-src
|
||||||
configMap:
|
configMap:
|
||||||
name: zot-config
|
name: zot-config
|
||||||
- name: htpasswd
|
- name: cfg-rendered
|
||||||
secret:
|
emptyDir: {}
|
||||||
secretName: zot-htpasswd
|
|
||||||
- name: zot-data
|
- name: zot-data
|
||||||
persistentVolumeClaim:
|
persistentVolumeClaim:
|
||||||
claimName: zot-data
|
claimName: zot-data
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user