§38 Knative, Authentik and GitOps for Self-Hosted Loam

The 2026-10-02 boundary reconfirmation (D403) and what moved to `loam-platform`; Knative Serving for the `http-port` contract (`KnativeRunner`, per-namespace tenancy, Kourier behind the gateway, no meter) and Knative Eventing as an adapter to Loam streams; Authentik's open-source edition as the IdP (D404: the checked feature list, the RFC 8693 exchange for Loam tokens, groups to OpenFGA, blueprints, the Enterprise guard), replacing Keycloak; GitOps with Clever's open-source operator and CKE tooling under Argo CD, new waves, a Flux layout and the k3s profile; track MT (D440–D459)

Status: Proposed · 2026-10-02. Source: three owner rulings. On 2026-10-01 the owner wrote "loams multitenant also fully opensource using knative and for gitops clever cloud, for auth Authentik so no paid plan" and "all run on cloudflare using byoc". On 2026-10-02 the owner narrowed them: "keep loam cloud and loams-cloud private; may add Knative in OSS but no metering; I want adoption and also to raise money from VCs; move Cloudflare, OpenRTB etc. commercial to private repos." This document applies the 2026-10-02 ruling. It does not reopen the open-core boundary (D220, open-core.md), which stays as approved on 2026-09-29.

It turns the ruling into decisions D440–D459 and open questions Q440–Q453 (Q454–Q459 are reserved and unused). They are proposals until the owner rules on them. Plans: MT1 (Authentik identity), MT2 (Knative Serving and Eventing) and MT3 (GitOps).

Amends §19 (the IdP in front of Loam), §22 (D-SC-3: the suite's IdP), §24 (a Knative runner for the http-port contract), §25 (what "GitOps from Clever Cloud" means; new sync waves) and §27 (Knative pods under the hooks contract, with no meter). Narrows D111 (the unified auth plan) and D221 (SAML is brokered through Authentik, not Keycloak). The private side of the same ruling (the hosted Loams Cloud on Cloudflare, the protocol gateway, the Cloudflare target, the metering ledger) is designed in loam-platform. This repository does not depend on it.

Markers: (verify) means not checked against a primary source; the task that depends on it checks it first. (estimate) means computed, not measured. Every version, licence and status claim with a date was read on 2026-10-02 from the source named in §13.

Numbering. D440–D459 and Q440–Q459 are this document's reserved ranges; Q440–Q453 are used.


1. Summary

#DecisionStatus
D440The open-core boundary stands (D220, reconfirmed by the owner on 2026-10-02). Self-hosting a single organisation is open source; running the multi-tenant paid cloud is loam-platform. Knative, Authentik and the GitOps layout are self-hosting features, so they are open. No metering in this repository: only §27's hooks stay. The protocol gateway (§34) and the Cloudflare target (the former §35) move to loam-platform (private), and §34 becomes a stubProposed · owner ruling 2026-10-02
D441Knative Serving is an optional compute layer for the http-port contract (§24 D181, tier T2) in self-hosted clusters. KnativeRunner implements the Runner trait (D375): one Knative Service per function, one Revision per version, scale to zero, gVisor through runtimeClassName. The node supervisor stays the only runner for fetch (T0 workerd) and Wasm (T1), whose many-tenants-per-process model Knative cannot expressProposed
D442Knative's ingress is Kourier, inside the cluster, behind Loam's edge. Envoy stays the edge (D184); the gateway routes a function's traffic to Kourier's internal service with the tenant already checked. Knative's own domains are cluster-local (svc.cluster.local), so no function is reachable except through the gatewayProposed
D443Tenancy on Knative: one Kubernetes namespace per Loam namespace (loam-ns-<namespace>), with a default-deny NetworkPolicy, a ResourceQuota and a LimitRange set by loam-operator from the namespace's limits. The quota is enforced here; who sets it per plan is loam-platform's concern (D220). Every pod carries §27 §3.2's labelsProposed
D444No meter on Knative. KnativeRunner returns usage: None and writes no host reports, like the supervisor. Usage is visible only through the open hooks: §27 §3.2's pod labels on the pod cgroup, Knative's queue-proxy and activator Prometheus metrics, and the edge's access logs. Aggregating, rating and billing them is loam-platform (D190, D202)Proposed · owner ruling 2026-10-02
D445Knative Eventing is an adapter, not Loam's event log. Loam streams (D270) and the Event Fabric (§32 D331) stay the logs. Loam ships loam-knative-source, which reads a stream consumer group and delivers binary-mode CloudEvents to any Knative sink, and documents POST /v1/namespaces/{ns}/streams/{stream}/events as a Knative sink URI. The broker is the in-memory channel for development; the production broker is an open question (Q443)Proposed
D446Knative is installed by the Knative Operator (Apache-2.0), as KnativeServing and KnativeEventing resources pinned to 1.23 with the features Loam needs turned on (kubernetes.podspec-runtimeclassname, kubernetes.podspec-securitycontext). It is off by default in the umbrella chart (knative.enabled: false)Proposed
D447Authentik, open-source edition, is the default identity provider of the Kubernetes distribution and the showcase suite. It replaces Keycloak in D-SC-3 (§22) and in D221's "SAML brokered through Keycloak". It runs as an unmodified, separate service (Python, Postgres only since 2025.10), version 2026.8.3, and only code outside authentik/enterprise/ is used: no licence key is ever installedProposed
D448The usable feature list is fixed (§4.2): OAuth2/OIDC provider (authorization code with PKCE, client credentials with JWT federation, device code, refresh, token exchange (RFC 8693), dynamic client registration (RFC 7591)); SAML, SCIM (static token), LDAP, RADIUS (PAP), Proxy and RAC providers; OAuth, SAML, LDAP, Kerberos and SCIM sources; flows and stages with TOTP, WebAuthn and passkeys; RBAC; brands; blueprints; outposts. Everything listed as Enterprise on 2026-10-02 is excluded, multi-tenancy (tenants) includedProposed
D449Loam's gateway stays the resource server and the authority for Loam tokens (§19 §5). Authentik authenticates people: the console and the CLI sign in through it (OIDC authorization code with PKCE; device code for the CLI), and the gateway exchanges the Authentik token for a Loam access token. Agents stay Loam principals (§19 P5), with federation, delegation and vending on Loam's token endpoint; Authentik's "agent accounts" are Enterprise and are not used. Biscuit stays inside the runtime (D188), OpenFGA stays the authority (D66, D67), and Authentik groups reach OpenFGA as team tuples at sign-inProposed
D450The single binary keeps its built-in sign-in (§19 P7: setup token, password with argon2id, TOTP, generic OIDC). Authentik is the default only where Kubernetes is (the Helm chart, the operator, the showcase). A self-hoster may point Loam at any OIDC provider; Authentik is the documented and tested oneProposed
D451D111 is narrowed, not dropped. User identity, MFA, SSO and SAML brokering are Authentik's. What remains of the unified auth plan is Loam's side: token verification on every listener, API keys, agent tokens, TLS and leaving loopback. MT1 is that plan for the native API, the console and MCP; the other listeners follow it in their own plansProposed
D452Authentik is configured by blueprints in Git and installed from its upstream chart. Loam's blueprints (the Loam application and providers, the loam-* groups, the enrolment and MFA flows) are Apache-2.0 YAML under deploy/authentik/blueprints/. The upstream Helm chart (goauthentik/helm) is GPL-3.0, so it is referenced by an Argo CD Application, never copied or vendored into this repositoryProposed
D453"GitOps from Clever Cloud" means Clever's open-source operator and infrastructure tooling, not a Clever deployer. Clever Cloud publishes no GitOps reconciler or deployer (checked 2026-10-02; its git-push deployer is closed). So: loam-operator is the fork of clever-kubernetes-operator (MIT, D185); terraform-provider-clevercloud and karpenter-provider-clever-cloud (Apache-2.0) are used unmodified on Clever Kubernetes Engine; clever-tools is the CLI reference. Argo CD is not replaced (D186 stands)Proposed
D454The GitOps layout stays consumable by Flux. Argo CD is the default and the tested path; a Flux layout (deploy/gitops/flux/) with the same order through dependsOn is documented for the single-node k3s profile, where Argo CD's footprint matters (Q-RT-11)Proposed
D455New sync waves (§6.3): CloudNativePG and the Knative Operator join wave −1; Authentik's Postgres joins wave 1; Authentik and its blueprints join wave 2; KnativeServing and KnativeEventing join wave 3; loam-knative-source joins wave 5. Lua health checks are added for authentik blueprint instances, KnativeServing and KnativeEventingProposed
D456The reference small cluster is k3s (Apache-2.0, v1.37.1+k3s1) or k3d, started with --disable traefik so that Envoy and Kourier own ingress. MT2 and MT3 test on k3d in CI and on a single k3s node by handProposed
D457Licences (§9): Knative (Serving, Eventing, Operator, Kourier, func) Apache-2.0; Authentik MIT outside authentik/enterprise/, unmodified; the Authentik chart GPL-3.0, referenced only; CloudNativePG Apache-2.0; Argo CD and Flux Apache-2.0; the operator fork MIT with its notice kept. No enterprise or copyleft code is linked or vendoredProposed
D458A CI guard keeps Authentik free of the Enterprise edition: the chart values never set a licence, a blueprint lint rejects models from authentik_enterprise* and authentik_providers_* apps that live in the enterprise tree, and the MT1 e2e job asserts that GET /api/v3/enterprise/license/summary/ reports no licenceProposed
D459Track MT (§10): MT1 Authentik identity, MT2 Knative, MT3 GitOps. MT1 and MT2 are independent; MT3 wires both into the waves. Each is small, stacked PRs; none adds a dependency to operon's default buildProposed

2. Goals and non-goals

2.1 Goals

  1. Adoption. A self-hoster gets a serverless layer (scale to zero), a real identity provider (SSO, MFA, SAML) and a GitOps install from open source, with no paid plan anywhere in the stack.
  2. No new runtime in the engine. Knative and Authentik are separate services. The engine binary links neither, and the single-binary install works without them.
  3. The boundary holds. Nothing here meters, rates, invoices, provisions orgs across clusters or sets quotas per plan (D220).
  4. Every feature is checked against its licence. Authentik is open core, so each feature Loam uses is checked against the directory it lives in.

2.2 Non-goals

  • Metering, billing, multi-org control planes and BYOC management. These stay in loam-platform (D220, D440).
  • Running Loam on Cloudflare. The Cloudflare target is a commercial component in loam-platform (D440). The Fs trait's portable part stays here, in §36.
  • Replacing the node supervisor with Knative for T0 and T1 (D441).
  • Replacing Loam streams with Knative Eventing (D445).
  • Authentik multi-tenancy. It is Enterprise and alpha (§4.2). A self-hosted Loam has one org (§19 P3), so one Authentik tenant is enough.

3. Knative (D441–D446)

3.1 Where Knative fits in §24

§24 contractTierRunnerWhy
fetchT0 workerd, one process per tenant, isolates per versionSupervisorRunnerKnative scales pods; T0 packs many function versions into one per-tenant process. A pod per function would waste the isolate model
Wasm componentT1 wasmtime, many tenants per hostSupervisorRunnerSame: one host process serves many components
http-portT2, a container under gVisorKnativeRunner (when knative.enabled), else the supervisor's T2A server listening on $PORT is exactly a Knative Service; Knative adds scale to zero, concurrency-based autoscaling, revisions and traffic splitting
staticobject store and edgenoneUnchanged

So Knative replaces the hand-written T2 scheduler that F2 would otherwise need. F2 keeps the gVisor node setup and the gvisor RuntimeClass; the pod lifecycle becomes Knative's.

3.2 KnativeRunner

crates/operon-runner-knative (MT2) implements D375's trait over kube 3:

Runner methodKnative operation
deploy(cx, artifact)Server-side apply of a serving.knative.dev/v1 Service named fn-<function_id> in loam-ns-<namespace>, with the image by digest, runtimeClassName: gvisor, containerConcurrency from the manifest, autoscaling.knative.dev/min-scale: "0", max-scale from the namespace's limits, and the §27 §3.2 labels. Idempotent by digest: an unchanged digest creates no new revision
invoke(cx, dep, req)HTTP/2 over TLS to Kourier's internal service (Knative's internal TLS on; no cleartext fallback, because the Biscuit is a bearer token; MT2 Ruling 4) with Host: fn-<id>.loam-ns-<ns>.svc.cluster.local, the request's traceparent, and the runtime's Biscuit (D182) in x-loam-sandbox-token. usage: None (D444)
undeploy(cx, dep)Delete the Service; Knative garbage-collects its revisions
health()KnativeServing Ready, Kourier reachable
capabilities()contracts [http-port], suspend: false, cold start: Knative's (seconds, image-dependent) (estimate)

A function's traffic still enters through the gateway: the gateway authenticates, authorizes (OpenFGA), applies the namespace's rate limits, and only then calls Runner::invoke. Knative's activator buffers requests while a revision scales from zero.

Scale to zero. Knative's defaults (enable-scale-to-zero: "true", scale-to-zero-grace-period: "30s", read in config/core/configmaps/autoscaler.yaml at 1.23) apply. A namespace can set scale-to-zero-pod-retention-period through its manifest, within the operator's bound.

gVisor. Knative rejects runtimeClassName unless kubernetes.podspec-runtimeclassname is enabled in config-features (it is disabled by default at 1.23); D446 turns it on. kubernetes.podspec-securitycontext is turned on so the operator can set runAsNonRoot, readOnlyRootFilesystem and a seccomp profile. Kata is not used (D174).

3.3 Tenancy on Knative (D443)

  • One Kubernetes namespace per Loam namespace, loam-ns-<namespace>, created by loam-operator when the namespace is created and deleted with it. A Loam namespace is one environment (§19 P2), so a project's staging and production never share a Kubernetes namespace.
  • Network. A default-deny NetworkPolicy; ingress only from Kourier's pods; egress only to the gateway and loam-dapr (functions reach Loam through them, §24 §5), DNS, and whatever the namespace's egress policy allows.
  • Quotas. A ResourceQuota (CPU, memory, pod count, count/services.serving.knative.dev) and a LimitRange per namespace, computed by the operator from the namespace's limits record (D65). Knative's max-scale is capped by the same record.
  • Identity. Each function's pod runs with a service account that has no Kubernetes API rights (automountServiceAccountToken: false). Its Loam credential is the per-invocation Biscuit, never a long-lived secret (§19 P6).

3.4 Usage without a meter (D444)

Knative pods are T2 sandboxes in §27's terms, so §27 §3.2 already covers them: the pod cgroup with the labels loam.dev/org, loam.dev/namespace, loam.dev/function and loam.dev/tier (t2). Two more open hooks come for free and are documented, not built:

  • queue-proxy and activator metrics (Prometheus): request counts, latencies and concurrency per revision, which carry the revision's labels;
  • the edge's access logs, with x-loam-tenant set by the gateway (§27 §3.4).

KnativeRunner writes no HostReport; Q-UH-3 (the final cgroup reading for pods) applies unchanged. Whoever wants usage per tenant, a self-hoster's dashboard or loam-platform, reads these hooks.

3.5 Knative Eventing (D445)

Knative Eventing delivers CloudEvents from sources to sinks through Brokers and Triggers. Loam already has two logs: streams for databases, retrieval and trigger-rate events (D270), and the Event Fabric (Iggy and Fluss) for high-rate ingestion (§32 D331, D332). Eventing is neither; it is a delivery layer for teams that already use it.

DirectionHowDelivery
Knative → LoamAny Knative Trigger or Subscription can use http://loam-gateway.<ns>/v1/namespaces/{ns}/streams/{stream}/events as its subscriber.uri. Knative delivers binary-mode CloudEvents over HTTP, which is §02 §7.4's HTTP binary modeD270's dedupe on source + id makes Knative's retries safe
Loam → Knativeloam-knative-source, a small Rust service (one Deployment per LoamSource resource, a SinkBinding-style sink reference): it reads a stream through a consumer group and POSTs each record as a binary-mode CloudEvent to the sink, committing the offset after a 2xxAt least once; the sink dedupes on id
Fabric → Knativeloam-knative-source with an Iggy topic instead of a stream (after FL1)Same

The broker for development is InMemoryChannel (not durable). The production broker is open (Q443): Knative's Kafka broker over Loam's Kafka gateway (M5, D74), a Loam broker class over streams, or no broker (sources deliver to Services directly, which covers most uses). Loam's own triggers (functions subscribed to streams, §24) do not need Eventing at all.

Event types Loam defines use the owner's prefix io.loams.dev.<domain>.<name>.v1 (ruling of 2026-10-01).

3.6 What Knative does not change

  • §26 jobs. Queues, leases and schedules stay operon-jobs and Resonate (D205, D210). A Knative function can enqueue through loam.jobs.v1; Knative does not run job workers.
  • §21 durable execution. Long waits still go through Resonate (D173). A scaled-to-zero Knative revision is not a suspended durable function.
  • The edge. Envoy stays the edge (D184), and Kourier is internal (D442).

4. Authentik (D447–D452, D458)

4.1 The licence split, checked

The repository's LICENSE (read at version/2026.8.3, released 2026-09-17):

"All content that resides under the "authentik/enterprise/" directory of this repository, if that directory exists, is licensed under the license defined in "authentik/enterprise/LICENSE". … Content outside of the above mentioned directories or restrictions above is available under the "MIT" license."

authentik/enterprise/LICENSE is the authentik Enterprise Edition (EE) license:

"This software … may only be used in production, if you … have agreed to, and are in compliance with, the Authentik Subscription Terms of Service … and otherwise have a valid authentik Enterprise Edition subscription for the correct number of user seats. … you may copy and modify the Software for development and testing purposes, without requiring a subscription."

So the rule for Loam is: use only what is outside authentik/enterprise/, and never install a licence key (D447, D458). The enterprise code ships in the same image, but it is inactive without a licence.

4.2 What Loam may use

Checked against the source tree at 2026.8.3 (authentik/providers, authentik/sources, authentik/stages, authentik/enterprise/*) and the "Enterprise features" page (docs.goauthentik.io/enterprise/enterprise-features, read 2026-10-02):

FeatureWhere it livesLoam
OAuth2/OIDC provider: authorization code + PKCE, refresh, device code, client credentialsproviders/oauth2 (MIT)Use: console, CLI and showcase apps
Client credentials with JWT federation (a JWT from a configured provider authenticates a service account)providers/oauth2 (MIT)Use for CI and automation that signs in to Authentik
Token exchange (RFC 8693), impersonation and delegation with an act claim; since 2026.8.0providers/oauth2/views/token.py, common/oauth/constants.py (GRANT_TYPE_TOKEN_EXCHANGE) (MIT)Available; Loam's own token endpoint still does agent exchange (D449)
Dynamic client registration (RFC 7591)providers/oauth2/views/dcr.py (MIT)Not needed: MCP clients register with Loam's authorization server (§19 §5.2)
SAML providerproviders/saml (MIT)Use: SAML apps in the showcase
SCIM provider (outbound), static token authproviders/scim (MIT)Showcase apps only (§22 §7.3). Loam's own SCIM endpoint is loam-platform (D221, Q440)
SCIM provider with OAuth authenticationenterprise/providers/scim/auth_oauth2.pyExcluded
LDAP, Proxy and RAC providers, with outpostsproviders/ldap, providers/proxy, providers/rac (MIT)LDAP and Proxy for apps without OIDC; RAC not used
RADIUS provider (PAP)providers/radius (MIT)Not used
RADIUS EAP-TLSenterprise/providers/radiusExcluded
Sources: OAuth (GitHub, Google, any OIDC), SAML, LDAP, Kerberos, SCIM, Plex, Telegramsources/* (MIT)Use OAuth, SAML and LDAP sources so a company's own IdP federates in
The source stage (an external IdP embedded in a flow)enterprise/stages/sourceExcluded
Flows and stages: identification, password, TOTP, WebAuthn and passkeys, Duo, email, SMS, static recovery codes, consent, invitation, captcha, promptstages/* (MIT)Use: enrolment, MFA and recovery flows
Client-certificate (mTLS) stage, account lockdown, password-history policyenterprise/stages/mtls, enterprise/stages/account_lockdown, enterprise/policies/unique_passwordExcluded
RBAC (roles, object permissions)rbac (MIT)Use for Authentik's own admin
Brands (per-domain branding; called tenants before 2024.2)brands (MIT)Use: one brand per install
Multi-tenancy (tenants, a Postgres schema per tenant)the tenants app, gated: "an Enterprise feature … in alpha", one licence per additional tenant (docs.goauthentik.io/sys-mgmt/tenancy)Excluded; not needed (one org per install, §19 P3)
Blueprints (declarative YAML)blueprints (MIT)Use: all of Loam's Authentik configuration (D452)
Google Workspace and Microsoft Entra ID sync, Shared Signals Framework, WS-Federation, agent accountsenterprise/providers/*, enterprise/agentsExcluded
Enhanced audit (before and after values), event maps, CSV exports, reports, object lifecycle management, privileged access management, endpoint and device connectorsenterprise/audit, enterprise/reports, enterprise/lifecycle, enterprise/endpointsExcluded. Loam's own audit events (D221) cover Loam's actions

The "Enterprise features" page also lists "External OAuth and SAML sources embed an external identity provider in a flow". That is the source stage only: plain OAuth and SAML sources (federated login) are in sources/ under MIT.

Runtime. Since 2025.10 Authentik needs only Postgres: cache, sessions, WebSockets and the embedded outpost moved off Redis, with about 50% more Postgres connections (2025.10 release notes; goauthentik.io blog "We removed Redis", 2025-11-13). Its Postgres is a CloudNativePG cluster (D230), like the other showcase databases.

4.3 How Loam uses it (D449)

 person ── browser / loams CLI ─► Authentik (OIDC: code + PKCE, or device code; MFA, passkeys, SAML/LDAP/OAuth sources)
                                     │ ID token + access token (groups claim)
                                     ▼
                           loam-gateway  POST /api/v1/oauth/token
                           (RFC 8693: subject_token = Authentik token, trusted issuer)
                                     │ Loam access token (JWT, Ed25519, §19 §5.3)
                                     ▼
                  native API · console API · MCP · gateways  ──►  Authorizer (OpenFGA, D66)
 agent ── federation / delegation / vending on Loam's token endpoint (§19 §5.2, unchanged)
 sandbox ── Biscuit minted and attenuated by the supervisor (D188, unchanged)
  • People sign in through Authentik. The console uses the authorization-code flow with PKCE; loams login uses the device-code flow (providers/oauth2/views/device_*). Loam's gateway is an OIDC relying party (openidconnect 4, §19 §6) and keeps the session.
  • Loam issues Loam tokens. The gateway exchanges the Authentik token for a Loam access token on its own token endpoint (RFC 8693, §19 §5.2 flow 1, with Authentik registered as a trusted issuer). Every listener verifies only Loam tokens, so the verification code does not change with the IdP.
  • Agents are not Authentik users. An agent is a Loam principal with a trust policy (§19 §5.1). Authentik's agent accounts are Enterprise and are not used.
  • Groups reach OpenFGA at sign-in. The groups claim maps to Loam teams (§19 P4, "OIDC groups can map to teams"); the gateway writes team#member tuples through the outbox (D66) when a person signs in or refreshes. Removal takes effect at the next refresh (1 hour) or on session revocation. Continuous provisioning through SCIM stays a loam-platform feature (D221) unless the owner moves it (Q440).
  • SAML, LDAP and social logins are Authentik sources. Loam itself only ever speaks OIDC (D221 as amended).

4.4 Deployment (D452)

  • Chart. The upstream chart goauthentik/helm (authentik-2026.8.3) is GPL-3.0. Loam's umbrella chart does not include it; Loam's GitOps layout points an Argo CD Application at https://charts.goauthentik.io with Loam's values file. Nothing from the chart is copied into this repository.
  • Configuration as code. deploy/authentik/blueprints/loam.yaml creates the loam application, its OAuth2 provider (the console's and the CLI's clients, redirect URIs, the groups scope mapping), the loam-admins and loam-developers groups, and the enrolment and MFA flows. It is mounted into the worker through the chart's blueprints.configMaps, so Argo CD owns it.
  • Secrets. The bootstrap token, the secret key and the client secrets come through the same secret path as everything else (D189); none is committed.

4.5 What this replaces

BeforeAfter
§22 D-SC-3: Keycloak is the suite's IdP; §22 §4.4 preferred it for having "no enterprise split"Authentik (D447), restricted to the MIT tree with a CI guard (D458). Keycloak's advantage (no split) is answered by the guard; Authentik's are blueprints, built-in passkeys and outposts, and a smaller footprint after Redis was removed
§19 P7 and §19 §6: "SAML … brokered by an IdP (Keycloak, Dex, Authentik)"; "Keycloak brokers SAML to OIDC"Authentik is the documented and tested broker; any OIDC IdP still works (D450)
D221: "plain OIDC SSO, with SAML brokered through Keycloak by self-hosters""… brokered through Authentik" (D447). The rest of D221 is unchanged
D111: one unified auth plan after M1Narrowed (D451): MT1 is the identity half; listeners leave loopback as their plans adopt MT1's verifier
loam-cloud's Clerk (hosted console)Not changed here. Hosted identity is loam-platform's and loam-cloud's decision (D440)

5. Reconciling with §19, D67 and D188

MechanismAnswersChanged?
Authentik (OIDC)Who is this person; which groupsNew, in front of the gateway (D449)
Loam access tokens (JWT, §19 §5.3)This bearer is principal X with scopes S until TNo; issued after the exchange
Agent federation, delegation, vending (§19 §5.2)How an agent gets a token without a secretNo
Biscuit (D188)What this sandbox may do, attenuated offlineNo
OpenFGA (D66, D67)Who may do whatNo; groups become team tuples at sign-in

6. GitOps (D453–D456)

6.1 What Clever Cloud publishes

Checked on 2026-10-02 (GitHub organisation CleverCloud, and §25 §2's inventory of 2026-09-29):

ProjectLicence · releaseRole in Loam's GitOps
clever-kubernetes-operatorMIT · v0.8.0 (2026-06-09), pushed 2026-09-04Forked as loam-operator (D185): reconciles Loam, Function, RuntimePool, ObjectStore, and now the per-namespace Knative tenancy (D443)
terraform-provider-clevercloudApache-2.0 · v2.3.0 (2026-09-28)Infra under GitOps on Clever Kubernetes Engine (CKE)
karpenter-provider-clever-cloudApache-2.0 · v0.13.0 (2026-10-01)Node autoscaling on CKE
clever-toolsApache-2.0 · 5.0.2 (2026-09-16)Reference for the loams CLI's deploy UX (§30)
A GitOps reconciler, deployer or git-push build systemnone publishedClever's own deployer is closed (§25 §1)

So Clever supplies the operator skeleton and the infrastructure layer for CKE, and a GitOps engine is still needed. Argo CD (Apache-2.0, v3.5.3, 2026-09-14) stays that engine (D186); Flux (Apache-2.0, v2.9.6, 2026-10-01) is the documented alternative for the smallest profile (D454).

6.2 What the owner's ruling changes in §25

Nothing in D185–D188 is reversed. The forked operator gains work (namespaces, NetworkPolicy, ResourceQuota and Knative Services for D443), the waves gain components (D455), and infra/clever-cke/ stays the place for Clever's Terraform provider.

6.3 Sync waves (amends §25 §6.3)

Wave§25 todayAdded by D455
−2CRDsKnative Operator CRDs, CloudNativePG CRDs
−1operators, gVisor node setup, Karpenter on CKEKnative Operator, CloudNativePG operator
0RustFS—
1PD and TiKVauthentik-db (a CNPG Cluster)
2ResonateAuthentik (upstream chart, Loam values, blueprints)
3loam-dapr, gateway, EnvoyKnativeServing (with Kourier) and KnativeEventing, when knative.enabled
4Loam—
5runtime tiersloam-knative-source instances, when enabled

Health: Argo CD Lua checks for KnativeServing and KnativeEventing (status.conditions[type=Ready]), the CNPG Cluster (status.phase == "Cluster in healthy state") and Authentik (the worker's blueprint status through the server's /-/health/ready/). Flux's layout (D454) expresses the same order with dependsOn.

6.4 The small profile (D456)

k3s v1.37.1+k3s1 (2026-09-30) or k3d, started with --disable traefik. On it: Argo CD (or Flux), RustFS single-node, one PD and one TiKV, Authentik with one CNPG instance, and Knative Serving with Kourier. Footprints are measured in MT3 Task 6 and recorded beside Q-RT-11; until then they are unknown.

7. Moves out of this repository (D440)

WhatWasNow
The protocol gateway, OpenRTB and Google adapters, the canonical loam.rtb.v1, partner negotiation, the ad-tech conformance suite (D366–D371, D373, D377, D379) and plans GW1–GW4§34, merged in #177loam-platform (private). §34 is a stub that keeps the vendor-neutral decisions (the standards charter, the narrow waist, the CloudEvents profile, the high-rate path, state rules, the Runner trait, usage hooks from runners)
The Cloudflare target (CloudflareRunner, Workers, Durable Objects, R2, Containers placement, the startup credits plan) and plan CF1the former §35 (PR #179)loam-platform (private). §36 (Loam Git) and GT1–GT3 stay; the Fs trait and NativeFs move into §36
The usage CloudEvents form and its Arrow mapping (RN1 Task 6), and any ledgerRN1, §34 §12loam-platform. RN1 keeps the Runner trait, RunnerHost, the process and Lambda runners and §27's host-report emitter

8. Contradictions with earlier decisions, and how they are resolved

#EarlierThis documentResolution
1D-SC-3 (§22): Keycloak is the suite's IdPAuthentikSuperseded by D447
2D221: SAML brokered through KeycloakThrough AuthentikAmended by D447; the rest of D221 stands
3D111: one unified auth plan after M1MT1 plus each listener's planNarrowed by D451
4§19 P7, §6 name Keycloak as the SAML brokerAuthentikAmended (D447, D450); built-in sign-in kept
5§19 §3: Cloud identity "Clerk or Keycloak"—Not changed here (hosted is loam-platform, D440)
6D379 (§34): the adapters, negotiation and ad-tech conformance are Apache-2.0 hereloam-platformSuperseded by D440 (owner ruling 2026-10-02)
7The former §35 §2 (PR #179): CloudflareRunner and the Worker crates are Apache-2.0 hereloam-platform (private)Superseded by D440 before merge
8D376 item 4, RN1 Task 6: usage as CloudEvents, built hereMovedThe record spec (§27 §3.6) stays; the event form is loam-platform's (D444)
9D186: Argo CD"GitOps from Clever Cloud"No conflict: Clever has no GitOps engine (D453)
10§24 §11 F2: Loam schedules T2 sandboxesKnative schedules them when enabledRefined by D441; F2's gVisor setup stays
11§22 §4.4 rejected Authentik's split as a riskA CI guard (D458)Risk accepted with a guard

9. Licences (D457)

ComponentLicence (file, release)How used
Knative Serving, EventingApache-2.0 · knative-v1.23.0 (2026-07-28/29)Unmodified services
Knative Kafka brokerApache-2.0 · knative-v1.23.1 (2026-08-25)Only if Q443 picks it
KourierApache-2.0 · knative-v1.23.0Unmodified
Knative funcApache-2.0 · knative-v1.23.3 (2026-09-03)Optional developer tool
Knative OperatorApache-2.0 · knative-v1.23.1 (2026-09-01)Unmodified (D446)
AuthentikMIT outside authentik/enterprise/ (EE licence inside) · 2026.8.3 (2026-09-17)Unmodified image, no licence key (D458)
Authentik Helm chartGPL-3.0 (goauthentik/helm) · authentik-2026.8.3Referenced by URL; not vendored (D452)
CloudNativePGApache-2.0 · v1.30.1 (2026-09-23)Unmodified operator (D230)
Argo CD · FluxApache-2.0 · v3.5.3 · v2.9.6Unmodified
k3sApache-2.0 · v1.37.1+k3s1 (2026-09-30)Reference cluster (D456)
clever-kubernetes-operatorMIT · v0.8.0Forked, notice kept (D185)

Knative graduated in the CNCF on 2025-10-08 (CNCF announcement).

10. Track MT (D459)

PlanScopeDepends on
MT1Authentik blueprints and the CI guard; the gateway's OIDC sign-in against Authentik; the RFC 8693 exchange for Loam tokens; groups → teams → OpenFGA tuples; loams login with device code; the showcase moves from Keycloak§19's M2 identity work (the token endpoint, sessions); D66's outbox
MT2operon-runner-knative; per-namespace tenancy in loam-operator; Kourier routing from the gateway; loam-knative-source; the Knative sink docs; usage-hook conformance with no meterRN1 Tasks 1–3 (the trait); loam-operator (D185)
MT3New waves and health checks; the Authentik and Knative Applications; the Flux layout; the k3s small profile; CKE variantMT1 Task 1, MT2 Task 1; §25's layout

MT, like tracks R, D, J and GT, interleaves on the one-build machine: one cargo build at a time. MT1 and MT3 are mostly YAML and e2e scripts; MT2 adds two crates outside operon's default features.

11. Risks

RiskMitigation
A future Authentik release moves a feature Loam uses into authentik/enterprise/D458's guard runs on every Authentik bump; the pin moves only after MT1's e2e passes; the gateway's OIDC side is IdP-agnostic, so Keycloak remains a fallback
Authentik's monthly releases and security fixesPin a minor (2026.8.x), take patch releases promptly, record each bump (Q453)
Knative's cold start (image pull plus pod start) is far from T0's millisecondsKnative is for http-port only (D441); min-scale per function for latency-sensitive services, charged by nothing in OSS
Two schedulers (supervisor and Knative) for one runtimeThey own different contracts (§3.1); the Runner trait hides which one runs a function
Kourier and Envoy both in the pathKourier is internal and small; Q446 asks whether net-gateway-api on Envoy Gateway removes Kourier
Usage under Knative is coarser than the supervisor's (pod cgroup, not per invocation)Accepted: no metering in OSS (D444); per-invocation precision for billing is loam-platform's problem
Removing §34 and §35 leaves references dangling in other branches§34 stays as a stub at the same path; §36 was edited to match; the decision log records what moved (one row per moved range)

12. Open questions

#QuestionOwnerNeeded by
Q440Authentik's SCIM provider is free, and Loam could accept SCIM in OSS. Keep SCIM provisioning in loam-platform (D221), or move it to OSS for adoptionFounderMT1 Task 5
Q441Keep the single binary's built-in password and TOTP (§19 P7), or make an external OIDC IdP mandatory once MT1 landsFounderMT1 Task 0
Q442Hosted Loams Cloud identity: Clerk (in loam-cloud today) or Authentik, given the 2026-10-01 "no paid plan" ruling. Decided in loam-platform, recorded here only for the cross-referenceFounderBefore the hosted beta
Q443Knative Eventing's production broker: the Kafka broker over Loam's Kafka gateway (M5), a Loam broker class over streams, or noneEngMT2 Task 6
Q444gVisor mandatory for every KnativeRunner function, or optional for trusted single-org codeFounderMT2 Task 2
Q445Should KnativeRunner emit per-invocation request and wall-time reports (no CPU) for showback dashboards, or stay at usage: None (D444)FounderMT2 Task 4
Q446Kourier, or net-gateway-api on Envoy Gateway so Envoy is the only proxyEngMT2 Task 3
Q447Authentik's Postgres: CloudNativePG now (D230), Loam Postgres (§28) laterEngMT3 Task 3
Q448Does Authentik's OIDC provider send back-channel logout, so a removed user's Loam session ends before its refresh (verify)EngMT1 Task 4
Q449Flux as the default for the single-node profile, if MT3 measures Argo CD as too heavy (merges Q-RT-11)EngMT3 Task 6
Q450Give §34's retained vendor-neutral decisions (D360–D365, D372, D374, D378) their own OSS document, and split GW1's vendor-neutral tasks (buf breaking, the CloudEvents profile) into an OSS planFounderBefore GW1's plan starts in loam-platform (private)
Q451The loam.dev/* pod labels of §27 §3.2 under the loams rename: keep, or move to loams.dev/* with the rename PREngRename PR
Q452loam-knative-source for Iggy topics (§32): in MT2 or with FL1EngAfter FL1
Q453Authentik upgrade cadence and who takes security patches for self-hosters (chart values pinned in Loam's layout)EngMT3 Task 2

13. Sources

Read on 2026-10-02 unless a date is given.

  • The owner's rulings of 2026-10-01 and 2026-10-02 (quoted in the status line).
  • Authentik: github.com/goauthentik/authentik at version/2026.8.3 (released 2026-09-17): LICENSE; authentik/enterprise/LICENSE (the EE licence); directory listings of authentik/providers (ldap oauth2 proxy rac radius saml scim), authentik/sources (kerberos ldap oauth plex saml scim telegram), authentik/stages, authentik/enterprise/providers (google_workspace microsoft_entra radius scim ssf ws_federation), authentik/enterprise/stages (account_lockdown authenticator_endpoint_gdtc mtls source), authentik/enterprise/{agents,audit,endpoints,lifecycle,policies,reports}; authentik/common/oauth/constants.py (GRANT_TYPE_TOKEN_EXCHANGE); authentik/providers/oauth2/views/ (token.py, dcr.py, device_*). Docs: docs.goauthentik.io/enterprise/enterprise-features; docs.goauthentik.io/sys-mgmt/tenancy ("This feature is in alpha"; Enterprise; a licence per additional tenant); docs.goauthentik.io/add-secure-apps/providers/oauth2/token_exchange (2026.8.0+, act claim); docs.goauthentik.io/add-secure-apps/providers/oauth2/client_credentials (JWT federation); docs.goauthentik.io/releases/2025.10 and goauthentik.io/blog/2025-11-13-we-removed-redis. Chart: github.com/goauthentik/helm (GPL-3.0, authentik-2026.8.3).
  • Knative: knative/serving and knative/eventing releases knative-v1.23.0 (2026-07-29, 2026-07-28), Apache-2.0; knative/serving config/core/configmaps/features.yaml (kubernetes.podspec-runtimeclassname: "disabled") and config/core/configmaps/autoscaler.yaml (enable-scale-to-zero: "true", scale-to-zero-grace-period: "30s"); knative-extensions/eventing-kafka-broker knative-v1.23.1 (2026-08-25); knative-extensions/net-kourier knative-v1.23.0; knative/func knative-v1.23.3 (2026-09-03); CNCF announcement "Cloud Native Computing Foundation Announces Knative's Graduation" (2025-10-08).
  • Clever Cloud: CleverCloud/clever-kubernetes-operator (MIT, v0.8.0, pushed 2026-09-04); CleverCloud/terraform-provider-clevercloud (Apache-2.0, v2.3.0, 2026-09-28); CleverCloud/clever-tools (Apache-2.0, 5.0.2, 2026-09-16); a repository search of the organisation for GitOps, deploy and operator projects (no reconciler or deployer found); §25 §2.
  • Argo CD v3.5.3 (2026-09-14), Flux v2.9.6 (2026-10-01), k3s v1.37.1+k3s1 (2026-09-30): GitHub releases, Apache-2.0.
  • This repository: §02 §7.4, §19, §21, §22 §4.4, §24 (§4, §7, §16), §25 (§1, §4, §6), §26, §27 (§3.2, §3.6), §32 (branch flow-fabric-house-design, D331–D332), §34, docs/open-core.md; D65, D66, D67, D111, D184–D188, D190, D202, D220, D221, D230, D270, D375, D376.

On this page