Groundfloor Docs

Keycloak Integration

How Control Plane authenticates Customer Portal and API users via the platform Keycloak realm.

Control Plane uses Keycloak as the identity provider for the Customer Portal (app.groundfloor.cloud) and Operator Admin (admin.groundfloor.cloud). Every /v1/* request carries a Bearer JWT verified against the platform realm.

This page covers Control Plane auth — signing into Groundfloor's own portals and APIs. Optional per-workspace site auth is a separate feature; see Workspace site auth.

Flow

User → Keycloak login → access_token (JWT)
     → Customer Portal or API client
     → Authorization: Bearer <token>
     → Control Plane verifies iss + signature
     → sub resolved to internal users.id
     → SpiceDB CheckPermission for the requested action

Principal model

After JWT verification, handlers receive a Principal with:

FieldSourceUsage
subject_idJWT subStable IdP user ID
emailJWT claimDisplay, membership lookup
idp_providerConfig"keycloak" today
scopesJWTOptional fine-grained claims

Control Plane maps sub → internal users.id on each request. Authorization always uses the internal user ID when writing SpiceDB relationships.

Environments

SurfaceProductionDevelopment
Customer Portalapp.groundfloor.cloudlocalhost:3000
Control Plane APIdev-platform.groundfloor.cloudlocalhost:8088
Keycloak issuerPlatform realm URLLocal or shared dev realm

Tenant provisioning

In production, customers typically do not self-serve account creation. Groundfloor operators provision accounts via POST /v1/admin/accounts with an owner email unless ALLOW_CUSTOMER_ACCOUNT_CREATE=true.

On create, Control Plane:

  1. Creates or attaches the Keycloak realm user
  2. Upserts the Portal users row
  3. Grants owner membership on the new account

One human may belong to multiple accounts (same sub, multiple memberships).

API authentication

See API Authentication for headers, error codes, and curl examples.

On this page