Setting Up Platform Authority In KDCube
KDCube can turn a browser user into a platform user through Cognito, multiple Cognito pools, a local SimpleIDP, or
an application-hosted login. These are not interchangeable — they differ in who proves the user, which credential is
written, and which verifier accepts it. This overview puts all methods side by side, anchored on one contract:
Connection Hub defines the provider, assembly.yaml selects it, /api/cp-frontend-config
tells the browser how to log in, and /profile is the source of truth.
KDCube can run with more than one way to make a browser user into a platform user. A deployment may use Cognito, trust multiple Cognito pools, use a local SimpleIDP for development, or let an application host the login flow while Connection Hub still owns the platform authority registry.
Those options are not interchangeable implementation details. They define:
who proves the user?
where the login UI lives?
which browser credential is written?
which server verifier accepts it?
where roles and grants are configured?
how /profile decides whether the browser is logged in?
how a runtime can safely switch from one provider to another?
This article is the overview. The companion piece Your Application As A Platform Authority zooms into one option — the application-hosted flow. This one shows all platform-authority methods side by side so a developer or deployment owner can choose one without mixing the contracts.
The common contract
No matter which provider is selected, the rest of KDCube wants one thing:
KDCube platform subject
authority_id = kdcube.platform
roles / permissions
session accepted by /profile
economics subject and provenance
The platform frontend should not hardcode how that session is created. It asks
GET /api/cp-frontend-config and receives the current browser auth contract:
{
"auth": {
"authType": "cognito | simple | bundle",
"oidcConfig": { "authority": "...", "client_id": "..." },
"loginUrl": "/api/integrations/bundles/.../public/platform_login",
"profileUrl": "/profile",
"logoutUrl": "/api/platform/logout",
"authTokenCookieName": "__Secure-LATC",
"idTokenCookieName": "__Secure-LITC"
}
}
oidcConfig is present for Cognito-style browser OIDC; loginUrl is present when an
application hosts the login page; profileUrl is always the server-side truth. A client may have local
OIDC state, a visible email, or a "Logout" button, but it is not authenticated until /profile returns
a non-anonymous platform user.
The word bundle still appears in current implementation identifiers such as auth.type:
bundle and bundle_session_login. The reader-facing product concept is
application-hosted platform authority: an application hosts the login/consent experience, while
Connection Hub owns the authority registry and KDCube verifies a normal platform session.
Option matrix
| Method | Login UI | Server verifier | Browser credential | Use when |
|---|---|---|---|---|
| Cognito | Cognito Hosted UI / OIDC provider | Cognito auth manager (selected through Connection Hub provider config) | LATC access token + LITC ID token | One Cognito pool/client is the platform login. |
| Multi-Cognito | Browser logs into one configured OIDC provider | Multi-Cognito verifier trusts a configured pool/client list | LATC + LITC | One runtime must accept platform tokens from multiple trusted Cognito providers. |
| SimpleIDP | Local/simple login or seeded token | SimpleIDP verifier | LATC simple token or Authorization header | Local development, test environments, embedded demos. |
| Application-hosted | Application page from auth.loginUrl | Application-session verifier using a KDCube kst1 session token | LATC application-session token; LITC not required | Branded/custom login or non-Cognito upstream proof (Google, portal SSO, another app identity). |
All four methods produce the same downstream fact — /profile returns a non-anonymous
kdcube.platform user — which is the contract widgets, chat, memories, usage, admin surfaces,
economics, and external-client consent rely on.
Server configuration: selection versus definition
There are two separate configuration questions: assembly.yaml selects which platform
authority provider is active, and the connection-hub@1-0 config in bundles.yaml
defines provider details, trusted issuers, entrypoints, roles, and cookies.
assembly.yaml stays small:
auth: auth: # application-hosted
type: cognito type: bundle
connection_hub: idp: session
bundle_id: connection-hub@1-0 connection_hub:
authority_id: kdcube.platform bundle_id: connection-hub@1-0
provider_id: cognito authority_id: kdcube.platform
provider_id: product_google_session
entrypoint: login
The definition lives under Connection Hub:
items:
- id: connection-hub@1-0
config:
authority_registry:
authorities:
kdcube.platform:
label: KDCube platform authority
platform: true
providers:
<provider_id>:
type: <provider_type>
enabled: true
authenticator: ...
issuer: ...
entrypoints: ...
grants: ...
This split matters. The platform shell, gateway, and application widgets should not re-invent provider URLs or
parse the Connection Hub registry directly. They consume /api/cp-frontend-config and
/profile.
Cognito and Multi-Cognito
Cognito and multi-Cognito are platform-managed token authorities. The browser uses an OIDC authorization-code flow and writes the platform token cookies.
Browser opens /platform/chat
-> /api/cp-frontend-config returns authType=cognito + oidcConfig
-> browser redirects to OIDC/Cognito
-> OIDC redirects back to /platform/callback?code=...&state=...
-> browser OIDC client receives access token + ID token
-> browser writes __Secure-LATC (access) + __Secure-LITC (ID)
-> /profile verifies through Cognito / Multi-Cognito
authority_registry:
authorities:
kdcube.platform:
platform: true
providers:
cognito:
type: multi_cognito
enabled: true
authenticator:
type: cognito_id_token
region: eu-west-1
user_pool_id: eu-west-1_PRIMARY
app_client_id: primary-client
cookie:
auth_token_cookie_name: __Secure-LATC
id_token_cookie_name: __Secure-LITC
trusted_providers:
- { alias: primary, kind: cognito, region: eu-west-1, user_pool_id: eu-west-1_PRIMARY, app_client_id: primary-client }
- { alias: peer, kind: cognito, region: eu-west-1, user_pool_id: eu-west-1_PEER, app_client_id: peer-client }
Single Cognito is the same shape with one trusted provider. Multi-Cognito does not mean the browser logs into
multiple providers — it means the server verifier accepts tokens whose issuer/client match any configured trusted
provider. The callback /platform/callback?code=...&state=... is normal OIDC; it is not the
application-hosted session flow.
SimpleIDP
SimpleIDP is for local, development, and controlled test deployments.
Simple login/token issue
-> browser or host receives a simple platform token
-> token carried in Authorization or __Secure-LATC
-> SimpleIDP verifier resolves the kdcube.platform user
-> /profile returns non-anonymous
providers:
simple:
type: simple_idp
enabled: true
authenticator:
type: simple_idp_token
cookie:
auth_token_cookie_name: __Secure-LATC
SimpleIDP has no OIDC callback and does not need __Secure-LITC.
Application-hosted platform authority
Application-hosted platform authority is for deployments where the product wants its own login page, upstream proof, or consent presentation.
Browser opens /platform/chat
-> /api/cp-frontend-config returns authType=bundle + auth.loginUrl
-> browser opens the application login page
-> user completes upstream proof, e.g. a Google ID token
-> application public operation calls the Connection Hub SDK runtime
-> SDK resolves the provider, verifies the proof, resolves grants
-> SDK issues a KDCube application-session token
-> server writes __Secure-LATC = kst1 application-session token
-> /profile verifies through the application-session verifier
providers:
product_google_session:
type: bundle_session_login
enabled: true
label: Google sign-in for KDCube
entrypoints:
login: { bundle_id: product-app@1-0, route: public, operation: platform_login }
session_issue: { bundle_id: product-app@1-0, route: public, operation: auth_google_session }
consent: { bundle_id: product-app@1-0, route: public, operation: delegated_consent }
input:
authenticator_ref: { authority_id: google.accounts, provider_id: google_oidc }
issuer:
type: kdcube_session_token
ttl_seconds: 43200
cookie: { auth_token_cookie_name: __Secure-LATC, secure: true, same_site: lax }
grants:
default: { roles: [kdcube:role:registered], permissions: [] }
assignable: { roles: [kdcube:role:registered, kdcube:role:super-admin] }
google.accounts:
platform: false
providers:
google_oidc:
type: google_id_token
authenticator:
client_id: <google-client-id>.apps.googleusercontent.com
The application hosts UI and calls the SDK; it does not own platform policy. The application owns login/consent
presentation and branding; Connection Hub owns the authority_registry, entrypoints, input
authenticator reference, issuer settings, and grants; the platform owns
/api/cp-frontend-config, /profile, logout, the session verifier, economics projection,
and surface enforcement.
Cookies, headers, and APIs
| Method | /api/cp-frontend-config | Browser credential | /profile verifier |
|---|---|---|---|
| Cognito | authType: cognito, oidcConfig present | __Secure-LATC + __Secure-LITC | Cognito verifier |
| Multi-Cognito | authType: cognito, trusted providers in server config | __Secure-LATC + __Secure-LITC | Multi-Cognito verifier |
| SimpleIDP | authType: simple or simple local config | __Secure-LATC simple token or Authorization header | SimpleIDP verifier |
| Application-hosted | authType: bundle, loginUrl present | __Secure-LATC kst1 session token | application-session verifier |
The stable APIs are GET /api/cp-frontend-config, GET /profile, and the logout POST
(usually /api/platform/logout). The client should not infer auth state from local storage, OIDC
cache, a visible email, or a readable cookie. The source of truth is /profile.
Switching between providers
Switching providers on one origin is where most test confusion happens. Browser cookies are scoped by origin/path/name — not by tenant/project or descriptor.
Safe switch procedure:
1. If the old runtime is still running, call its auth.logoutUrl.
2. Stop or refresh the old runtime.
3. Clear site data for the origin if logout is unavailable or stale HttpOnly cookies may exist.
4. Start the new runtime.
5. Open /api/cp-frontend-config; confirm authType, loginUrl/oidcConfig, profileUrl, logoutUrl, cookies.
6. Complete login.
7. Open /profile — trust the session only when it returns a non-anonymous platform user.
If a client visually looks logged in but /profile says anonymous, the client is wrong. Reset the
provider flow, cookies, or proxy routing until /profile is coherent.
Summary
Platform authority setup is not "pick a login screen." It is the contract that turns a browser into a KDCube platform user. Cognito, multi-Cognito, SimpleIDP, and application-hosted sessions are all valid methods with different client flows and credential shapes. The shared rules:
Connection Hub defines the platform authority provider.
assembly.yaml selects the active provider.
/api/cp-frontend-config tells the browser how to log in.
/profile is the source of truth for logged-in state.
Provider switches require cookie/logout hygiene on the shared origin.
Once those rules hold, product code can stop caring whether the user arrived through Cognito, SimpleIDP, or an application-hosted login page. It receives a normal KDCube platform user.
Related publication
Documentation on GitHub
The live docs behind this entry: