# prole.org auth — Samba AD cross-realm trust & keytab provisioning **Status:** Infrastructure coded; operational steps pending. **Owner:** chrisfu Closes Path B: Samba AD users on `myrddin.prole.org` → Kerberos SPNEGO → knoe-auth session. --- ## Architecture recap The in-cluster KDC runs the `KNOE.LOCAL` realm. `myrddin.prole.org` (10.0.0.3) runs Samba AD with realm `PROLE.ORG`. A bidirectional cross-realm trust lets a `PROLE.ORG` ticket-holder authenticate to any kerberized in-cluster service (`HTTP/api.prole.org@KNOE.LOCAL` etc.) without needing a second Kerberos account. ``` AD user on myrddin → TGT from PROLE.ORG KDC (myrddin:88) → cross-realm referral → KNOE.LOCAL KDC (in-cluster) → service ticket for HTTP/api.prole.org@KNOE.LOCAL → SPNEGO negotiation with knoe-auth → knoe_session cookie issued ``` The in-cluster ExternalName service `prole-kerberos-ad-dc.knoe-system.svc.cluster.local:88` routes to `myrddin.prole.org` so the KDC container can find the PROLE.ORG KDC. --- ## Step 1 — Create the inter-realm keys on the in-cluster KDC `init_kdc.sh` provisions the MIT KDC side when `PROLE_KDC_TRUST_REALM` is set. Run this from within the cluster (or via `kubectl exec` into the KDC container): ```bash # The shared trust password is in knoe-kdc-secrets/trust_shared_password TRUST_SHARED_PW=$(kubectl -n knoe-system get secret knoe-kdc-secrets \ -o jsonpath='{.data.trust_shared_password}' | base64 -d) kubectl exec -n knoe-system deploy/knoe-auth -c kdc -- kadmin.local -q \ "addprinc -pw ${TRUST_SHARED_PW} krbtgt/PROLE.ORG@KNOE.LOCAL" kubectl exec -n knoe-system deploy/knoe-auth -c kdc -- kadmin.local -q \ "addprinc -pw ${TRUST_SHARED_PW} krbtgt/KNOE.LOCAL@PROLE.ORG" ``` Both directions must exist. The KNOE.LOCAL → PROLE.ORG key is used when a PROLE.ORG principal requests a service ticket in KNOE.LOCAL (referral chain). --- ## Step 2 — Create the reciprocal trust account on myrddin (Samba side) SSH to `myrddin.prole.org` as Administrator and run: ```bash # Create the outbound trust principal that KNOE.LOCAL will use sudo samba-tool user create krbtgt_KNOEDOTLOCAL --random-password # Set the inter-realm key to the SAME shared password used in Step 1 sudo samba-tool user setpassword krbtgt_KNOEDOTLOCAL --newpassword="${TRUST_SHARED_PW}" # Disable password expiry for the trust account sudo samba-tool user setexpiry krbtgt_KNOEDOTLOCAL --noexpiry # Create the one-way trust entry (PROLE.ORG trusts KNOE.LOCAL) sudo samba-tool domain trust create KNOE.LOCAL \ --type=external \ --direction=incoming \ --password="${TRUST_SHARED_PW}" ``` Note: `KNOE.LOCAL` must be resolvable from `myrddin`. Either add a DNS forwarder for the `KNOE.LOCAL` domain pointing at the in-cluster KDC service IP, or add a hosts entry. --- ## Step 3 — Extract the HTTP service keytab The knoe-auth pod needs `HTTP/api.prole.org@PROLE.ORG` to accept SPNEGO from PROLE.ORG browsers. ```bash # Option A — generate keytab on myrddin (if the principal lives in PROLE.ORG) ssh myrddin.prole.org "sudo samba-tool user create HTTP-api-prole-org --random-password && \ sudo samba-tool spn add HTTP/api.prole.org HTTP-api-prole-org && \ sudo samba-tool domain exportkeytab /tmp/http-api.keytab --principal=HTTP/api.prole.org" scp myrddin.prole.org:/tmp/http-api.keytab ./http.keytab # Option B — generate on the in-cluster KDC (principal in KNOE.LOCAL) kubectl exec -n knoe-system deploy/knoe-auth -c kdc -- kadmin.local -q \ "addprinc -randkey HTTP/api.prole.org@KNOE.LOCAL" kubectl exec -n knoe-system deploy/knoe-auth -c kdc -- kadmin.local -q \ "ktadd -k /tmp/http.keytab HTTP/api.prole.org@KNOE.LOCAL" kubectl cp knoe-system/$(kubectl get pod -n knoe-system -l app=knoe-auth -o name | head -1 | cut -d/ -f2):/tmp/http.keytab ./http.keytab ``` Choose Option A if clients authenticate as `user@PROLE.ORG` — the service principal must match the realm clients target. Use Option B if you want KNOE.LOCAL to be authoritative. Store the keytab in the k8s secret: ```bash kubectl create secret generic knoe-auth-http-keytab \ --namespace knoe-system \ --from-file=http.keytab=./http.keytab \ --dry-run=client -o yaml | kubectl apply -f - ``` The deployment mounts this at `/etc/knoe-auth/http.keytab` (already wired in `knoe-auth-deployment.yaml`). --- ## Step 4 — Verify trust end-to-end From a domain-joined Windows or Linux machine in `PROLE.ORG`: ```bash # Linux (kinit from PROLE.ORG) kinit user@PROLE.ORG kvno HTTP/api.prole.org@KNOE.LOCAL # should succeed via cross-realm referral # Test SPNEGO login curl -v --negotiate -u : https://api.prole.org/auth/spnego # Expect: 302 redirect with knoe_session cookie ``` --- ## Step 5 — AD group sync (future work) AD group membership → `knoe.access_grant` rows is not yet implemented. Current behavior: - Samba AD users get a baseline `knoe_session` with no extra groups. - Admin rights are granted only to usernames listed in `PROLE_AUTH_ADMIN_PRINCIPALS`. To grant admin access to an AD user before group sync is built: ```bash kubectl -n knoe-system set env deploy/knoe-auth \ PROLE_AUTH_ADMIN_PRINCIPALS="admin," ``` --- ## Related files | File | Purpose | |---|---| | [`deploy/opentofu/k3s/manifests/knoe/prole-kerberos-ad-dc-svc.yaml`](../opentofu/k3s/manifests/knoe/prole-kerberos-ad-dc-svc.yaml) | ExternalName service → myrddin.prole.org:88 | | [`deploy/opentofu/k3s/manifests/knoe/knoe-kdc-secrets.example.yaml`](../opentofu/k3s/manifests/knoe/knoe-kdc-secrets.example.yaml) | trust_shared_password lives here | | [`etc/init_kdc.sh`](../../etc/init_kdc.sh) | Automates Step 1 when `PROLE_KDC_TRUST_*` env vars are set | | [`deploy/opentofu/k3s/manifests/knoe/knoe-auth-http-keytab-secret.example.yaml`](../opentofu/k3s/manifests/knoe/knoe-auth-http-keytab-secret.example.yaml) | HTTP service keytab secret template |