//Role & Access Check API

Role & Access Check API

ButtrBase exposes three endpoints that your app's frontend and backend can call to validate who a user is, what they're allowed to do, and whether they hold an admin role within a specific app context.

Token Introspection — GET /api/auth/me

Returns the full decoded payload of the caller's access token. Use this in your frontend to drive permission-aware UI without parsing JWTs yourself.

~~~http GET /api/auth/me Authorization: Bearer ~~~

~~~jsonc // 200 OK { "user_uuid": "usr_01abc...", "email": "alice@acme.com", "org_uuid": "org_01def...", "org_name": "Acme Corp", "roles": ["member", "admin"], "entitlements": ["advanced_analytics", "sso"], "app_admin": ["app_01ghi..."], // apps this user can admin "platform_admin": false, "sandbox": false } ~~~

app_admin is an array so one user can admin multiple apps. If the user is the org owner they implicitly have app admin rights for every app the org publishes — this is reflected in the response without an explicit grant row.

---

Feature & Role Check — POST /api/entitlements/check

Checks whether the caller has a specific entitlement or role. Designed for app backends to use on the hot path — the check runs against the already-decoded token and does not re-verify the full JWT chain.

~~~http POST /api/entitlements/check Authorization: Bearer Content-Type: application/json

{ "feature": "admin_panel", "org_uuid": "org_01def..." } ~~~

~~~jsonc // 200 OK { "granted": true, "reason": "role:app_admin" // or "entitlement:admin_panel" or "denied" } ~~~

reason values

| Value | Meaning | |-------|---------| | role:app_admin | User has an app_admin grant for this app | | role:platform_admin | User holds a platform_admin credential | | entitlement: | Feature entitlement is active for the org | | denied | Neither role nor entitlement matched |

Use this in Axum/Express/Django middleware to gate routes without adding a database roundtrip per request.

---

App Access Check — GET /api/marketplace/apps/:app_id/access

Returns the caller's relationship to a specific marketplace app. Call this from your app's frontend to decide which UI to render, or from your backend to enforce admin-only routes.

~~~http GET /api/marketplace/apps/app_01ghi.../access Authorization: Bearer ~~~

~~~jsonc // 200 OK { "is_app_admin": true, "is_org_owner": false, "install_status": "active", // or "suspended" | "deprovisioned" | null "install_id": "inst_01jkl..." } ~~~

install_status is null if the caller's org has never installed this app.

---

JWT Claim Structure

All three endpoints derive their response from claims already embedded in the access token. You can inspect these locally using the SDK's verify_token method without making any API call:

~~~jsonc // Decoded JWT payload { "sub": "usr_01abc...", "org": "org_01def...", "roles": ["admin"], "entitlements": ["sso"], "app_admin": ["app_01ghi..."], "platform_admin": false, "sandbox": false, "exp": 1748000000, "iat": 1747999100 } ~~~

platform_admin and app_admin are populated at token issuance and remain valid until the token expires. If you grant or revoke app admin access you should instruct the affected user to refresh their token to pick up the change.

---

SDK Methods

Rust

~~~rust use buttrbase_sdk::ButtrBaseClient;

let bb = ButtrBaseClient::new("bb_live_cid_...", "bb_live_sk_...");

// Local JWT verification — no network call let claims = bb.verify_token(&bearer).await?; let is_app_admin = claims.app_admin.contains(&app_id);

// Remote entitlement check let result = bb.check_entitlement(&bearer, "admin_panel").await?; if result.granted { / allow access / }

// App access check (new) let access = bb.check_app_access(&bearer, &app_id).await?; if access.is_app_admin { / show admin UI / } ~~~

Node

~~~typescript import { ButtrBaseClient } from '@buttrbase/sdk';

const bb = new ButtrBaseClient({ clientId: '...', clientSecret: '...' });

const claims = await bb.verifyToken(bearer); const check = await bb.checkEntitlement(bearer, 'admin_panel'); const access = await bb.checkAppAccess(bearer, appId); ~~~

Python

~~~python from buttrbase import ButtrBaseClient

bb = ButtrBaseClient(client_id='...', client_secret='...')

claims = await bb.verify_token(bearer) check = await bb.check_entitlement(bearer, 'admin_panel') access = await bb.check_app_access(bearer, app_id) ~~~