Topolo Docs Topolo Platform
Open workspace

List my resource grants

List a bounded page of the caller's live resource grants.

Outcome

List a bounded page of the caller's live resource grants.

These examples prove local handler behavior with real isolated SQL and explicitly simulated identity/permission dependencies.

Before you start

  • Verify identity and the current credential-scoped action contract before preparing input. Resource-grant operations authorize the target organization/app at runtime; metadata discovery does not prove execution permission.

  • Discover the recipient and existing application resource. Use one exact organization/app/type/id tuple consistently; a grant never creates the target resource.

Discover the target

topolo whoami --json
topolo apps --json
topolo actions get app_topolo_auth.resource_grants.list_mine --detail --json

Discover the recipient and target resource using owning-application actions. Read app_topolo_auth.resource_grants.list_resource with the exact resource tuple and follow all pages.

Input fields

resource_type and resource_id must both be present or both absent. Follow only a returned positive-timestamp cursor.

FieldRequiredMeaning
org_idNoOptional exact organization filter for the authenticated caller own live grants.
app_idNoExact stored application identifier to filter grants. App id and slug are not interchangeable in grant storage or list filters.
resource_typeNoExact resource kind paired with resource_id. For list_mine both filters must be supplied together; list_resource requires both.
resource_idNoExact resource id paired with resource_type; no wildcard discovery of recipients.
limitNoPage size from 1 to 100, default 50. Preserve the same filters when following nextCursor.
cursorNoOpaque continuation copied from the previous page.nextCursor; do not construct one from examples. Pagination is keyset-based on createdAt/id and is not a snapshot of concurrent grant changes.

Effects

  • Reads a bounded page of the authenticated subject live grants.

Interpret the response

The raw target success envelope is success/message/data/timestamp. Create returns HTTP 201; all other successes return 200. CLI and MCP may wrap or project this envelope.

Grant id and createdAt remain stable when create updates the same user/organization/app/resourceType/resourceId key or reactivates a revoked grant. Omitted scope/type/metadata/expiry reset to create defaults rather than preserve previous values. Take a snapshot before replacing an existing grant.

Live lists omit revoked and expired rows. page.hasMore controls continuation; nextCursor is null at the end. list_mine contains only the authenticated subject, never a supplied userId. list_resource additionally returns recipient id/email/name or null when identity lookup is unavailable.

Create data.provisioned means this call created an unverified identity. It does not imply membership, invitation, sign-in, recipient acceptance or resource access. A create with past expiry can succeed with data.grant null because its stored row is already absent from live access.

Grant createdAt, expiresAt and revokedAt are epoch seconds; response timestamp is ISO text. Legacy create expiry strings can remain strings in stored output. Convert dates before planning; never infer live access from a successful storage response.

Update preserves identity and can extend an expired unrevoked grant. A revoked row is refused. Revoke returns only data.id, including on repeated revocation, and does not delete the recipient identity or affect separate membership/other grants.

Promote creates organization membership before revoking all non-workspace resource grants for that user and organization across apps. appId limits the permission check, not the revocation scope. These writes span databases and are not atomic; a 500 can leave membership active while grants remain. Read membership/effective access and remaining grants before any reviewed retry or compensation.

Promote data.role echoes the requested/default role. Existing membership, stored user role and effective authorization require separate verification. Notification delivery is nonfatal and is not proven by success. An empty list_mine after promotion does not mean the user has lost organization access.

AUTH_ERROR (401) is used both for absent/invalid tokens and for authenticated callers lacking organization or app grant authority. Inspect the error and identity before assuming OAuth expired; preserve authorization denials rather than changing credential context automatically.

Worked examples

These are complete raw target-handler responses, not CLI/gateway envelopes or live authorization proof. Replace synthetic identifiers using authorized discovery. Save only the reviewed input as payload.json; inspect validation and plan before executing. --confirm assumes the intended operation is approved. Metadata read-back requires separate recipient-principal and owning-application access tests.

Recipient has no resource grants

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions plan app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions call app_topolo_auth.resource_grants.list_mine --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.resource_grants.list_mine",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Resource grants fetched",
  "data": {
    "grants": [],
    "page": {
      "nextCursor": null,
      "hasMore": false
    }
  },
  "timestamp": "2026-10-02T18:01:40.140Z"
}

Recipient sees its exact live resource grant

Input · payload.json:

{
  "org_id": "org_example",
  "app_id": "app_topolo_people",
  "resource_type": "candidate",
  "resource_id": "candidate_one"
}

CLI:

topolo actions validate app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions plan app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions call app_topolo_auth.resource_grants.list_mine --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.resource_grants.list_mine",
    "input": {
      "org_id": "org_example",
      "app_id": "app_topolo_people",
      "resource_type": "candidate",
      "resource_id": "candidate_one"
    }
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Resource grants fetched",
  "data": {
    "grants": [
      {
        "id": "rg_JOD6QZYnE1JA",
        "userId": "usr_recipient",
        "organizationId": "org_example",
        "appId": "app_topolo_people",
        "resourceType": "candidate",
        "resourceId": "candidate_one",
        "grantType": "consumer",
        "scope": "read_write",
        "expiresAt": null,
        "grantedBy": "usr_operator",
        "metadata": {
          "purpose": "interview"
        },
        "revokedAt": null,
        "createdAt": 1790964100
      }
    ],
    "page": {
      "nextCursor": null,
      "hasMore": false
    }
  },
  "timestamp": "2026-10-02T18:01:40.147Z"
}

Recipient live grants exclude revoked grant

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions plan app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions call app_topolo_auth.resource_grants.list_mine --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.resource_grants.list_mine",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Resource grants fetched",
  "data": {
    "grants": [],
    "page": {
      "nextCursor": null,
      "hasMore": false
    }
  },
  "timestamp": "2026-10-02T18:01:40.148Z"
}

Empty scoped grants after promotion do not prove absence of organization access

Input · payload.json:

{}

CLI:

topolo actions validate app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions plan app_topolo_auth.resource_grants.list_mine --data @payload.json --json
topolo actions call app_topolo_auth.resource_grants.list_mine --data @payload.json --json

MCP call after validation and plan review:

{
  "tool": "topolo_read_action",
  "arguments": {
    "actionId": "app_topolo_auth.resource_grants.list_mine",
    "input": {}
  }
}

Captured local handler response · HTTP 200:

{
  "success": true,
  "message": "Resource grants fetched",
  "data": {
    "grants": [],
    "page": {
      "nextCursor": null,
      "hasMore": false
    }
  },
  "timestamp": "2026-10-02T18:01:40.154Z"
}

Verify the result

  • Confirm each returned grant belongs to the authenticated subject and matches the supplied filters; preserve filters and follow nextCursor until hasMore is false.

  • Use only the intended live resource/scope with the owning application. An empty grant list does not prove absence of access through organization membership or another authorization path.

Errors and recovery

Anonymous read requires an access token

Captured local refusal · HTTP 401:

{
  "input": {},
  "response": {
    "success": false,
    "error": {
      "message": "Access token required",
      "code": "AUTH_ERROR",
      "details": null,
      "timestamp": "2026-10-02T18:01:40.150Z"
    }
  }
}

Unpaired resource filter is refused

Captured local refusal · HTTP 400:

{
  "input": {
    "resource_type": "candidate"
  },
  "response": {
    "success": false,
    "error": {
      "message": "resource_type and resource_id must be provided together",
      "code": "VALIDATION_ERROR",
      "details": {
        "resourceType": false,
        "resourceId": true
      },
      "timestamp": "2026-10-02T18:01:40.150Z"
    }
  }
}

Zero timestamp cursor is refused

Captured local refusal · HTTP 400:

{
  "input": {
    "cursor": "0:rg_invalid"
  },
  "response": {
    "success": false,
    "error": {
      "message": "cursor is invalid",
      "code": "VALIDATION_ERROR",
      "details": {
        "cursor": true
      },
      "timestamp": "2026-10-02T18:01:40.150Z"
    }
  }
}

Published recovery guidance

  • VALIDATION_ERROR (HTTP 400): Correct reported fields. Pair resource filters, preserve pagination cursors and use workspace access actions for workspace grants.

  • AUTH_ERROR (HTTP 401): Inspect identity and error message: invalid token and insufficient grant authority both use 401. Refresh an expired token when necessary; obtain intended access through its authorized owner for permission denials.

  • NOT_FOUND (HTTP 404): Rediscover the exact live resource grant. Revoked rows cannot be updated; creation reactivation is a separate reviewed access grant.

  • SERVER_ERROR (HTTP 500): Inspect actual stored state before retrying. Create can fail after identity provisioning; promote can fail after membership creation. Correct unsupported SQL-constrained scope/type input; do not treat a failure as proof that nothing changed.

Recovery boundaries

Read-only; preserve filters through pagination and a denial through any access review.

Discovery and evidence

This record belongs to app_topolo_auth. Local tests prove real resource-grant SQL and handler responses with simulated identity, permissions, identity lookup/provisioning and stored-role synchronization. They do not prove recipient sign-in, invitation delivery, owning-application resource enforcement, live permissions, deployment or production completion.