Groundfloor Docs

Architecture

How the Customer Portal, Control Plane API, Dataplane, Coderunner, and Shell interact.

Request flow (Customer Portal)

sequenceDiagram
  participant Browser
  participant Portal as Customer Portal
  participant KC as Keycloak
  participant API as Control Plane API
  participant SP as SpiceDB
  participant PG as Postgres

  Browser->>Portal: Load page
  Portal->>KC: OIDC login
  KC-->>Browser: JWT
  Browser->>API: GET /v1/workspaces (Bearer JWT)
  API->>KC: Validate JWT
  API->>SP: CheckPermission(read)
  SP-->>API: allowed
  API->>PG: Query workspaces
  API-->>Browser: JSON response

Control Plane backend

LayerTechnologyPurpose
APIFastAPI (Python 3.12)REST routers per pillar
StatePostgres (gf_controlplane)Accounts, workspaces, audit, metadata
AuthorizationSpiceDB (gRPC)ReBAC — schema in schema.zed
IdentityKeycloakCustomer JWT (Clerk legacy via IDP_PROVIDER=clerk)
Object storageS3-compatible (MinIO local)Files, published remoteEntry.js
SecretsInfisical (pluggable backend)Workspace-scoped secrets
LogsLoki via Fluent BitProcess log, observability
LLMLiteLLMWorkspace virtual keys + CU billing
EventsRedpandaLifecycle events, billing CU emission

Federated app flow

graph LR
  Portal[Customer Portal<br/>register + publish]
  API[Control Plane<br/>manifest + bootstrap]
  Store[(Object store<br/>remoteEntry.js)]
  Shell[Shell host<br/>Module Federation]
  Remote[Federated remote<br/>your React app]

  Portal --> API
  Portal --> Store
  Shell --> API
  Shell --> Store
  Shell --> Remote
  Remote --> API
  1. Register app + publish remoteEntry.js in the Portal
  2. Control Plane stores manifest + bootstrap metadata in Postgres
  3. Shell host calls the public bootstrap API to load the remote URL
  4. Federated remote calls workspace-scoped Control Plane APIs with Keycloak JWT

Edge routing (Coderunner public URLs)

The front door is a stateless Caddy edge proxy. Control Plane is the source of truth for hostname → upstream routing via /v1/public/route and TLS authorization via /v1/public/tls-authorize.

See Front Door integration for deployment details.

On this page