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"
  }
}
THE BROWSER FOLLOWS THE SERVER CONTRACT Browser shell /platform/chat GET /api/cp-frontend-config the browser auth contract authType oidcConfig | loginUrl profileUrl · logoutUrl cookie names (LATC / LITC) provider login OIDC · app page · simple GET /profile the source of truth anonymous → not logged in platform user → logged in The browser reads the contract, runs the provider login, and trusts /profile — not local OIDC state, a visible email, or a readable cookie. Not authenticated until /profile returns a non-anonymous kdcube.platform user.
The browser follows the server auth contract and trusts /profile — not local OIDC state, a visible email, or a readable cookie.

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

ONE PLATFORM SUBJECT, MANY WAYS IN kdcube.platform the platform subject contract Cognito Cognito Hosted UI / OIDC one pool + client LATC + LITC Multi-Cognito OIDC UI + trust list verifier accepts many pools LATC + LITC SimpleIDP local / dev simple / seeded token LATC / header Application-hosted app login page upstream proof (e.g. Google) LATC · kst1 Different login providers, one platform subject contract. Cognito & Multi-Cognito write external OIDC tokens; SimpleIDP a local token; application-hosted a KDCube kst1 session.
Different login providers, one platform subject contract.
MethodLogin UIServer verifierBrowser credentialUse when
CognitoCognito Hosted UI / OIDC providerCognito auth manager (selected through Connection Hub provider config)LATC access token + LITC ID tokenOne Cognito pool/client is the platform login.
Multi-CognitoBrowser logs into one configured OIDC providerMulti-Cognito verifier trusts a configured pool/client listLATC + LITCOne runtime must accept platform tokens from multiple trusted Cognito providers.
SimpleIDPLocal/simple login or seeded tokenSimpleIDP verifierLATC simple token or Authorization headerLocal development, test environments, embedded demos.
Application-hostedApplication page from auth.loginUrlApplication-session verifier using a KDCube kst1 session tokenLATC application-session token; LITC not requiredBranded/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.

TWO FLOWS, ONE /profile COGNITO — EXTERNAL OIDC TOKENS cp-frontend-config authType=cognito OIDC / Cognito code flow /platform/callback code + state browser writes LATC + LITC /profile ✓ platform user APPLICATION-HOSTED — A KDCUBE SESSION TOKEN cp-frontend-config authType=bundle auth.loginUrl application page app login + proof e.g. Google ID token Hub SDK issues kst1 session server writes LATC → /profile ✓ Cognito writes external OIDC tokens; application-hosted login issues a KDCube session token. Both land on the same fact: /profile returns a non-anonymous platform user.
Cognito writes external OIDC tokens; application-hosted login issues a KDCube session token — both land on the same /profile fact.

Cookies, headers, and APIs

Method/api/cp-frontend-configBrowser credential/profile verifier
CognitoauthType: cognito, oidcConfig present__Secure-LATC + __Secure-LITCCognito verifier
Multi-CognitoauthType: cognito, trusted providers in server config__Secure-LATC + __Secure-LITCMulti-Cognito verifier
SimpleIDPauthType: simple or simple local config__Secure-LATC simple token or Authorization headerSimpleIDP verifier
Application-hostedauthType: bundle, loginUrl present__Secure-LATC kst1 session tokenapplication-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.

SWITCHING PROVIDERS ON ONE ORIGIN old provider cookies LATC / LITC still in the jar logoutUrl / clear site data end the old session first new /api/cp-frontend-config read the new contract new login flow cognito / app page / simple /profile ✓ confirms non-anonymous platform user SAME ORIGIN — ONE COOKIE JAR https://your-runtime.ngrok-free.dev old runtime demo-project · Cognito · LATC+LITC new runtime custom-authority · app-hosted · LATC Cookies are scoped by origin / path / name — the two runtimes share one jar. Clear or log out before switching, or stale HttpOnly cookies bleed across. A tenant / project switch is not a cookie boundary. Trust the session only when /profile is coherent — a page that looks logged in but reads anonymous is wrong.
A tenant/project switch is not a browser-cookie boundary.

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

Your Application As A Platform Authority — the deep dive into the application-hosted option: hosting the login/consent screens while Connection Hub owns the authority registry.
KDCube Deep · 03.07.2026