generated from coulomb/repo-seed
fix(privacyidea): bootstrap-realm scope fixes + netpol for PI→LLDAP
bootstrap-realm.sh: - Remove Content-Type header from GET requests (Werkzeug 3.x BadRequest fix) - Fix resolver type check — result path is result.value.<name>.type, not .data - Fix self-enrollment policy scope: 'user' not 'enrollment' (PI 3.12) NetworkPolicies: - allow-egress-to-lldap (mfa ns): privacyIDEA → LLDAP :3890 - allow-privacyidea-to-lldap (sso ns): ingress from mfa/privacyIDEA → LLDAP :3890 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
# INGRESS: Traefik (kube-system) → privacyIDEA :8080 (user-facing portal)
|
||||
# INGRESS: KeyCape (sso) → privacyIDEA :8080 (Provider API calls)
|
||||
# EGRESS: privacyIDEA → databases :5432 (PostgreSQL)
|
||||
# EGRESS: privacyIDEA → sso/lldap :3890 (LDAP resolver for realm)
|
||||
# EGRESS: all pods → kube-dns :53 (UDP+TCP)
|
||||
#
|
||||
# Everything else is denied.
|
||||
@@ -90,6 +91,33 @@ spec:
|
||||
- port: 5432
|
||||
protocol: TCP
|
||||
---
|
||||
# ── privacyIDEA → LLDAP :3890 ────────────────────────────────────────────────
|
||||
# privacyIDEA's LDAP resolver binds to LLDAP to resolve users in the coulomb realm.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-egress-to-lldap
|
||||
namespace: mfa
|
||||
labels:
|
||||
net-kingdom/component: mfa
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: privacyidea
|
||||
policyTypes:
|
||||
- Egress
|
||||
egress:
|
||||
- to:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
net-kingdom/component: sso
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: lldap
|
||||
ports:
|
||||
- port: 3890
|
||||
protocol: TCP
|
||||
---
|
||||
# ── Traefik → ACME HTTP-01 solver pods :8089 ─────────────────────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
|
||||
@@ -173,6 +173,33 @@ spec:
|
||||
- port: 3890
|
||||
protocol: TCP
|
||||
---
|
||||
# ── privacyIDEA (mfa ns) → LLDAP :3890 ──────────────────────────────────────
|
||||
# privacyIDEA's LDAP resolver binds to LLDAP to resolve users in the coulomb realm.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: allow-privacyidea-to-lldap
|
||||
namespace: sso
|
||||
labels:
|
||||
net-kingdom/component: sso
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: lldap
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
net-kingdom/component: mfa
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: privacyidea
|
||||
ports:
|
||||
- port: 3890
|
||||
protocol: TCP
|
||||
---
|
||||
# ── KeyCape egress → Authelia + LLDAP (within sso namespace) ─────────────────
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
|
||||
@@ -90,6 +90,8 @@ info "Authenticated as pi-admin (token obtained)"
|
||||
|
||||
pi_api() {
|
||||
# pi_api <method> <path> [json-body]
|
||||
# Content-Type is only set on requests with a body — Werkzeug 3.x raises
|
||||
# BadRequest if Content-Type: application/json is sent on a bodyless GET.
|
||||
local method="$1"; local path="$2"; local body="${3:-}"
|
||||
if [[ -n "$body" ]]; then
|
||||
curl -sf -X "$method" "$PI_URL$path" \
|
||||
@@ -99,7 +101,6 @@ pi_api() {
|
||||
else
|
||||
curl -sf -X "$method" "$PI_URL$path" \
|
||||
-H "Authorization: $PI_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
2>/dev/null || echo "CURL_FAILED"
|
||||
fi
|
||||
}
|
||||
@@ -163,7 +164,7 @@ echo "Step 2: Testing resolver '$RESOLVER_NAME' ..."
|
||||
TEST_RESP=$(pi_api GET "/resolver/$RESOLVER_NAME")
|
||||
if [[ "$TEST_RESP" != "CURL_FAILED" ]]; then
|
||||
RESOLVER_TYPE=$(echo "$TEST_RESP" | python3 -c \
|
||||
"import sys,json; d=json.load(sys.stdin); r=d.get('result',{}).get('value',{}).get('data',{}); print(list(r.values())[0].get('type','') if r else '')" \
|
||||
"import sys,json; d=json.load(sys.stdin); r=d.get('result',{}).get('value',{}); print(list(r.values())[0].get('type','') if r else '')" \
|
||||
2>/dev/null || echo "")
|
||||
if [[ "$RESOLVER_TYPE" == "ldapresolver" ]]; then
|
||||
ok "Resolver '$RESOLVER_NAME' exists and is type ldapresolver"
|
||||
@@ -217,12 +218,13 @@ check_result "Default realm set to '$REALM_NAME'" "$RESP" || true
|
||||
# ── 6. Create self-enrollment policy ─────────────────────────────────────────
|
||||
echo ""
|
||||
echo "Step 6: Creating self-enrollment policy ..."
|
||||
# Allows users in the coulomb realm to self-enroll TOTP tokens.
|
||||
# Allows users in the coulomb realm to self-enroll TOTP tokens via the self-service portal.
|
||||
# Scope must be 'user' (not 'enrollment') — self-service actions live in the user scope.
|
||||
# The WebUI self-service portal is at pink-account.coulomb.social.
|
||||
ENROLL_POLICY=$(python3 -c "
|
||||
import json
|
||||
body = {
|
||||
'scope': 'enrollment',
|
||||
'scope': 'user',
|
||||
'action': 'enrollTOTP, delete, disable',
|
||||
'realm': '$REALM_NAME',
|
||||
'user': '*',
|
||||
|
||||
Reference in New Issue
Block a user