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>
|
||
|---|---|---|
| .idea/runConfigurations | ||
| archive/2026-04-cnpg-and-gitlab-cleanup | ||
| authority | ||
| conf | ||
| demo | ||
| deploy | ||
| docs | ||
| etc | ||
| gitea | ||
| img | ||
| infrastructure | ||
| k3s | ||
| k8s | ||
| knoe | ||
| knoe-db | ||
| mock_val | ||
| modes | ||
| monitoring | ||
| scan | ||
| scripts | ||
| src | ||
| supabase | ||
| tests | ||
| .coveragerc | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| AGENTS.md | ||
| ansible_min.cfg | ||
| ansible.cfg | ||
| ansible.sh | ||
| BUILD.md | ||
| CLAUDE.md | ||
| config.py | ||
| config.sh | ||
| deploy.sh | ||
| env.sh | ||
| Executing | ||
| install.sh | ||
| knoe-db.iml | ||
| knoe.iml | ||
| knoe.sh | ||
| knoe.spec | ||
| LICENSE | ||
| Makefile | ||
| pom.xml | ||
| pyproject.toml | ||
| qodana.yaml | ||
| README.md | ||
| requirements-test.txt | ||
| requirements.txt | ||
| run_with_coverage.sh | ||
| status.py | ||
| supabase.sh | ||
| update.sh | ||
Knoe
Knoe makes it practical to run a Supabase-style platform across air-gapped, edge, and cloud environments.
It packages the core building blocks needed for a modern internal developer platform around PostgreSQL, object storage, secrets, auth, observability, and Kubernetes-native operations — with a bias toward simple deployment, shard-based scale-out, and deterministic ingestion.
Platform badges
What Knoe is
Knoe is an infrastructure stack for running a Supabase-like data and application platform across constrained, sovereign, and cloud environments, including:
- air-gapped networks
- edge and small-cluster deployments (K3s, K3d)
- Google Cloud Platform (GCP) deployments
- sovereign or private data environments
- disconnected labs and field systems
- internal platforms where cloud dependencies are undesirable
The design goal is not to mimic Supabase branding or every managed feature exactly.
The design goal is to provide the useful substrate people actually want:
- PostgreSQL as the center of gravity
- object storage
- auth integration
- secret management
- ingress and service exposure
- observability
- reproducible Kubernetes deployment
- application and worker services around the database
- ingestion patterns that are safe, resumable, and idempotent
Core idea
Knoe can run Supabase-style workloads in an air gap, on the edge, or in the cloud.
That means:
- PostgreSQL remains the system of record, managed as
knoe-dbwithin theknoe-systemnamespace - services are deployed on Kubernetes (K3d locally, K3s on-prem, GKE on GCP)
- auth can come from local identity systems or cloud OIDC where available
- object storage stays inside the environment
- secrets stay inside the environment
- ingestion does not depend on live internet services
- the stack can be deployed in shards for locality, resilience, and operational simplicity
Main components
Application layer
- Next.js app for the user-facing platform
- knoe-agent worker for async and background execution
Data layer
- knoe-db — CloudNativePG-managed PostgreSQL cluster in the
knoe-systemnamespace - PostgreSQL as the primary relational store
- append-only fact tables for durable ingestion and replay-friendly modeling
- PostgreSQL COPY for efficient bulk ingest
Deployed add-ons
- Supabase — self-hosted Supabase stack for auth, realtime, storage, and API gateway
- ArgoCD — GitOps continuous delivery for the
knoe-systemcluster - Gitea — lightweight self-hosted Git service
- GitLab — full-featured self-hosted DevOps platform
Storage and secrets
- Garage for S3-compatible object storage
- OpenBao for secret storage and secret distribution
Identity
- Dev auth: Samba AD + IdP
- Cloud auth: Google Workspace OIDC
Observability
- Vector for log and event shipping
- Prometheus / Grafana for metrics and dashboards
Platform operations
- K3d — local development clusters
- K3s — on-prem lightweight Kubernetes
- GCP / GKE — cloud-hosted cluster tier
- Helm
- ArgoCD
- Ansible
- OpenTofu
Ingestion model
Knoe is designed around deterministic, replayable ingestion.
Key patterns:
- SQLite delta cartridges as portable input units
- append-only fact tables for auditability and recovery
- PostgreSQL COPY for high-throughput loading
- queue-driven workers using
SKIP LOCKED - idempotent ingestion so retries are safe
- shard-based deployment so data movement stays deliberate and bounded
This makes the platform well suited to environments where data may arrive in batches, be transferred physically, or need careful replay and provenance.
Architecture at a glance
flowchart LR
subgraph Clients
U["Users / Operators"]
end
subgraph knoe-system ["knoe-system (Kubernetes)"]
A["Next.js App"]
W["knoe-agent worker"]
SB["Supabase\n(auth · realtime · storage · API)"]
ARGO["ArgoCD\n(GitOps)"]
GITEA["Gitea\n(Git)"]
GITLAB["GitLab\n(DevOps)"]
PG["knoe-db\n(CloudNativePG / PostgreSQL)"]
OBJ["Garage\n(Object Store)"]
SEC["OpenBao\n(Secrets)"]
OBS["Vector / Prometheus / Grafana\n(Observability)"]
ING["Traefik / Kong\n(Ingress)"]
end
subgraph Infra ["Infrastructure"]
K3D["K3d\n(local dev)"]
K3S["K3s\n(on-prem)"]
GCP["GCP / GKE\n(cloud)"]
end
subgraph Identity
AUTH["Samba AD / Google Workspace OIDC"]
end
U --> ING
ING --> A
ING --> SB
ING --> ARGO
ING --> GITEA
ING --> GITLAB
A --> PG
A --> OBJ
A --> SEC
A --> AUTH
W --> PG
W --> OBJ
W --> SEC
SB --> PG
SB --> OBJ
SB --> AUTH
ARGO --> A
ARGO --> W
ARGO --> SB
ARGO --> PG
ARGO --> OBJ
ARGO --> SEC
GITEA --> ARGO
GITLAB --> ARGO
K3D & K3S & GCP --> |hosts| knoe-system
OBS -.-> PG
OBS -.-> A
OBS -.-> W
Deployment model
Knoe favors simple, understandable deployment over excessive platform ceremony.
Typical characteristics:
- Kubernetes-native deployment across K3d (local), K3s (on-prem), and GCP (cloud)
- lightweight K3s/K3d-friendly footprint
- HA where it matters
- shard-oriented layout instead of one giant control surface
- GitOps-driven operations via ArgoCD, backed by Gitea or GitLab
- support for small clusters, including Pi-based or edge environments
Use cases
Knoe is a good fit for teams that need:
- a PostgreSQL-centered application stack inside a disconnected or sovereign environment
- a self-hosted substrate for Supabase-style internal platforms
- ingestion from offline or intermittently connected sources
- reproducible deployment on small Kubernetes clusters (K3s/K3d) or GCP
- strong control over secrets, storage, and identity boundaries
- a full GitOps workflow with ArgoCD, Gitea, and GitLab
Project principles
- Air-gap first
- Postgres first
- Simple over ornate
- Deterministic ingestion
- Kubernetes-native
- Shard-friendly
- Operationally boring where possible
Repository scope
This repository contains the infrastructure and platform materials used to stand up Knoe components, including Kubernetes deployment, database operations (knoe-db in knoe-system), storage, auth, observability, and supporting services.
As the project evolves, this README should stay focused on:
- what Knoe is
- why it exists
- the major building blocks
- the deployment model
- the operational philosophy
Detailed setup docs, cluster procedures, and host-specific notes should live in dedicated documents under docs/, ops/, k8s/, or role-specific subdirectories rather than expanding this file indefinitely.
Status
Knoe is an actively evolving platform stack aimed at practical self-hosted, edge, and cloud operation.
Expect the architecture to continue being refined toward:
- cleaner bootstrapping
- better shard isolation
- smoother rejoin/reset behavior for cluster nodes
- clearer service boundaries
- improved onboarding and operations documentation
License
Add the project license here.