Topolo Docs Topolo Platform
Open workspace

Create my short-lived application surface session

Create an application-scoped surface credential from a current human sign-in, with no context switch, new entitlement or change to workspace grants.

Outcome

Create an application-scoped surface credential from a current human sign-in, with no context switch, new entitlement or change to workspace grants.

Before you start

  • Verify the human identity and intended pinned credential context, then discover the canonical application. The fixture identities and signing output below are synthetic and unusable.

  • Keep account eligibility, surface/workspace availability and operation-specific permission or conversation consent separate. A result here never widens authority.

Discover the application

topolo whoami --json
topolo apps --json
topolo actions get app_topolo_auth.surface_sessions.create --detail --json

Input fields

FieldRequiredMeaning
app_idYesRegistered application to scope the surface to. Does not select an account or organisation.

Interpret the response

Supply only app_id; creation does not switch context, select another account, assign seats, restore membership or grant work access. A current human source is required. API keys, delegated actor headers and service principals cannot substitute for that identity. A surface credential cannot mint another surface credential.

data.access_token is sensitive, token_type is Bearer and expires_in is at most 300 seconds. A context-RBAC or refresh source with less remaining lifetime produces a shorter TTL. The synthetic signing result in local examples is unusable; it is not a live credential.

First-party CLI/MCP sources retain client identity, the pinned organization boundary and source expiry. Protected local tooling replaces returned credentials with topolo-secret references; preserve the reference unchanged for a compatible next action, never reveal or persist its underlying token, and release it through the published secret-release operation after use.

Cookie-authenticated Chat creation requires X-Topolo-Auth: 1, live session/refresh records and matching X-CSRF-Token from the surface read. It neither rotates cookies nor extends the original sign-in. Revoked or expired browser records cannot be used for recovery.

Inspect account_id, appId and per-context resources, then read surface_sessions.get with the same app_id and source credential. Target operations independently recheck membership and consent. Discard the credential when finished; no persistent grant was created. Use a separately discovered authorized session revocation only if sign-in compromise requires it.

Run the action

Write the discovered application id to payload.json. Validate and plan the unchanged input. Creation is a mutation: execute only after the human has authorized this credential operation; --confirm acknowledges that authorization.

topolo actions validate app_topolo_auth.surface_sessions.create --data @payload.json --json
topolo actions plan app_topolo_auth.surface_sessions.create --data @payload.json --confirm --json
topolo actions call app_topolo_auth.surface_sessions.create --data @payload.json --confirm --detail --json

MCP uses topolo_validate_action and topolo_plan_action for the same input, followed by topolo_call_action with confirm=true after authorization.

{
  "tool": "topolo_call_action",
  "arguments": {
    "actionId": "app_topolo_auth.surface_sessions.create",
    "input": {
      "app_id": "app_topolo_chat"
    },
    "confirm": true
  }
}

Worked responses

Every example uses synthetic identities and a fixed clock. Cookie/browser and credential state described in a title is a fixture precondition, not an extra action-input field. Responses below are the raw handler envelope; protected tooling may replace returned credential values with opaque references.

Verified account retains personal history context and only the currently authorized Alpha workspace

Input · payload.json:

{
  "app_id": "app_topolo_chat"
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Surface session created",
  "data": {
    "account_id": "usr_surface_fixture",
    "access_token": "synthetic-unusable-surface-token",
    "token_type": "Bearer",
    "expires_in": 300,
    "surface_session": {
      "version": 1,
      "appId": "app_topolo_chat",
      "contexts": [
        {
          "type": "personal",
          "id": "usr_surface_fixture",
          "label": "Personal",
          "slug": null,
          "role": "account",
          "permissions": [],
          "resources": []
        },
        {
          "type": "organization",
          "id": "org_surface_alpha",
          "label": "Alpha fixture",
          "slug": "alpha-fixture",
          "role": "member",
          "permissions": [
            "direct_messages:read"
          ],
          "resources": [
            {
              "type": "workspace",
              "id": "ws_surface_alpha",
              "label": "Alpha workspace",
              "slug": "alpha-workspace",
              "isDefault": true,
              "accessLevel": "read_write"
            }
          ]
        }
      ]
    }
  },
  "timestamp": "2026-10-05T00:00:00.000Z"
}

Verified account retains personal history context and only the currently authorized Alpha workspace. The response uses synthetic unusable signing output; compatible protected CLI/MCP replaces a real credential with an opaque secret reference.

Revoked work membership leaves a personal context with no workspace grants

Input · payload.json:

{
  "app_id": "app_topolo_chat"
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Surface session created",
  "data": {
    "account_id": "usr_surface_fixture",
    "access_token": "synthetic-unusable-surface-token",
    "token_type": "Bearer",
    "expires_in": 300,
    "surface_session": {
      "version": 1,
      "appId": "app_topolo_chat",
      "contexts": [
        {
          "type": "personal",
          "id": "usr_surface_fixture",
          "label": "Personal",
          "slug": null,
          "role": "account",
          "permissions": [],
          "resources": []
        }
      ]
    }
  },
  "timestamp": "2026-10-05T00:00:00.000Z"
}

Revoked work membership leaves a personal context with no workspace grants. The response uses synthetic unusable signing output; compatible protected CLI/MCP replaces a real credential with an opaque secret reference.

First-party context-RBAC credential retains its Alpha organization boundary

Input · payload.json:

{
  "app_id": "app_topolo_chat"
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Surface session created",
  "data": {
    "account_id": "usr_surface_fixture",
    "access_token": "synthetic-unusable-surface-token",
    "token_type": "Bearer",
    "expires_in": 90,
    "surface_session": {
      "version": 1,
      "appId": "app_topolo_chat",
      "contexts": [
        {
          "type": "personal",
          "id": "usr_surface_fixture",
          "label": "Personal",
          "slug": null,
          "role": "account",
          "permissions": [],
          "resources": []
        },
        {
          "type": "organization",
          "id": "org_surface_alpha",
          "label": "Alpha fixture",
          "slug": "alpha-fixture",
          "role": "member",
          "permissions": [
            "direct_messages:read"
          ],
          "resources": [
            {
              "type": "workspace",
              "id": "ws_surface_alpha",
              "label": "Alpha workspace",
              "slug": "alpha-workspace",
              "isDefault": true,
              "accessLevel": "read_write"
            }
          ]
        }
      ]
    }
  },
  "timestamp": "2026-10-05T00:00:00.000Z"
}

First-party context-RBAC credential retains its Alpha organization boundary. The response uses synthetic unusable signing output; compatible protected CLI/MCP replaces a real credential with an opaque secret reference.

Live browser session and refresh record with matching existing CSRF nonce

Input · payload.json:

{
  "app_id": "app_topolo_chat"
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Surface session created",
  "data": {
    "account_id": "usr_surface_fixture",
    "access_token": "synthetic-unusable-surface-token",
    "token_type": "Bearer",
    "expires_in": 300,
    "surface_session": {
      "version": 1,
      "appId": "app_topolo_chat",
      "contexts": [
        {
          "type": "personal",
          "id": "usr_surface_fixture",
          "label": "Personal",
          "slug": null,
          "role": "account",
          "permissions": [],
          "resources": []
        },
        {
          "type": "organization",
          "id": "org_surface_alpha",
          "label": "Alpha fixture",
          "slug": "alpha-fixture",
          "role": "member",
          "permissions": [
            "direct_messages:read"
          ],
          "resources": [
            {
              "type": "workspace",
              "id": "ws_surface_alpha",
              "label": "Alpha workspace",
              "slug": "alpha-workspace",
              "isDefault": true,
              "accessLevel": "read_write"
            }
          ]
        }
      ]
    }
  },
  "timestamp": "2026-10-05T00:00:00.000Z"
}

Live browser session and refresh record with matching existing CSRF nonce. The response uses synthetic unusable signing output; compatible protected CLI/MCP replaces a real credential with an opaque secret reference.

Verify the result

  • Read surface_sessions.get with the same app_id and credential. Match account_id and the application; each workspace must remain within the returned context.

  • Projection metadata grants neither messaging entitlement nor conversation membership. Resource operations must recheck current authorisation.

Errors and recovery

An API key cannot substitute for a human source credential

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 403:

{
  "success": false,
  "error": {
    "message": "A human sign-in is required",
    "code": "FORBIDDEN",
    "details": null,
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

Token version predates current account revocation

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 401:

{
  "success": false,
  "error": {
    "message": "Invalid or revoked account session",
    "code": "AUTH_ERROR",
    "details": null,
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

Unverified account without a work context has no available Chat surface

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 403:

{
  "success": false,
  "error": {
    "message": "User does not have access to this surface in any context",
    "code": "FORBIDDEN",
    "details": null,
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

Canonical-looking identifier is not a registered application

Input:

{
  "app_id": "app_unknown_fixture"
}

Captured local refusal · HTTP 400:

{
  "success": false,
  "error": {
    "message": "app_id is not registered",
    "code": "VALIDATION_ERROR",
    "details": {
      "app_id": true
    },
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

An organization selector cannot widen or change the credential

Input:

{
  "app_id": "app_topolo_chat",
  "orgId": "org_surface_beta"
}

Captured local refusal · HTTP 400:

{
  "success": false,
  "error": {
    "message": "Supply one registered app_id only",
    "code": "VALIDATION_ERROR",
    "details": {
      "app_id": true
    },
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

Unavailable workspace policy is an error, not an empty grant

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 503:

{
  "success": false,
  "error": {
    "message": "Account surface is temporarily unavailable",
    "code": "SURFACE_UNAVAILABLE",
    "details": null,
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

Revoked browser refresh record cannot renew or recover sign-in

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 401:

{
  "success": false,
  "error": {
    "message": "Browser sign-in revoked or expired",
    "code": "AUTH_ERROR",
    "details": null,
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

A surface credential cannot mint another surface credential

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 400:

{
  "success": false,
  "error": {
    "message": "Surface sessions cannot mint surface sessions",
    "code": "VALIDATION_ERROR",
    "details": {
      "token": true
    },
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 403:

{
  "success": false,
  "error": {
    "message": "Browser request verification required",
    "code": "FORBIDDEN",
    "details": null,
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}

Expired first-party source cannot issue a new surface credential

Input:

{
  "app_id": "app_topolo_chat"
}

Captured local refusal · HTTP 403:

{
  "success": false,
  "error": {
    "message": "A current first-party account credential is required",
    "code": "FORBIDDEN",
    "details": null,
    "timestamp": "2026-10-05T00:00:00.000Z"
  }
}
  • AUTH_ERROR (HTTP 401): Sign in normally after expiry or revocation. A stale refresh credential cannot recover a session.

  • FORBIDDEN (HTTP 403): Use a first-party human credential for the requested surface. Cookie creation requires the matching CSRF token from the credentialed surface read. Do not switch context to bypass denial.

  • VALIDATION_ERROR (HTTP 400): Discover the application and supply only app_id. A surface token cannot mint another surface token.

  • SURFACE_UNAVAILABLE (HTTP 503): Retry the same request when Auth is available; do not infer an access grant from failure.

Tooling error categories

CLI/MCP may separately report authentication_required, permission_denied, rate_limited, invalid_input or dependency_unavailable. These are tooling/catalog categories; preserve the underlying handler code and status shown above when deciding recovery. Do not assume a handler emitted a tooling category.

Recovery boundary

No persistent grants are created. Discard the returned credential; it expires within five minutes. Use published session revocation for a compromised browser sign-in. Creation never restores a revoked session or former organisation access.

Evidence

Existing isolated handlers; no live session, credential, membership, entitlement or provider was changed.

Actual dependencies: HTTP response serialization and strict input validation; Account identity, token-version and CSRF policy checks; Surface projection and TTL issuer calculation; Portable entitlement SQL evaluated by SQLite.

Simulated dependencies: Access/refresh credential verification and synthetic unusable signing output; Registry, hydrated identity, workspace and permission repositories; Seat-policy decision; minimal entitlement schema is not the full migration database; Fixed clock and deliberately synthetic records.

These captures prove existing handler serialization and selected policy branches with disclosed simulations. They do not prove live signing, production grants, multi-D1 consistency or a real cookie/JWT authentication journey. No business credential operation was executed.