Topolo Docs Topolo Platform
Open workspace

Read my application surface

Read current account and work-resource availability without selecting or changing the browser organisation or the credential context.

Outcome

Read current account and work-resource availability without selecting or changing the browser organisation or the credential context.

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.get --detail --json

Input fields

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

Interpret the response

Use app_id from application discovery. data.account_id identifies the caller; surface_session.version=1 and appId identify the projection. Each context has its own permissions and workspace resources. A verified Chat account may retain a personal context with role=account, no permissions and no workspaces after work access is removed; this grants no messaging entitlement or conversation consent.

The handler reads fresh active identity and memberships. Suspended/inactive memberships and unauthorized application contexts are omitted. Workspace IDs, default flags and access levels are observations; the target operation must recheck authority. A first-party context-RBAC CLI/MCP credential remains within its pinned organization, including when the account has other memberships.

Bearer reads return no csrf_token and set no cookies. A browser Chat read uses X-Topolo-Auth: 1 plus a live session and unrevoked refresh cookie. It returns a matching existing host-only CSRF nonce or sets one when absent. Keep that nonce in memory for a cookie-authenticated create; it is not an access token or sign-in renewal.

No accessible context is HTTP 403, a revoked account is HTTP 401 and policy failure is HTTP 503 SURFACE_UNAVAILABLE. The read uses Cache-Control: private, no-store.

Run the action

Write the discovered application id to payload.json. Validate and plan the unchanged input. This published read requires no mutation confirmation.

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

MCP uses topolo_validate_action and topolo_plan_action for the same input, followed by topolo_read_action.

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.surface_sessions.get",
    "input": {
      "app_id": "app_topolo_chat"
    }
  }
}

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 retrieved",
  "data": {
    "account_id": "usr_surface_fixture",
    "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 decision reflects only the disclosed fixture state; resolve live identifiers and runtime authority separately.

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 retrieved",
  "data": {
    "account_id": "usr_surface_fixture",
    "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 decision reflects only the disclosed fixture state; resolve live identifiers and runtime authority separately.

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 retrieved",
  "data": {
    "account_id": "usr_surface_fixture",
    "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 decision reflects only the disclosed fixture state; resolve live identifiers and runtime authority separately.

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 retrieved",
  "data": {
    "account_id": "usr_surface_fixture",
    "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"
            }
          ]
        }
      ]
    },
    "csrf_token": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
  },
  "timestamp": "2026-10-05T00:00:00.000Z"
}

Live browser session and refresh record with matching existing CSRF nonce. The decision reflects only the disclosed fixture state; resolve live identifiers and runtime authority separately.

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",
    "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"
  }
}

Duplicate application query is rejected

Input:

{
  "app_id": "app_topolo_chat"
}

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"
  }
}
  • 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

Revoked memberships disappear on the next read; a retained personal context is not work access. The browser verification nonce does not extend or recover a sign-in.

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.