A KDCube deployment does not always want Cognito to be the only way a user becomes a platform user. Sometimes the product already has a login page. Sometimes the application wants a branded sign-in flow. Sometimes the upstream proof is Google, an enterprise portal, a Telegram Mini App, or another identity source that belongs to the application realm.

The platform still needs one coherent answer after that login:

Who is the platform subject?
Which roles and permissions does this subject have?
Which browser credential proves the platform session?
Who pays when the user calls paid capabilities?
Where does an external-client consent screen come from?
How does the browser know where login and logout are?

Connection Hub now gives KDCube a way to answer those questions without turning every application into its own private auth system. The application can host the user-facing login and consent screens, while Connection Hub owns the authority registry and KDCube still verifies a standard platform session. That is the subject of this article: how an application can host a platform authority flow without owning platform authority policy.

This piece sits next to the existing Connection Hub publications — delegated credentials, managed MCP guards, and named services:

  • Protecting KDCube Surfaces With Managed Credentials — the managed guard and descriptor model.
  • Authenticated MCP In KDCube: Delegated Credentials, Not Shared Secrets — the delegated-credential lifecycle.
  • Named services can now leave KDCube through a delegated MCP connector — the external-client case.

Those pieces explain the connection side. This one explains the missing platform-login side: how the user gets the platform identity that can approve those connections in the first place.

The core idea

The mistake to avoid is thinking "my application is the authority, therefore my application owns everything." In KDCube the split is sharper:

Connection Hub owns:          The application owns:         The platform owns:
  authority id                  login page presentation       browser auth contract
  provider registry             callback page/operation       standard session verification
  platform-ness                 custom consent presentation   /profile
  provider entrypoints          calling the Hub SDK runtime   configured logoutUrl
  default/assignable grants                                   economics projection
  subject & bootstrap grants                                 protected-surface enforcement
  issuer settings
WHO OWNS WHAT Application owns presentation login page UI session-issue operation custom consent renderer product branding Connection Hub owns authority meaning authority_registry provider entrypoints grants · default / assignable subject & bootstrap grants issuer settings KDCube platform verifies & enforces /profile /api/platform/logout session verifier economics projection surface guards The application owns presentation, Connection Hub owns authority meaning, and the platform verifies and enforces.
The application owns presentation. Connection Hub owns authority meaning. The platform verifies and enforces.

In one sentence: the app hosts the door, Connection Hub registers what the door means, and the platform verifies the session created by that door. This is not a replacement for Connection Hub — it is a way for Connection Hub to delegate user-facing UI to an app while keeping authority semantics centralized.

What "platform authority" means

A platform authority is an authority whose identities can become KDCube platform subjects — the identities used by normal KDCube surfaces: chat, widgets, memory, conversations, admin views, economics, and delegated external-client consent. In descriptors this is explicit:

authority_registry:
  authorities:
    kdcube.platform:
      label: KDCube platform authority
      platform: true

platform: true is the important part. It means identities under that authority can be used as the platform user. There can be more than one platform-capable authority: a normal deployment may use Cognito; a custom deployment may use an application-hosted provider that accepts Google login and issues a standard KDCube application-session credential.

An upstream provider, such as Google, is different — it proves a Google subject, but does not automatically become the KDCube platform authority. The application-hosted provider consumes that Google proof and creates a platform session under kdcube.platform:

Google proof
  authority = google.accounts
  subject   = google:<sub>
        |
        | consumed by registered application-session login provider
        v
KDCube platform session
  authority = kdcube.platform
  subject   = google:<sub>  (as the platform subject in this deployment)

Raw channel proofs, such as Telegram initData, are also not platform login by themselves. They prove the channel actor. They become platform-authorized only when a configured platform login or explicit connection/delegation edge says so.

The flow

The browser does not need to know whether the selected platform provider is Cognito, an application-session provider, or something else. It asks the platform for the current auth contract.

1.  Browser opens /platform/chat
2.  Browser fetches /api/cp-frontend-config
3.  Config contains auth.loginUrl / auth.profileUrl / auth.logoutUrl
4.  Browser asks auth.profileUrl: logged in? stay. anonymous? go to auth.loginUrl
5.  Application-hosted login page renders
6.  User completes upstream login, for example Google
7.  Application operation calls the Connection Hub SDK runtime
8.  SDK resolves the authority_registry provider
9.  SDK verifies the proof, resolves grants, issues a kst1 platform session
10. Browser returns to KDCube with a standard platform session cookie
11. Future requests are verified by normal platform auth
LOGIN FLOW — THE BROWSER ASKS THE SERVER 1 Browser /platform/chat 2 cp-frontend-config → auth.* URLs 3 profileUrl anonymous → loginUrl 4 Application login Google / custom button 5 upstream proof Google ID token / custom 6 Connection Hub SDK resolve · verify · issue 7 kst1 session platform cookie set 8 /profile ✓ sees platform user The browser receives its URLs from the server — it never branches on the provider implementation. Cognito or an application-hosted provider, the browser asks auth.profileUrl and follows auth.loginUrl.
The browser receives its URLs from the server and never branches on the provider implementation.

The browser-facing config is generic:

{
  "auth": {
    "loginUrl": "/api/integrations/bundles/.../public/platform_login",
    "profileUrl": "/profile",
    "logoutUrl": "/api/platform/logout"
  }
}

profileUrl is the canonical "am I logged in?" check — the browser should ask the server, not inspect HTTP-only cookies or branch on a provider type. logoutUrl is provider-neutral: for application-session providers, /api/platform/logout invalidates the active application session record and clears the platform auth/session cookie when that route is routed by the deployment proxy. An application may still host a branded sign-out page, but the platform session is ended by the platform logout contract.

The registry: where the meaning lives

The most important descriptor block is the Connection Hub authority registry. This is where an app-hosted provider becomes a platform authority provider.

items:
  - id: connection-hub@1-0
    config:
      authority_registry:
        authorities:
          kdcube.platform:
            label: KDCube platform authority
            platform: true

            grants:
              subjects:
                google:<verified_google_sub>:
                  label: bootstrap_admin
                  roles: [ kdcube:role:super-admin ]
                  permissions: [ kdcube:*:*:* ]
              bootstrap_rules:
                - id: bootstrap_admin_by_google_email
                  when:
                    provider: google
                    claims: { email: owner@example.com, email_verified: true }
                  roles: [ kdcube:role:super-admin ]
                  permissions: [ kdcube:*:*:* ]

            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: { secure: true, same_site: lax }
                grants:
                  default:    { roles: [ kdcube:role:registered ], permissions: [] }
                  assignable: { roles: [ kdcube:role:registered, kdcube:role:super-admin ] }

          google.accounts:
            label: Google Accounts
            platform: false
            providers:
              google_oidc:
                type: google_id_token
                enabled: true
                authenticator:
                  client_id: <google-client-id>.apps.googleusercontent.com

This shape has a few useful properties:

  • The provider id is a deployment name. product_google_session is the configured instance; the type bundle_session_login is the reusable runtime.
  • Entrypoints describe where the app hosts UI and operations. login is the page, session_issue exchanges the proof and issues the session, consent is an optional custom consent renderer.
  • Input describes what upstream proof is accepted — here a Google ID token, verified through google.accounts.providers.google_oidc.
  • Issuer describes the KDCube credential produced — a standard application-session token (kst1) in the configured platform auth/session cookie, not a private token format.
  • Grants describe what this provider may give. grants.default is what every session receives; grants.assignable is the maximum it may assign via subject/bootstrap grants.
  • Subject grants are keyed by stable subjects (e.g. google:<sub>). Email is a bootstrap matcher only when verified (email + email_verified).

The application: where the experience lives

The application descriptor stays small — it points to Connection Hub and carries only the application-local integration config the hosted UI needs.

items:
  - id: product-app@1-0
    config:
      connections:
        connection_hub:
          bundle_id: connection-hub@1-0

The application operations are also thin: they host UI and call the SDK runtime.

@api(method="GET", alias="platform_login", route="public")
async def platform_login(self, request: Request, **kwargs):
    return await platform_session_issuer.google_login_page(
        self, request=request, bundle_id=self.bundle_id,
    )

@api(method="POST", alias="auth_google_session", route="public")
async def auth_google_session(self, request: Request, **kwargs):
    payload = await request.json()
    return await platform_session_issuer.issue_google_session(
        self, request=request, credential=payload.get("credential", ""), bundle_id=self.bundle_id,
    )

@api(method="POST", alias="delegated_consent", route="public")
async def delegated_consent(self, request: Request, **kwargs):
    return platform_session_issuer.delegated_consent_page(
        self, request=request, bundle_id=self.bundle_id,
    )

The reusable runtime lives in the platform SDK (...connections.authority_providers.bundle_session_login), with an example wrapper in the Versatile example application (...versatile.services.platform_session_issuer). The hosted operation asks the Connection Hub SDK to resolve its registered provider; the runtime checks that the provider exists, is enabled, is platform-capable, and is actually hosted by the current application operation. Then it verifies the upstream proof, resolves grants, and issues the standard platform session.

Login screens and consent screens

There are two user-facing screens in this model, and they are not the same thing.

Login screen
  Purpose:       create a KDCube platform session.
  Hosted by:     the application.
  Registered at: provider.entrypoints.login.

Consent screen
  Purpose:       approve a delegated external client, such as an MCP connector.
  Hosted by:     Connection Hub by default, or the application for custom layout.
  Registered at: provider.entrypoints.consent.
  Security owner: Connection Hub.
TWO SCREENS, ONE ISSUER LANE A · PLATFORM LOGIN user signed-in person app login page hosted by the application platform session kst1 cookie LANE B · DELEGATED EXTERNAL-CLIENT CONSENT external client an MCP connector Hub authorize OAuth endpoint consent renderer optional · app-styled Hub approve/deny validates · narrows delegated credential issued by the Hub only the Hub issues The app may render both screens — but only Connection Hub issues the delegated credential. The custom consent page is presentation, not policy — approve/deny always returns through the Hub.
The app may render both screens — but only Connection Hub issues the delegated credential.

The custom consent screen is presentation, not policy. An application may render the entire page in its own style, but approval still returns through Connection Hub so CSRF validation, grant narrowing, authorization-code creation, token issuance, and credential storage remain central.

The renderer receives a payload with form_action, csrf_token, the original OAuth authorize request (client_id, redirect_uri, scope, resource, state, PKCE fields), the account label, selected-platform-grant options, and tool options. The custom page should POST approve/deny to form_action and preserve the authorize request fields as hidden inputs. Connection Hub re-validates all fields before issuing anything. There is also a hardening layer: if a custom renderer drops a non-secret authorize field, Connection Hub can recover it from the same-origin authorize referrer before validation — which makes custom UIs safer to build without moving OAuth policy into the application.

External client wants access
  -> Connection Hub authorize endpoint
  -> Selected platform provider has entrypoints.consent?
       no  -> render standard Connection Hub consent
       yes -> ask application to render custom consent page
              -> Approve/Deny posts back to Connection Hub
              -> Connection Hub issues or denies the delegated credential

Troubleshooting. If the consent page renders but approve says unknown client_id, check the Connection Hub proc logs for authorize_consent rejected, dynamic_client_missing, or consent params recovered from authorize referrer. If the posted form misses client_id / redirect_uri / scope / PKCE fields, fix the custom consent renderer to preserve the hidden authorize fields.

What the application developer does

For an application developer, the checklist is short.

1. Decide the upstream proof. Google ID token, enterprise SSO callback, signed portal token, or a Telegram proof consumed as part of a platform login flow.

2. Register the upstream authenticator in Connection Hub.

google.accounts:
  platform: false
  providers:
    google_oidc:
      type: google_id_token
      authenticator:
        client_id: <google-client-id>.apps.googleusercontent.com

3. Register the platform provider under a platform authority (type bundle_session_login, with entrypoints, input.authenticator_ref, issuer, and grants.default / grants.assignable).

4. Configure the platform frontend to select that provider. assembly.yaml selects the Connection Hub provider — it does not hardcode the final application URL.

auth:
  type: bundle
  idp: session
  connection_hub:
    bundle_id: connection-hub@1-0
    authority_id: kdcube.platform
    provider_id: product_google_session
    entrypoint: login

5. Add the shared platform session secret. Every ingress/proc worker needs the same verifier secret.

services:
  session_token:
    secret: "<deployment secret>"

6. Add the application operations — they render UI and delegate verification/session issuing to the SDK runtime.

7. Test the normal browser route. Open /platform/chat, let the frontend redirect through auth.loginUrl, complete login, confirm /profile sees the user, then confirm logout through auth.logoutUrl.

8. If using Google, register the runtime origin. Google OAuth clients must include the exact browser origin under Authorized JavaScript origins — scheme, host, and optional port only (no /platform/chat or /api/integrations/... path).

Why this matters for external agents

The delegated MCP story needs a platform subject. When a user connects an external client, the consent page asks: which platform user is approving this, which tools/grants may the client use, which identity pays, and which actor is recorded as provenance. An application-hosted platform authority answers the first question without requiring Cognito — the user logs in through the app's chosen provider, KDCube receives a standard platform session, and Connection Hub can then issue delegated credentials in the normal way.

App-hosted login
  -> platform session
  -> external-client consent
  -> delegated credential
  -> protected MCP/named-service call
  -> economics charged to platform owner

The result is one coherent model: browser users, Telegram users, external agents, enterprise-portal users, and Google-authenticated product users all connect through Connection Hub, all resolve through authorities and edges, and all reach protected surfaces through explicit grants.

Switching platform authority methods

Switching one origin between Cognito, SimpleIDP, and an application-hosted platform session is a deployment/test action. Browser cookies are scoped by origin, path, and cookie name. They are not scoped by tenant, project, or the active descriptor.

1. Open /api/cp-frontend-config.
2. Confirm auth.authType and selected provider fields.
3. Complete login.
4. Open /profile.
5. Trust the session only when /profile returns a non-anonymous platform user.

Expected credential state: Cognito/multi-Cognito writes LATC access token plus LITC ID token; SimpleIDP uses a simple platform token in LATC or Authorization; application-hosted platform session writes LATC with the KDCube application-session token and does not require LITC. If /profile remains anonymous after a visual login, use auth.logoutUrl while that runtime is available or clear site data for the origin before retrying.

Summary

Making an application a platform authority is not about giving an application unchecked power over platform auth. It is about registering a provider in Connection Hub, letting the app host the user-facing screens, and issuing a standard KDCube platform session through the SDK runtime.

custom login UI            standard KDCube session
custom consent UI          standard platform logout/profile
custom upstream proof      central authority policy
                           central delegated-credential enforcement

The application becomes the face of the login flow. Connection Hub remains the registry of what the flow means.

KDCube Deep · 02.07.2026