KDCube

A user can now create a bounded credential for their own automation. That sounds small, but it closes a gap: KDCube could let an external app negotiate access through OAuth/MCP, and let a hosted application protect a managed surface — but a user also needs a simpler path: "give this script, agent, CI job, or DevOps task a token that represents me, only for the resources and operations I choose."

That is Delegated Access in Connection Hub — the Delegated by KDCube tab.

signed-in KDCube user
        |
        | creates delegated access in Connection Hub
        v
short-lived bearer token for automation
        |
        | Authorization: Bearer ...
        v
managed REST / MCP / platform surface
        |
        | guard checks resource_grants + selected operation
        v
route runs as the grantor user, with delegated provenance

The token is not a password and not a full login session. It is a delegated credential: revocable, scoped, tied to the approving platform user, and checked server-side on every call.

The whole idea in one line

Connection Hub lets a signed-in user mint a short-lived bearer token for automation, where the real authority is stored server-side as resource_grants: resource → grants[], plus selected operations. We do not store separate resources and grants lists — that would let the meaning drift. We store one shape:

{
  "resource_grants": {
    "https://runtime.example/A": ["records:read"],
    "https://runtime.example/B": ["records:write"]
  },
  "operations": ["records_search", "records_export"]
}

For a request to A, the guard uses grants from the matching A entry. It does not take a global union of every grant on the token. A token with {A: read, B: write} cannot use write on A.

What this is, and what it is not

Delegated Access is a KDCube-issued credential for entering KDCube. It is not the same as a user connecting their Gmail, Slack, iCloud, or LinkedIn account. Those are user-connected provider integrations — KDCube stores provider credentials so an application can call an external service for the user. Delegated Access points the other way: the user gives an automation a bounded way to call KDCube.

user-connected provider account
  KDCube -> external provider API
  example: KDCube reads the user's Gmail

delegated automation access
  automation -> KDCube API
  example: a script publishes news, exports conversations, or calls an app API

It is also different from OAuth/MCP connector setup such as Claude. Claude can negotiate with KDCube as a client and receive a delegated credential after a consent flow. Delegated Access is the manual, user-facing version: the user opens Connection Hub and creates a token directly.

The user flow

USER-CREATED DELEGATED ACCESS User signed-in picks resources + ops Connection Hub Delegated Access stores the grant record Automation script · agent · CI Bearer kst1… managed surface REST · MCP · platform guard checks the record create token (once) Bearer revoke anytime SERVER-SIDE GRANT RECORD the token is only a handle · loaded per call news publish → [news:write] conversations → [conversations:read] The bearer token is a handle — the guard loads the server-side grant record and enforces resource_grants matching per call. The route runs as the grantor user, with delegated provenance — never as the automation itself.
The bearer token is only a handle; the guard loads the server-side grant record and enforces resource-grant matching per call — and the user can revoke it anytime.

The UI should feel like selecting surfaces, not assembling OAuth internals:

Create automation access

Name:  nightly news publisher

Resources:
  [x] News operations API
      [x] publish article        news:write
      [ ] rebuild all indexes    news:admin

  [x] KDCube conversations MCP
      [x] export conversations   conversations:read

  [ ] All platform and application APIs
      admin-only                 kdcube:role:super-admin

After creation, the UI shows the raw token once (Authorization: Bearer kst1...). The Granted access list then shows metadata only: name, origin, approval/creation time, expiry, resource_grants, selected operations, token last-four, and revoke.

One registry for manual tokens and OAuth connects

Granted access lists more than the tokens created in this form. When an external client (for example an MCP client such as Claude) connects through the KDCube OAuth consent flow, that approval registers in the same per-user registry:

manual token   badge: manual token    Created  <time>
OAuth connect  badge: connected app   Approved <time>

OAuth rows keep one row per (user, client, resource) — reconsent widens the same row and keeps the first-approval time. The label is the client's own registration name, so users see "Claude", not a dcr-... id. The row expires with the connection's refresh-token lifetime, so a connection that can no longer mint tokens disappears on its own.

Revoke is immediate for both kinds. A manual token's bound session is logged out. An OAuth connect loses its refresh token (no new access tokens) and its current access-grant binding — the bearer in flight is rejected by the guards.

The runtime flow

The automation does not become the browser user. It becomes a delegated client actor whose grantor is the signed-in platform user who approved the token.

automation
  |  Authorization: Bearer kst1...
  v
KDCube request-auth surface
  |  hash token -> load server-side grant record
  |  check resource_grants against current URL/resource
  |  check selected operation/tool
  |  project grantor as platform UserSession
  v
route handler / MCP tool / application operation
  |  sees platform user context + delegated provenance
  v
product code runs

The route receives a projected platform context, so application code can use the normal user/session path rather than parsing tokens:

UserSession.user_id            -> grantor platform user id
UserSession.user_type          -> derived from projected grantor roles
UserSession.identity_authority -> delegated credential provenance:
                                  delegate actor, grantor, authority,
                                  resource_grants, operations, expiry

Product code should treat the request as delegated platform-user context. It should not parse the bearer token or infer the grantor itself.

The data model

The important persisted shape is resource_grants. The bearer token is only a handle — runtime guards read the server-side record by token hash.

{
  "label": "nightly news publisher",
  "grantor_user_id": "a1b2c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
  "delegate_user_id": "automation:7d9f...",
  "authority_id": "delegated_client",
  "resource_grants": {
    "*/api/integrations/bundles/*/*/news@2026-05-20-12-05/operations/publish*": ["news:write"],
    "*/api/integrations/bundles/*/*/kdcube-services@1-0/public/mcp/conversations*": ["conversations:read"]
  },
  "operations": ["news_publish", "conversations_export"],
  "expires_at": "2026-07-06T12:00:00Z"
}
  • Resource and grant cannot drift apart — grants live inside resource_grants[resource].
  • Revocation is immediate — the guard must load the server-side record.
  • Wildcards are explicit resource entries"*" is just another key in resource_grants.

Admin all-resource automation

Sometimes an administrator wants a token for DevOps automation: deploy, publish, sync descriptors, or call any platform/application API. That is not a separate synthetic grant — the platform admin role (kdcube:role:super-admin) is already a grant. So the all-resource token is:

{ "resource_grants": { "*": ["kdcube:role:super-admin"] } }

resource: "*" is deliberately special: it is visible only to users who can delegate kdcube:role:super-admin; it means all platform and application APIs; it still uses the same guard path; the request is projected as the grantor admin user; and the delegated actor is still recorded for provenance. If a token mixes entries, the * entry still matches every resource:

{
  "resource_grants": {
    "*": ["kdcube:role:super-admin"],
    "https://runtime.example/B": ["records:read"]
  }
}
# the * entry matches B too — admin authority on B, because it is a real matching entry
THE GUARD MATCHES ONE RESOURCE ENTRY — NOT A UNION GRANTS DO NOT UNION ACROSS RESOURCES GRANT RECORD A → [read] B → [write] request to A asks: write guard checks row A only 403 forbidden write ∉ A's grants THE WILDCARD * IS A REAL MATCHING ENTRY GRANT RECORD * → [super-admin] B → [read] request to B an admin action guard * matches B ✓ admin on B via the * resource entry Grant checks use only the matching resource entry{A: read, B: write} never implies write on A.
Grant checks use only the matching resource entry — a denied write on A, and a wildcard * that legitimately matches B.

Configuration: Connection Hub owns the registry

The catalog of delegable grants and protected resources belongs in Connection Hub configuration. Applications may expose managed surfaces, but Connection Hub owns the registry a user sees when creating delegated access.

bundles:
  items:
    - id: connection-hub@1-0
      config:
        connections:
          delegated_credentials:
            oauth:
              enabled: true
              capabilities:
                - { grant: kdcube:role:super-admin, label: Use all platform and application APIs,
                    delegable_roles: [kdcube:role:super-admin] }
                - { grant: news:write, label: Publish news,
                    delegable_roles: [kdcube:role:super-admin] }
                - { grant: conversations:read, label: Read conversations,
                    delegable_roles: [kdcube:role:super-admin] }
              resources:
                - resource: "*"
                  label: All platform and application APIs
                  admin_only: true
                  grants: [kdcube:role:super-admin]
                - resource: "*/api/integrations/bundles/*/*/news@2026-05-20-12-05/operations/publish*"
                  label: News publishing API
                  grants: [news:write]
                  operations:
                    news_publish: { label: Publish news content, grants: [news:write] }
                - resource: "*/api/integrations/bundles/*/*/kdcube-services@1-0/public/mcp/conversations*"
                  label: KDCube conversations MCP
                  grants: [conversations:read]
                  operations:
                    conversations_export: { label: Export conversations, grants: [conversations:read] }

This is the same registry used by OAuth delegated credentials and managed MCP. Delegated Access adds a user-created token path on top of that registry.

Configuration: an application REST operation

For an application REST operation, the application declares that its operation is managed by Connection Hub. The application does not parse delegated tokens.

@api(method="POST", alias="news_publish", route="operations")
async def news_publish(self, **params):
    # Product code runs only after the managed REST guard accepts the request.
    ...
bundles:
  items:
    - id: news@2026-05-20-12-05
      config:
        surfaces:
          as_provider:
            api:
              operations:
                news_publish:
                  POST:
                    auth:
                      mode: managed
                      authority_id: delegated_client
                      selected_operation_grants: true
                      operations:
                        news_publish: { label: Publish news content, grants: [news:write] }

selected_operation_grants: true means the operation must be present in the server-side delegated credential record. MCP calls this protocol-level object a tool; REST calls it an operation. The Connection Hub model is resource and operation based.

Configuration: a platform REST resource

Some APIs are not application operations — they are platform APIs. Connection Hub still owns the resource catalog, and the shared request-auth surface validates the bearer before the normal route handler runs.

connections:
  delegated_credentials:
    oauth:
      capabilities:
        - { grant: devops:deploy, label: Deploy runtime, delegable_roles: [kdcube:role:super-admin] }
      resources:
        - resource: "*/api/platform/admin/redeploy*"
          label: Platform redeploy API
          operations:
            platform_admin_redeploy: { label: Redeploy runtime, grants: [devops:deploy] }

If the URL is not configured as a Connection Hub delegated resource, the bearer token is not treated as magic — normal platform authentication rules apply.

How automation calls it

The call is ordinary HTTP with a bearer token — no browser cookie needed:

curl -sS \
  -H "Authorization: Bearer ${KDCUBE_DELEGATED_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{"limit": 5}' \
  "https://runtime.example/api/integrations/bundles/demo/demo/news@2026-05-20-12-05/operations/publish"

The same token can call MCP if its resource_grants and selected operations cover that MCP resource:

POST /api/integrations/bundles/<tenant>/<project>/kdcube-services@1-0/public/mcp/conversations
Authorization: Bearer kst1...

tools/call conversations_export

Failure modes

The useful failures are explicit:

401 unauthorized
  no bearer token, expired token, revoked token, or unknown token

403 forbidden
  resource_grants has no matching resource entry
  matching resource entry lacks the required grant
  selected operation/tool is absent
  grantor can no longer delegate the grant

The important security rule — grant checks use only the matching resource entry, never a union of all grants on the token:

resource_grants:  A: [read]   B: [write]
request to A with write   ->   forbidden

What to test

  1. Sign in as a regular user; open Connection Hub → Delegated by KDCube.
  2. Confirm all-resource admin access is not visible.
  3. Create a token for one concrete resource; call it with Authorization: Bearer ....
  4. Call a different resource and confirm it fails; revoke the token and confirm the same call now fails.
  5. Connect an external MCP client through the OAuth consent flow; confirm it appears under Granted access as a connected app; revoke it and confirm the client's next call is rejected.
  6. Sign in as an admin; create an all-resource token with kdcube:role:super-admin; call an admin-only API.
  7. Confirm logs show delegated projection and the automation actor.
# REST
[connection-hub.oauth.rest_guard] accepted ...
Managed REST runtime projection applied ...

# MCP
[connection-hub.oauth.mcp_guard] accepted ...
Managed MCP runtime projection applied ...

Why this belongs in Connection Hub

This is not a one-off token feature — it is another way to create a delegation edge. Connection Hub already owns who the platform user is, which grants they may delegate, which resources/operations are delegable, where durable consent and delegated credentials are stored, and how the runtime projects actor, grantor, and economics identity. Delegated Access reuses that infrastructure; the application owns product code, Connection Hub owns the boundary.

THREE ENTRY PATHS, ONE GUARD CONCEPT Claude OAuth / MCP connector negotiates a credential via consent an external client User-created automation token Delegated Access → Bearer the direct user-created path Application / platform REST a managed operation / resource same registry Connection Hub · delegated credential store + guard loads the server-side grant record checks resource_grants + operation product code runs as the grantor user · delegated provenance
Three entry paths — an external OAuth/MCP connector, a user-created automation token, a managed REST resource — one credential store and guard, one projected grantor user.

Related publications

Protecting KDCube Surfaces With Managed Credentials — the managed guard that checks resource_grants and the selected operation/tool before product code.
Authenticated MCP In KDCube: Delegated Credentials, Not Shared Secrets — the OAuth/MCP version of delegated credentials.
Delegating A KDCube Service To An External App — the user-facing delegation lifecycle.
Setting Up Platform Authority In KDCube — why the approving user can come from Cognito, multi-Cognito, or an application-hosted authority.
Connect Your Named Services To Claude Code — a concrete external-agent consumer of the same managed delegated-credential model.
KDCube Deep · 04.07.2026