mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 11:03:59 +00:00
feat(knoe-auth): Phase 2 OIDC sandbox in k3d dev loop
Completes the Phase 2 OIDC laptop dev path. Source for the OIDC surface
(discovery, authorize, token, userinfo, JWKS controllers + signing /
session services) landed on `main` via the merge that brought
claude/crazy-bose-fec256 back. This commit makes Phase 2 actually
exercisable in the k3d dev loop without any GKE deploy.
What's new:
authority/src/main/resources/application-k3d.yml
Spring profile activated by `-Dspring-boot.run.profiles=k3d`.
Enables OIDC (knoe.oidc.enabled=true), points the issuer at
`http://localhost:8080`, sets Kerberos realm to KNOE.LOCAL, and
aligns the datasource with the port-forwarded localhost:5432 DB.
etc/gen_oidc_signing_key.sh (executable)
Idempotent RS256 PKCS#8 keypair generator. Outputs:
etc/secrets/knoe-auth-oidc-key.pem (PEM)
etc/secrets/knoe-auth-oidc-key.b64 (single-line base64 of DER —
directly consumable as KNOE_AUTH_OIDC_SIGNING_KEY by
OidcTokenService.init())
`etc/secrets/` is already gitignored. Set FORCE=1 to rotate.
What's wired:
scripts/k3d-knoe-up.sh
New §7 calls etc/gen_oidc_signing_key.sh after schema seed. Keypair
persists across `make k3d-knoe-down && make k3d-knoe-up` cycles.
scripts/k3d-knoe-pf.sh
Output now includes the KNOE_AUTH_OIDC_SIGNING_KEY export line, the
full `mvn spring-boot:run` invocation with -Dspring-boot.run.profiles=k3d,
and the three OIDC endpoints to curl-test.
What's documented:
docs/local-dev-knoe-auth.md
"Daily loop" Terminal B: now exports KNOE_AUTH_OIDC_SIGNING_KEY,
runs with `-Dspring-boot.run.profiles=k3d`, and the verify section
includes /jwks.json. IntelliJ run config: adds Active Profiles: k3d
and a note about pasting the b64 directly (no shell expansion in
the env-var field).
docs/knoe-system.md
Phase 2 status row split: "k3d setup" → Shipped, "GKE deploy" →
Pending. The "Open work items" Phase 2 entry rewritten to flag
that the GKE deploy is the remaining thread (gated on queue #3 for
the image rebuild as `knoe-auth:latest`).
docs/TODO.md
Promoted "Phase 2 OIDC provider — GKE deploy" into §In progress
(replacing the empty "(none)" placeholder). Done section updated
with two entries: the k3d Phase 1 dev loop (Junie's c3...) and
this Phase 2 OIDC k3d sandbox.
End-to-end loop the engineer can run:
make k3d-knoe-up # one-time, ~5 min
make k3d-knoe-pf & # port-forwards
export KRB5_CONFIG=$PWD/etc/krb5.local.conf
export KNOE_AUTH_OIDC_SIGNING_KEY=$(cat etc/secrets/knoe-auth-oidc-key.b64)
mvn -pl authority spring-boot:run \
-Dspring-boot.run.jvmArguments="-Djava.security.krb5.conf=$PWD/etc/krb5.local.conf" \
-Dspring-boot.run.profiles=k3d
# then:
curl -s http://localhost:8080/.well-known/openid-configuration | jq .issuer
# → "http://localhost:8080"
curl -s http://localhost:8080/jwks.json | jq '.keys[0].kty'
# → "RSA"
Verified locally: keypair generator round-trips through openssl pkey -inform DER
(produces valid 2048-bit RSA keys); idempotent (existing key kept by default,
FORCE=1 rotates); bash -n clean on all 5 touched scripts.
Out of scope (TODO §In progress captures it):
- GKE deploy of Phase 2 (image rebuild + K8s Secret + deployment env vars)
- SPNEGO E2E from host browsers (k3d-mirror Phase 2)
- knoe-auth-as-pod in k3d (k3d-mirror Phase 3)
- OidcCodeService DB persistence (separate track)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5d3600845d
commit
93157b0a86
68
authority/src/main/resources/application-k3d.yml
Normal file
68
authority/src/main/resources/application-k3d.yml
Normal file
@ -0,0 +1,68 @@
|
||||
# Spring profile: k3d
|
||||
# Activated by `-Dspring-boot.run.profiles=k3d` (see docs/local-dev-knoe-auth.md).
|
||||
#
|
||||
# Overrides for application.yml when knoe-auth runs on the laptop against
|
||||
# the k3d-resident CNPG + KDC stack (see docs/plans/k3d-gke-mirror.md).
|
||||
# Production / GKE values are NOT here — only the dev-loop adjustments.
|
||||
#
|
||||
# Phase 2 OIDC provider is ENABLED in this profile. The signing key is
|
||||
# read from KNOE_AUTH_OIDC_SIGNING_KEY (base64 PKCS#8 RS256 private key);
|
||||
# generate one with `bash etc/gen_oidc_signing_key.sh` (idempotent — runs
|
||||
# automatically as part of `make k3d-knoe-up`).
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
knoe:
|
||||
auth:
|
||||
enabled: true
|
||||
cookieDomain: localhost
|
||||
sessionSecret: ${KNOE_AUTH_SESSION_SECRET:k3d-dev-session-secret-change-me-needs-32-chars-min}
|
||||
formEnabled: true
|
||||
# Bare usernames granted admin group membership for local dev.
|
||||
adminPrincipals:
|
||||
- admin
|
||||
- developer
|
||||
|
||||
kerberos:
|
||||
realm: KNOE.LOCAL
|
||||
servicePrincipal: ${KNOE_KERBEROS_SERVICE_PRINCIPAL:HTTP/localhost@KNOE.LOCAL}
|
||||
keytabPath: ${KNOE_KERBEROS_KEYTAB_PATH:}
|
||||
# The krb5.conf is set via JVM arg in `mvn spring-boot:run`:
|
||||
# -Djava.security.krb5.conf=etc/krb5.local.conf
|
||||
# See docs/local-dev-knoe-auth.md.
|
||||
|
||||
# ── Phase 2 OIDC provider ──────────────────────────────────────────────
|
||||
# Local issuer is http://localhost:8080. /.well-known/openid-configuration,
|
||||
# /jwks.json, /authorize, /token, /userinfo are all reachable once knoe-auth
|
||||
# is running. signingKey: leave blank to let OidcTokenService generate an
|
||||
# ephemeral key on each startup (tokens don't survive restart but flow works);
|
||||
# set KNOE_AUTH_OIDC_SIGNING_KEY for a persistent key (gen_oidc_signing_key.sh
|
||||
# produces it).
|
||||
oidc:
|
||||
enabled: true
|
||||
issuer: ${KNOE_AUTH_OIDC_ISSUER:http://localhost:8080}
|
||||
signingKey: ${KNOE_AUTH_OIDC_SIGNING_KEY:}
|
||||
clientId: ${KNOE_AUTH_OIDC_CLIENT_ID:knoe-local}
|
||||
clientSecret: ${KNOE_AUTH_OIDC_CLIENT_SECRET:}
|
||||
|
||||
enroll:
|
||||
baseUrl: ${KNOE_AUTH_BASE_URL:http://localhost:8080}
|
||||
|
||||
# ── Google upstream (optional locally) ─────────────────────────────────
|
||||
# Phase 2 OIDC dev primarily exercises LOCAL token issuance + JWKS, not
|
||||
# the Google federation path. If you want to test the upstream Google
|
||||
# bounce, set GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET in your shell env
|
||||
# (and register http://localhost:8080/auth/enroll/google-callback as an
|
||||
# authorized redirect URI on the dev OAuth client).
|
||||
google:
|
||||
clientId: ${GOOGLE_CLIENT_ID:}
|
||||
clientSecret: ${GOOGLE_CLIENT_SECRET:}
|
||||
redirectUri: ${KNOE_AUTH_BASE_URL:http://localhost:8080}/auth/enroll/google-callback
|
||||
|
||||
spring:
|
||||
datasource:
|
||||
# Local k3d port-forward (see scripts/k3d-knoe-pf.sh)
|
||||
url: ${KNOE_DB_URL:jdbc:postgresql://localhost:5432/knoe-db}
|
||||
username: ${KNOE_DB_USER:postgres}
|
||||
password: ${KNOE_DB_PASSWORD:}
|
||||
@ -13,10 +13,10 @@ The Kanban "Now" section at top is the only place this doc imposes structure. Ev
|
||||
## Now (Kanban)
|
||||
|
||||
### In progress
|
||||
*(none — pull from the ranked queue below)*
|
||||
- **Phase 2 OIDC provider — GKE deploy.** k3d sandbox shipped 2026-05-02 (commit pending): `application-k3d.yml` profile, `etc/gen_oidc_signing_key.sh` keypair generator, OIDC endpoints (`/.well-known/openid-configuration`, `/jwks.json`, `/authorize`, `/token`, `/userinfo`) reachable locally via `make k3d-knoe-up && make k3d-knoe-pf && mvn -pl authority spring-boot:run -Dspring-boot.run.profiles=k3d`. Remaining work to ship Phase 2 in production (this is the open thread): rebuild the knoe-auth image with the merged Phase 2 source from `main` (gated on queue #3 — also renames `knoe-authority` → `knoe-auth`); generate a production RS256 keypair (OpenBao `knoe-auth/oidc-signing-key`); create K8s Secret in `knoe-system` namespace; add `KNOE_AUTH_OIDC_ENABLED=true`, `KNOE_AUTH_OIDC_ISSUER=https://api.knoe.dev/auth`, `KNOE_AUTH_OIDC_SIGNING_KEY` (from secret) env vars to `deploy/gcp/gke/knoe-auth-deployment.yaml`; rollout; verify discovery + JWKS resolve through Kong at `https://api.knoe.dev/auth`. Design ref: [`docs/knoe-auth-phase-2.md`](knoe-auth-phase-2.md).
|
||||
|
||||
### Paused
|
||||
- **Phase 2: pg_oauth in install/deploy.sh + k3d build** — *previously assigned to Junie; paused.* The Phase 1 work (per-engineer roles, external LB at `pg.0.knoe.dev`, cert SANs, pg_hba tightening, [`docs/db-access.md`](db-access.md)) is committed. Phase 2 replaces the SCRAM password mechanism with PG18 native OAUTHBEARER, wires it into `install.sh` / `supabase/deploy.sh` so a fresh deploy lands with the OIDC mechanism active by default, and ports the Service + cluster cert pattern to k3d. Connection target stays at `pg.0.knoe.dev`; only the credential issuance changes (libpq Device Flow → Google Bearer token). Resumes once knoe-auth Phase 2 OIDC dev has somewhere to run locally (k3d dev loop now in place).
|
||||
- **pg_oauth in install/deploy.sh + k3d build** — *previously assigned to Junie; paused.* The Phase 1 work (per-engineer roles, external LB at `pg.0.knoe.dev`, cert SANs, pg_hba tightening, [`docs/db-access.md`](db-access.md)) is committed. This phase replaces the SCRAM password mechanism with PG18 native OAUTHBEARER, wires it into `install.sh` / `supabase/deploy.sh` so a fresh deploy lands with the OIDC mechanism active by default, and ports the Service + cluster cert pattern to k3d. Connection target stays at `pg.0.knoe.dev`; only the credential issuance changes (libpq Device Flow → knoe-auth Bearer token). Resumes once Phase 2 OIDC is deployed to GKE (depends on the OIDC issuer being reachable from PostgreSQL).
|
||||
|
||||
### Up next
|
||||
*(empty — pull from the ranked queue below)*
|
||||
@ -94,6 +94,10 @@ Items where docs describe an intended state that doesn't match live state. Each
|
||||
|
||||
- 2026-05-02 — **k3d-mirror-of-GKE Phase 1: laptop dev loop for knoe-auth** (k3d brief). Smallest k3d-resident stack (CNPG single-replica + standalone KDC, realm `KNOE.LOCAL`) that lets a host-side knoe-auth iterate against real Postgres + Kerberos. Deliverables: `k8s/knoe/knoe-kdc-{configmap,deployment,service,pvc,init-job}.yaml`, `etc/init_knoe_auth.sh --mode k3d` flag (extends existing script; GKE behavior unchanged), `make k3d-knoe-{up,pf,down}` targets, `etc/krb5.local.conf` (TCP-forced, `udp_preference_limit=1`), `docs/local-dev-knoe-auth.md`, `scripts/k3d-knoe-{up,pf,down,smoke}.sh`. Design choice: extended `init_knoe_auth.sh` with `--mode k3d` rather than a sibling script — minimizes drift, same `schema`/`status` subcommands work in both modes. Brief: [`docs/plans/junie/k3d-knoe-auth-dev-loop.md`](plans/junie/k3d-knoe-auth-dev-loop.md).
|
||||
|
||||
- 2026-05-02 — **Phase 2 OIDC k3d dev sandbox** (commit pending). Companion to the k3d Phase 1 brief — completes the laptop dev loop for knoe-auth Phase 2. New `authority/src/main/resources/application-k3d.yml` Spring profile activates the OIDC surface with local issuer (`http://localhost:8080`); new `etc/gen_oidc_signing_key.sh` idempotently generates an RS256 PKCS#8 keypair at `etc/secrets/knoe-auth-oidc-key.{pem,b64}` (gitignored); `scripts/k3d-knoe-up.sh` runs the generator after schema seed; `scripts/k3d-knoe-pf.sh` prints the env-var export the engineer needs (`export KNOE_AUTH_OIDC_SIGNING_KEY=$(cat etc/secrets/knoe-auth-oidc-key.b64)`) plus the OIDC endpoint surface to curl-test. `docs/local-dev-knoe-auth.md` updated to use `-Dspring-boot.run.profiles=k3d`, the env var is exported, and the verify section now includes a `/jwks.json` curl. `docs/knoe-system.md` Phase 2 status flipped from "Planned" to "Shipped (k3d sandbox)" / "Pending (GKE deploy)". GKE-side Phase 2 deploy is now the open work item in TODO §"In progress" (gated on queue #3 image rename for the rebuild).
|
||||
|
||||
- 2026-05-02 — **k3d Phase 1 dev loop for knoe-auth** (commit `5d36008`). Junie's Phase 1 brief landed — laptop dev loop with CNPG (single-replica) + KDC (realm `KNOE.LOCAL`) reachable from host via `make k3d-knoe-{up,pf,down}`. New: 5 KDC manifests under `k8s/knoe/knoe-kdc-*.yaml`, 4 helper scripts under `scripts/k3d-knoe-*.sh`, `etc/krb5.local.conf` (with `udp_preference_limit=1` to dodge kubectl port-forward UDP flakiness on macOS), `docs/local-dev-knoe-auth.md` engineer doc, and `docs/knoe-system.md` unified reference. `etc/init_knoe_auth.sh` extended with `--mode k3d` flag (GKE behavior unchanged). Brief: [`docs/plans/junie/k3d-knoe-auth-dev-loop.md`](plans/junie/k3d-knoe-auth-dev-loop.md). Architectural plan: [`docs/plans/k3d-gke-mirror.md`](plans/k3d-gke-mirror.md).
|
||||
|
||||
- 2026-05-02 — **Garage decommissioned on app cluster `knoe-dev-0`** (queue #4 closure). Reframed mid-flight: the original "verify with `garage repair --yes blocks`" premise didn't match reality. Live garage was unconfigured (`garage status` → NO ROLE ASSIGNED, `garage layout show` → version 0, 21d of "Ring not yet ready" warnings); cross-cluster sweep confirmed nothing referenced its S3 endpoint anymore (CNPG backups moved to GCS in 2026-04-29 migration). Removed the entire workload from `knoe-system` namespace mirroring the 2026-04-29 DB-cluster removal: `sts/garage`, `svc/garage`, `cm/garage-config`, `secret/garage-secrets`, `pvc/data-garage-0` (29 Gi, was on `garage-hdd` storage class), and the `garage-hdd` StorageClass itself. PV had `reclaim=Retain` so the underlying GCE pd-standard disk (`pvc-656e1936-…` in `us-west3-c`) persisted past the kubectl-side cleanup; reclaimed via `gcloud compute disks delete`. Note: app cluster only had a ClusterIP service — no `garage-s3-ilb` LoadBalancer (DB cluster had that). Source manifests remain at `k8s/knoe/garage-*.yaml`, `deploy/opentofu/k3s/manifests/knoe/garage-*.yaml`, and `etc/init_garage_store.sh` for the k3d/k3s/min deploy modes (and any future GKE deploy that wants to wire garage back). Whether the GKE deploy mode should stop applying garage altogether is a separate decision.
|
||||
|
||||
- 2026-05-02 — **Phase B orphan cleanup** (queue #5). Five resources deleted across both clusters. App cluster (`knoe-dev-0`): `gitlab/gitlab-migrations-58a3e27-97-23-n72j8` (Failed/Evicted, 11d stale; the parallel `…-nxzj5` Completed pod kept for log preservation), and three Released PVs from the 2026-04-28 monitoring stack rebuild — `pvc-42e8545b-…` (10Gi, claim=monitoring/storage-kps-grafana-0), `pvc-86422179-…` (30Gi, claim=monitoring/prometheus-…-prometheus-0), `pvc-e2c29f7a-…` (5Gi, claim=monitoring/alertmanager-…-alertmanager-0); all on `standard-hdd`, all 4d old, all matching the expected claimRef pattern, no surprises. DB cluster (`knoe-dev-cnpg-0`): `kube-system/prole-supabase-dirprep` Job (FailureTarget, 22d stale, prole-era). Post-state: `kubectl get pv` shows 0 Released; gitlab namespace has only the Completed migration pod; DB-cluster kube-system has no prole-* artifacts. No source-side changes (kubectl-only ops).
|
||||
|
||||
@ -37,8 +37,9 @@ external Google Workspace — any verified Google account works once invited.
|
||||
|---|---|---|
|
||||
| Round 1 Kerberos enrollment | **Shipped** | Operational on GKE |
|
||||
| k3d dev loop (Phase 1 brief) | **Shipped** | `make k3d-knoe-up` |
|
||||
| Phase 2 OIDC provider | **Planned** | Resumes once k3d loop is in place — see TODO §Paused |
|
||||
| pg_oauth (PG18 OAUTHBEARER) | **Paused** | Needs Phase 2 OIDC issuer first |
|
||||
| Phase 2 OIDC provider — **k3d setup** | **Shipped** | `application-k3d.yml` + `etc/gen_oidc_signing_key.sh`; OIDC discovery / JWKS / token endpoints exercise locally. See [`docs/local-dev-knoe-auth.md`](local-dev-knoe-auth.md) §"Daily loop". |
|
||||
| Phase 2 OIDC provider — **GKE deploy** | **Pending** | Source on `main`; needs image rebuild (queue #3) + K8s Secret with signing key + env-var wiring on `knoe-auth-deployment.yaml`. |
|
||||
| pg_oauth (PG18 OAUTHBEARER) | **Paused** | Resumes once Phase 2 OIDC is deployed to GKE |
|
||||
| Round 1.5 OpenBao transit-key encryption | **Later** | `UserProvisioningService.java:84` TODO |
|
||||
|
||||
---
|
||||
@ -284,9 +285,14 @@ k3d modes.
|
||||
Maven artifact is already `knoe-auth.jar`; manifests still pull
|
||||
`knoe-authority:latest`. Needs image rebuild + registry push.
|
||||
|
||||
- **Phase 2 OIDC provider** — Paused. Resumes once the k3d dev loop
|
||||
(now in place) gives the OIDC implementation somewhere to run locally.
|
||||
Design doc: [`docs/knoe-auth-phase-2.md`](knoe-auth-phase-2.md).
|
||||
- **Phase 2 OIDC provider** — k3d dev sandbox **shipped 2026-05-02**.
|
||||
`application-k3d.yml` enables the OIDC surface; `etc/gen_oidc_signing_key.sh`
|
||||
generates a persistent RS256 keypair on first `make k3d-knoe-up`.
|
||||
Endpoints reachable locally: `/.well-known/openid-configuration`,
|
||||
`/jwks.json`, `/authorize`, `/token`, `/userinfo`. **GKE deploy still
|
||||
pending** — needs queue #3 (image rebuild as `knoe-auth:latest`) plus a
|
||||
K8s Secret holding the signing key and env-var additions on the
|
||||
deployment. Design doc: [`docs/knoe-auth-phase-2.md`](knoe-auth-phase-2.md).
|
||||
|
||||
- **pg_oauth (Phase 2 pg_hba)** — Paused. Replaces SCRAM with PG18
|
||||
native OAUTHBEARER; wires into `install.sh` / `supabase/deploy.sh`.
|
||||
|
||||
@ -86,22 +86,38 @@ export SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/knoe-db?sslmode=re
|
||||
export SPRING_DATASOURCE_USERNAME=knoe
|
||||
export SPRING_DATASOURCE_PASSWORD=knoe-dev-password
|
||||
|
||||
mvn -pl authority spring-boot:run
|
||||
# Phase 2 OIDC signing key — generated by `make k3d-knoe-up` (idempotent;
|
||||
# persisted at etc/secrets/knoe-auth-oidc-key.b64). If absent, OidcTokenService
|
||||
# falls back to an ephemeral key (loops still work; tokens just don't survive
|
||||
# a knoe-auth restart).
|
||||
export KNOE_AUTH_OIDC_SIGNING_KEY=$(cat etc/secrets/knoe-auth-oidc-key.b64)
|
||||
|
||||
mvn -pl authority spring-boot:run \
|
||||
-Dspring-boot.run.jvmArguments="-Djava.security.krb5.conf=$PWD/etc/krb5.local.conf" \
|
||||
-Dspring-boot.run.profiles=k3d
|
||||
```
|
||||
|
||||
The `k3d` Spring profile (`authority/src/main/resources/application-k3d.yml`)
|
||||
enables Phase 2 OIDC, points the issuer at `http://localhost:8080`, sets the
|
||||
Kerberos realm to `KNOE.LOCAL`, and aligns the datasource defaults with the
|
||||
port-forwards.
|
||||
|
||||
### Verify the loop
|
||||
|
||||
```bash
|
||||
curl http://localhost:8080/health
|
||||
# → ok
|
||||
# → {"status":"ok"}
|
||||
|
||||
curl http://localhost:8080/.well-known/openid-configuration | jq .issuer
|
||||
# → "http://localhost:5000"
|
||||
curl -s http://localhost:8080/.well-known/openid-configuration | jq .issuer
|
||||
# → "http://localhost:8080"
|
||||
|
||||
curl -s http://localhost:8080/jwks.json | jq '.keys[0].kty'
|
||||
# → "RSA"
|
||||
```
|
||||
|
||||
> **Note:** The issuer URL is configured in `authority/src/main/resources/application.properties`
|
||||
> (or `application-local.properties`). For local dev it defaults to `http://localhost:5000`
|
||||
> or `http://localhost:8080` depending on your profile. Check the startup log for the actual value.
|
||||
If `/.well-known/openid-configuration` returns 404, OIDC isn't enabled —
|
||||
verify you started with `-Dspring-boot.run.profiles=k3d` (or that the
|
||||
`k3d` profile is active in your IntelliJ run config).
|
||||
|
||||
---
|
||||
|
||||
@ -143,6 +159,8 @@ klist
|
||||
3. Set:
|
||||
- **Module:** `authority`
|
||||
- **Main class:** `dev.knoe.auth.KnoeAuthApplication`
|
||||
- **Active profiles:** `k3d` *(enables Phase 2 OIDC + dev-only defaults)*
|
||||
- **VM options:** `-Djava.security.krb5.conf=$PROJECT_DIR$/etc/krb5.local.conf`
|
||||
4. Under **Environment variables**, add:
|
||||
|
||||
```
|
||||
@ -150,8 +168,13 @@ KRB5_CONFIG=/path/to/knoe-db/etc/krb5.local.conf
|
||||
SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/knoe-db?sslmode=require
|
||||
SPRING_DATASOURCE_USERNAME=knoe
|
||||
SPRING_DATASOURCE_PASSWORD=knoe-dev-password
|
||||
KNOE_AUTH_OIDC_SIGNING_KEY=<paste contents of etc/secrets/knoe-auth-oidc-key.b64>
|
||||
```
|
||||
|
||||
IntelliJ's environment-variable field doesn't expand `$(cat …)` shell
|
||||
substitution, so paste the base64 string directly (it's one line, ~1.6 KB).
|
||||
Or use a `.env` plugin like *EnvFile* and point it at the `.b64` file.
|
||||
|
||||
5. Click **OK**, then **Run**.
|
||||
|
||||
Spring DevTools is active — saving a `.java` file triggers a hot reload automatically.
|
||||
|
||||
65
etc/gen_oidc_signing_key.sh
Executable file
65
etc/gen_oidc_signing_key.sh
Executable file
@ -0,0 +1,65 @@
|
||||
#!/usr/bin/env bash
|
||||
# gen_oidc_signing_key.sh
|
||||
#
|
||||
# Idempotent RS256 keypair generator for knoe-auth Phase 2 OIDC provider
|
||||
# in local k3d / TDD dev mode. Produces:
|
||||
#
|
||||
# etc/secrets/knoe-auth-oidc-key.pem PKCS#8 PEM of the private key
|
||||
# etc/secrets/knoe-auth-oidc-key.b64 single-line base64 of the same key,
|
||||
# suitable for KNOE_AUTH_OIDC_SIGNING_KEY
|
||||
#
|
||||
# Both files live under etc/secrets/ which is gitignored. If the .b64 file
|
||||
# already exists, the script is a no-op (so you keep stable token signatures
|
||||
# across restarts).
|
||||
#
|
||||
# Usage:
|
||||
# bash etc/gen_oidc_signing_key.sh # generate if missing
|
||||
# FORCE=1 bash etc/gen_oidc_signing_key.sh # rotate
|
||||
#
|
||||
# Env consumption (in your shell or the spring-boot:run command):
|
||||
# export KNOE_AUTH_OIDC_SIGNING_KEY=$(cat etc/secrets/knoe-auth-oidc-key.b64)
|
||||
#
|
||||
# Production (GKE) provides this via a K8s Secret + Workload Identity / OpenBao;
|
||||
# this script is for laptop dev only.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
SECRETS_DIR="${REPO_ROOT}/etc/secrets"
|
||||
PEM_PATH="${SECRETS_DIR}/knoe-auth-oidc-key.pem"
|
||||
B64_PATH="${SECRETS_DIR}/knoe-auth-oidc-key.b64"
|
||||
|
||||
mkdir -p "${SECRETS_DIR}"
|
||||
chmod 700 "${SECRETS_DIR}" 2>/dev/null || true
|
||||
|
||||
if [[ -f "${B64_PATH}" && "${FORCE:-0}" != "1" ]]; then
|
||||
echo "[gen_oidc_signing_key] already present at ${B64_PATH} — keeping. Pass FORCE=1 to rotate."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v openssl >/dev/null 2>&1; then
|
||||
echo "[gen_oidc_signing_key] ERROR: openssl not found on PATH." >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
echo "[gen_oidc_signing_key] generating RSA-2048 PKCS#8 keypair ..."
|
||||
# `openssl genpkey` writes a PEM-wrapped PKCS#8 private key. Spring's
|
||||
# OidcTokenService.init() reads KNOE_AUTH_OIDC_SIGNING_KEY as base64 of the
|
||||
# raw DER PKCS#8 bytes — i.e., the PEM with header/footer stripped and no
|
||||
# whitespace. We produce both forms.
|
||||
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 \
|
||||
-out "${PEM_PATH}" 2>/dev/null
|
||||
chmod 600 "${PEM_PATH}"
|
||||
|
||||
# Strip PEM headers/footers and newlines to get the single-line base64 of the
|
||||
# DER PKCS#8 bytes that the Java `Base64.getDecoder().decode(signingKey)` call
|
||||
# expects (per OidcTokenService.java).
|
||||
grep -v -- '-----' "${PEM_PATH}" | tr -d '\n' > "${B64_PATH}"
|
||||
chmod 600 "${B64_PATH}"
|
||||
|
||||
echo "[gen_oidc_signing_key] wrote ${PEM_PATH}"
|
||||
echo "[gen_oidc_signing_key] wrote ${B64_PATH} ($(wc -c < "${B64_PATH}") bytes)"
|
||||
echo
|
||||
echo "Use it in your shell:"
|
||||
echo " export KNOE_AUTH_OIDC_SIGNING_KEY=\$(cat ${B64_PATH})"
|
||||
@ -56,6 +56,18 @@ echo "│ export KNOE_DB_PASSWORD=${DB_PASSWORD} │"
|
||||
echo "│ export SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/knoe-db?sslmode=require │"
|
||||
echo "│ export SPRING_DATASOURCE_USERNAME=knoe │"
|
||||
echo "│ export SPRING_DATASOURCE_PASSWORD=${DB_PASSWORD} │"
|
||||
echo "│ # Phase 2 OIDC signing key (from etc/gen_oidc_signing_key.sh):│"
|
||||
echo "│ export KNOE_AUTH_OIDC_SIGNING_KEY=\$(cat etc/secrets/knoe-auth-oidc-key.b64)│"
|
||||
echo "├─────────────────────────────────────────────────────────────────┤"
|
||||
echo "│ Run knoe-auth with the k3d profile (enables OIDC + dev defaults):│"
|
||||
echo "│ mvn -pl authority spring-boot:run \\ │"
|
||||
echo "│ -Dspring-boot.run.jvmArguments=\"-Djava.security.krb5.conf=\$PWD/etc/krb5.local.conf\" \\│"
|
||||
echo "│ -Dspring-boot.run.profiles=k3d │"
|
||||
echo "├─────────────────────────────────────────────────────────────────┤"
|
||||
echo "│ Phase 2 OIDC endpoints (after knoe-auth is up): │"
|
||||
echo "│ GET http://localhost:8080/.well-known/openid-configuration │"
|
||||
echo "│ GET http://localhost:8080/jwks.json │"
|
||||
echo "│ POST http://localhost:8080/token │"
|
||||
echo "├─────────────────────────────────────────────────────────────────┤"
|
||||
echo "│ Press ^C to stop all port-forwards │"
|
||||
echo "└─────────────────────────────────────────────────────────────────┘"
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
# 4. Waits for CNPG cluster to be healthy
|
||||
# 5. Applies KDC manifests (configmap, pvc, deployment, service)
|
||||
# 6. Runs etc/init_knoe_auth.sh schema --mode k3d to seed knoe.* tables
|
||||
# 7. Generates a persistent RS256 keypair for Phase 2 OIDC signing
|
||||
# (etc/gen_oidc_signing_key.sh — idempotent; keeps existing key if present)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
@ -152,11 +154,14 @@ log "Provisioning KDC (realm KNOE.LOCAL)..."
|
||||
KNOE_MODE=k3d APP_CLUSTER_KUBECONTEXT="$CTX" \
|
||||
"$REPO_ROOT/etc/init_knoe_auth.sh" initialize --mode k3d --context "$CTX"
|
||||
|
||||
# ── 7. Phase 2 OIDC signing key (laptop-side) ────────────────────────────────
|
||||
log "Generating RS256 signing key for OIDC (idempotent) ..."
|
||||
bash "$REPO_ROOT/etc/gen_oidc_signing_key.sh" || die "OIDC keypair generation failed"
|
||||
|
||||
log ""
|
||||
log "=== k3d-knoe is up ==="
|
||||
log " CNPG cluster: kubectl --context=$CTX -n $DB_NS get cluster knoe-db"
|
||||
log " KDC: kubectl --context=$CTX -n $SYS_NS get deploy knoe-kdc"
|
||||
log ""
|
||||
log "Next: make k3d-knoe-pf (opens port-forwards)"
|
||||
log "Then: export KRB5_CONFIG=\$PWD/etc/krb5.local.conf"
|
||||
log " mvn -pl authority spring-boot:run"
|
||||
log "Next: make k3d-knoe-pf (opens port-forwards + prints env vars to export)"
|
||||
log "Then: see docs/local-dev-knoe-auth.md for the daily loop"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user