172 lines
7.7 KiB
Markdown
172 lines
7.7 KiB
Markdown
|
|
WorkplanOneGrok
|
|||
|
|
|
|||
|
|
*How to start according to grok*
|
|||
|
|
|
|||
|
|
This is a protoplan not to be implemented directly but used as inspiration for an actual plan for implemenation!
|
|||
|
|
|
|||
|
|
**Integrated architecture (merging both opinions)**
|
|||
|
|
|
|||
|
|
Your single private credential remains the **root-of-trust** that only ever unlocks a vault. Everything else (initial admin passwords, database credentials, privacyIDEA crypto roots, TLS keys, Keycloak admin secret) lives inside the vault and is never typed manually again.
|
|||
|
|
|
|||
|
|
- **privacyIDEA** = MFA/token/policy engine (user resolvers, self-service enrollment, token types, audit)
|
|||
|
|
- **Keycloak** = full SSO IdP (OIDC/SAML clients, realms, groups, session management)
|
|||
|
|
- **Integration** = Keycloak PrivacyIDEA provider (MFA step in the browser flow)
|
|||
|
|
- **Vault** = single unlock point (KeePassXC/Bitwarden local, or HashiCorp Vault in-cluster)
|
|||
|
|
- **Databases** = private, encrypted, backed up with keys from the vault
|
|||
|
|
- **K8s layer** = Helm + Official Keycloak Operator + community privacyIDEA Helm chart (gpappsoft/privacyidea) + cert-manager + Ingress
|
|||
|
|
|
|||
|
|
This satisfies both sources: you bootstrap from literally one secret, immediately move to MFA-protected admins, treat crypto roots (SECRET_KEY, PI_PEPPER, PI_ENCFILE) as crown jewels, and run everything declaratively on Kubernetes.
|
|||
|
|
|
|||
|
|
### Kubernetes Workplan (Day 0–7)
|
|||
|
|
|
|||
|
|
**Prerequisites**
|
|||
|
|
- Running Kubernetes cluster (k3s, kind, EKS, AKS, GKE – any with StorageClass and cert-manager installed).
|
|||
|
|
- kubectl, Helm 3.
|
|||
|
|
- Ingress controller (nginx-ingress or Traefik).
|
|||
|
|
- cert-manager for automatic TLS.
|
|||
|
|
- Your single master credential ready (KeePassXC file or age private key).
|
|||
|
|
|
|||
|
|
#### Day 0 – Vault & Secret Bootstrap (single-credential principle)
|
|||
|
|
1. Create your vault (recommended: KeePassXC .kdbx file or self-hosted Bitwarden; for production add HashiCorp Vault later).
|
|||
|
|
2. Inside the vault generate/store (all random, never reuse):
|
|||
|
|
- privacyIDEA: `SECRET_KEY` (64+ chars), `PI_PEPPER` (32+ chars), encryption key file content (`pi-manage create_enckey`).
|
|||
|
|
- MariaDB root + privacyIDEA DB user passwords.
|
|||
|
|
- Keycloak admin initial secret + DB password.
|
|||
|
|
- TLS ACME account key (if not using cert-manager fully).
|
|||
|
|
- Break-glass admin credentials + offline recovery OTP seed.
|
|||
|
|
3. Export an encrypted “ops bundle” (age-encrypted tar of all secret YAML manifests) – this bundle is the only thing you ever decrypt with your single credential.
|
|||
|
|
4. Enable cluster encryption-at-rest (if not already).
|
|||
|
|
|
|||
|
|
#### Day 1 – Foundation & Databases
|
|||
|
|
```bash
|
|||
|
|
# Deploy HashiCorp Vault (optional but ideal for rotation)
|
|||
|
|
helm repo add hashicorp https://helm.releases.hashicorp.com
|
|||
|
|
helm install vault hashicorp/vault --namespace vault --create-namespace -f vault-values.yaml
|
|||
|
|
|
|||
|
|
# Or use simple sops/age for GitOps
|
|||
|
|
```
|
|||
|
|
- Deploy MariaDB (Bitnami Helm or Crunchy Postgres Operator).
|
|||
|
|
- Create Kubernetes Secrets from the vault (or use External Secrets Operator + Vault backend):
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: v1
|
|||
|
|
kind: Secret
|
|||
|
|
metadata:
|
|||
|
|
name: privacyidea-secrets
|
|||
|
|
data:
|
|||
|
|
SECRET_KEY: <base64-from-vault>
|
|||
|
|
PI_PEPPER: <base64-from-vault>
|
|||
|
|
PI_ENCFILE: <base64-content>
|
|||
|
|
```
|
|||
|
|
- Apply network policies: DBs only reachable from privacyIDEA/Keycloak pods.
|
|||
|
|
|
|||
|
|
#### Day 2–3 – Deploy privacyIDEA (MFA core)
|
|||
|
|
The community Helm chart (gpappsoft/privacyidea on Artifact Hub) deploys the full stack (privacyIDEA + MariaDB + optional Redis/RADIUS).
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
helm repo add privacyidea https://gpappsoft.github.io/helm-charts
|
|||
|
|
helm install privacyidea privacyidea/privacyidea \
|
|||
|
|
--namespace privacyidea --create-namespace \
|
|||
|
|
-f values-privacyidea.yaml
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Key parts of `values-privacyidea.yaml` (populated from vault):
|
|||
|
|
```yaml
|
|||
|
|
database:
|
|||
|
|
password: <from-vault>
|
|||
|
|
privacyidea:
|
|||
|
|
config:
|
|||
|
|
SECRET_KEY: <from-vault>
|
|||
|
|
PI_PEPPER: <from-vault>
|
|||
|
|
encfile: # mounted as secret volume
|
|||
|
|
enabled: true
|
|||
|
|
existingSecret: privacyidea-secrets
|
|||
|
|
key: PI_ENCFILE
|
|||
|
|
admin:
|
|||
|
|
bootstrap: true # chart runs pi-manage internally
|
|||
|
|
ingress:
|
|||
|
|
enabled: true
|
|||
|
|
hostname: pi.yourdomain.com
|
|||
|
|
tls: true
|
|||
|
|
```
|
|||
|
|
Post-install (one-time job or manual):
|
|||
|
|
- `kubectl exec` into privacyIDEA pod and run `pi-manage admin add pi-admin --email admin@yourdomain.com` (password from vault).
|
|||
|
|
- Immediately enroll an MFA token for `pi-admin` via the UI.
|
|||
|
|
- Create limited “trigger-admin” (only `triggerchallenge` right) for Keycloak.
|
|||
|
|
- Apply day-1 policies: WebUI restricted to VPN/office IPs, MFA required for all admin actions, enrollment policies locked down.
|
|||
|
|
|
|||
|
|
#### Day 4–5 – Deploy Keycloak + privacyIDEA MFA integration
|
|||
|
|
1. Install the official Keycloak Operator:
|
|||
|
|
```bash
|
|||
|
|
kubectl apply -f https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/main/kubernetes/keycloaks.k8s.keycloak.org-v1.yml
|
|||
|
|
kubectl apply -f https://raw.githubusercontent.com/keycloak/keycloak-k8s-resources/main/kubernetes/kubernetes.yml -n keycloak
|
|||
|
|
```
|
|||
|
|
2. Prepare the PrivacyIDEA provider JAR:
|
|||
|
|
```bash
|
|||
|
|
wget https://github.com/privacyidea/keycloak-provider/releases/latest/download/PrivacyIDEA-Provider.jar
|
|||
|
|
kubectl create configmap privacyidea-provider --from-file=PrivacyIDEA-Provider.jar -n keycloak
|
|||
|
|
```
|
|||
|
|
3. Create Keycloak CR (with custom provider mount):
|
|||
|
|
```yaml
|
|||
|
|
apiVersion: k8s.keycloak.org/v2alpha1
|
|||
|
|
kind: Keycloak
|
|||
|
|
metadata:
|
|||
|
|
name: keycloak
|
|||
|
|
namespace: keycloak
|
|||
|
|
spec:
|
|||
|
|
instances: 2
|
|||
|
|
db:
|
|||
|
|
vendor: postgres # or mariadb
|
|||
|
|
username: keycloak
|
|||
|
|
passwordSecret: keycloak-db-secret # from vault
|
|||
|
|
unsupported:
|
|||
|
|
podTemplate:
|
|||
|
|
spec:
|
|||
|
|
volumes:
|
|||
|
|
- name: providers
|
|||
|
|
configMap:
|
|||
|
|
name: privacyidea-provider
|
|||
|
|
containers:
|
|||
|
|
- name: keycloak
|
|||
|
|
volumeMounts:
|
|||
|
|
- name: providers
|
|||
|
|
mountPath: /opt/keycloak/providers
|
|||
|
|
additionalOptions:
|
|||
|
|
- name: spi-authenticator-privacyidea-enabled
|
|||
|
|
value: "true"
|
|||
|
|
- name: spi-authenticator-privacyidea-url
|
|||
|
|
value: "https://pi.yourdomain.com"
|
|||
|
|
- name: spi-authenticator-privacyidea-service-account
|
|||
|
|
value: "trigger-admin" # limited rights only
|
|||
|
|
ingress:
|
|||
|
|
enabled: true
|
|||
|
|
```
|
|||
|
|
4. In Keycloak UI (or via CR import): create realm, import same user resolver as privacyIDEA (LDAP/Keycloak internal/Entra), create custom browser flow with “PrivacyIDEA Forms” execution (REQUIRED). Bind as default flow.
|
|||
|
|
|
|||
|
|
#### Day 6–7 – Policies, Self-Service, Break-Glass & Testing
|
|||
|
|
- privacyIDEA: enable self-service enrollment policies + registration tokens.
|
|||
|
|
- Keycloak: require MFA step-up for admin console and sensitive clients.
|
|||
|
|
- Break-glass: store offline admin + recovery OTP in sealed envelope + vault. Alert on usage.
|
|||
|
|
- End-to-end test: app → Keycloak → privacyIDEA OTP/push → SSO session.
|
|||
|
|
- Configure backups (Velero or operator) encrypted with vault key.
|
|||
|
|
- Monitoring: Prometheus + Grafana (optional).
|
|||
|
|
|
|||
|
|
### Security & Operations Checklist (do these before going live)
|
|||
|
|
- All external traffic via Ingress + HSTS + strict TLS.
|
|||
|
|
- privacyIDEA encryption keys backed up and never in image.
|
|||
|
|
- Least-privilege service accounts everywhere.
|
|||
|
|
- NetworkPolicies + PodSecurityPolicies.
|
|||
|
|
- Rotate secrets via vault (External Secrets Operator handles re-injection).
|
|||
|
|
- Test recovery: vault unlock → restore DB + keys → everything works.
|
|||
|
|
|
|||
|
|
This plan is production-ready, fully declarative, and scales. You start with one memorized credential and end with a hardened, auditable SSO+MFA platform.
|
|||
|
|
|
|||
|
|
If you tell me:
|
|||
|
|
- Cluster type (k3s, EKS, bare-metal…)
|
|||
|
|
- Existing user store (LDAP/AD/Entra/Keycloak internal)
|
|||
|
|
- Target apps (Nextcloud, GitLab, custom…)
|
|||
|
|
- Preference for GitOps (ArgoCD/Flux) or manual Helm
|
|||
|
|
|
|||
|
|
I can give you the exact `values.yaml` files, CRDs, and one-click scripts.
|
|||
|
|
|
|||
|
|
xxx
|