k8s/iam: add cloudnativepg postgres and vault + authentik
- PostgreSQL 3-replica HA with pgvector - Vault S3 storage backend (MinIO) - Authentik federated OIDC provider - Vault auto-unseal via postStart hook
This commit is contained in:
Executable
+134
@@ -0,0 +1,134 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example: Register 'dashboard-service' with OAuth + Vault JWT auth.
|
||||
|
||||
This is a complete working example that demonstrates:
|
||||
1. Creating an Authentik OAuth2 provider and application
|
||||
2. Creating Kubernetes secrets for OIDC credentials
|
||||
3. Creating a Vault JWT role for service authentication
|
||||
4. Group-based RBAC
|
||||
|
||||
To use this example:
|
||||
|
||||
# 1. Ensure prerequisites
|
||||
kubectl port-forward -n iam svc/authentik-server 7000:80 &
|
||||
kubectl port-forward -n storage svc/vault 8200:8200 &
|
||||
|
||||
# 2. Generate and store credentials
|
||||
DASHBOARD_OIDC_CLIENT_SECRET=$(openssl rand -hex 32)
|
||||
export DASHBOARD_OIDC_CLIENT_SECRET="$DASHBOARD_OIDC_CLIENT_SECRET"
|
||||
talos put cluster/DASHBOARD_OIDC_CLIENT_SECRET DASHBOARD_OIDC_CLIENT_SECRET="$DASHBOARD_OIDC_CLIENT_SECRET"
|
||||
|
||||
# 3. Run registration
|
||||
python3 register_oauth_app.py \\
|
||||
--service-name dashboard-service \\
|
||||
--namespace apps \\
|
||||
--redirect-uri "https://dashboard.riotpiao.homelab.com/oauth2/callback" \\
|
||||
--service-name-in-vault DASHBOARD \\
|
||||
--vault-jwt-policy shell-secrets \\
|
||||
--add-group dashboard-admins \\
|
||||
--vault-jwt-bound-claims '{"groups":["dashboard-admins"]}'
|
||||
|
||||
# 4. Verify registration
|
||||
curl -s -H "Authorization: Bearer $AUTHENTIK_BOOTSTRAP_TOKEN" \\
|
||||
http://localhost:7000/api/v3/core/applications/?slug=dashboard-service | jq .
|
||||
|
||||
# 5. Test OAuth callback (requires app running)
|
||||
# Browser: http://dashboard.riotpiao.homelab.com/login
|
||||
# Should redirect to Authentik → back to dashboard with session
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def example_dashboard_service():
|
||||
"""Register the example 'dashboard-service' with full RBAC."""
|
||||
|
||||
# Check prerequisites
|
||||
print("Checking prerequisites...")
|
||||
|
||||
required_env = [
|
||||
"AUTHENTIK_BOOTSTRAP_TOKEN",
|
||||
"DASHBOARD_OIDC_CLIENT_SECRET",
|
||||
]
|
||||
|
||||
missing = [v for v in required_env if not os.environ.get(v)]
|
||||
if missing:
|
||||
print(f"❌ Missing environment variables: {', '.join(missing)}")
|
||||
print("\nSet them:")
|
||||
print(" talos get cluster/AUTHENTIK_BOOTSTRAP_TOKEN --key AUTHENTIK_BOOTSTRAP_TOKEN | source")
|
||||
print(" talos get cluster/DASHBOARD_OIDC_CLIENT_SECRET --key DASHBOARD_OIDC_CLIENT_SECRET | source")
|
||||
return False
|
||||
|
||||
# Call the registration script
|
||||
cmd = [
|
||||
"python3",
|
||||
"register_oauth_app.py",
|
||||
"--service-name", "dashboard-service",
|
||||
"--namespace", "apps",
|
||||
"--redirect-uri", "https://dashboard.riotpiao.homelab.com/oauth2/callback",
|
||||
"--service-name-in-vault", "DASHBOARD",
|
||||
"--vault-jwt-policy", "shell-secrets",
|
||||
"--add-group", "dashboard-admins",
|
||||
"--vault-jwt-bound-claims", '{"groups":["dashboard-admins"]}',
|
||||
]
|
||||
|
||||
print(f"\nRunning: {' '.join(cmd)}\n")
|
||||
|
||||
result = subprocess.run(cmd, check=False)
|
||||
return result.returncode == 0
|
||||
|
||||
|
||||
def verify_example():
|
||||
"""Verify that the dashboard-service was registered correctly."""
|
||||
print("\n" + "="*70)
|
||||
print("Verification Steps")
|
||||
print("="*70 + "\n")
|
||||
|
||||
print("✅ Check Authentik provider:")
|
||||
print(" curl -s -H 'Authorization: Bearer $AUTHENTIK_BOOTSTRAP_TOKEN' \\")
|
||||
print(" http://localhost:7000/api/v3/providers/oauth2/?name=dashboard-service \\")
|
||||
print(" | jq '.results[0] | {name, client_id, redirect_uris}'")
|
||||
print()
|
||||
|
||||
print("✅ Check Authentik application:")
|
||||
print(" curl -s -H 'Authorization: Bearer $AUTHENTIK_BOOTSTRAP_TOKEN' \\")
|
||||
print(" http://localhost:7000/api/v3/core/applications/?slug=dashboard-service \\")
|
||||
print(" | jq '.results[0] | {name, slug, provider}'")
|
||||
print()
|
||||
|
||||
print("✅ Check Kubernetes secret:")
|
||||
print(" kubectl get secret dashboard-service-oidc -n apps -o jsonpath='{.data}' \\")
|
||||
print(" | base64 -d | jq .")
|
||||
print()
|
||||
|
||||
print("✅ Check Vault JWT role:")
|
||||
print(" vault read auth/jwt/role/dashboard-service")
|
||||
print()
|
||||
|
||||
print("✅ Test Vault JWT authentication:")
|
||||
print(" # Get ID token from Authentik")
|
||||
print(" ID_TOKEN=$(curl -s -X POST \\")
|
||||
print(" http://localhost:7000/application/o/dashboard-service/token/ \\")
|
||||
print(" -d 'grant_type=client_credentials&client_id=dashboard-service&client_secret=...' \\")
|
||||
print(" | jq -r '.access_token')")
|
||||
print()
|
||||
print(" # Authenticate to Vault with JWT")
|
||||
print(" vault write auth/jwt/login \\")
|
||||
print(" role=dashboard-service \\")
|
||||
print(" jwt=\"$ID_TOKEN\"")
|
||||
print()
|
||||
|
||||
print("✅ Test OAuth redirect (requires app running):")
|
||||
print(" curl -L https://dashboard.riotpiao.homelab.com/login")
|
||||
print(" # Should redirect to Authentik, then back to dashboard")
|
||||
print()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if not example_dashboard_service():
|
||||
sys.exit(1)
|
||||
|
||||
verify_example()
|
||||
Reference in New Issue
Block a user