Figma
Proxy for the Figma REST API via the managed gateway.
What this connector does
Gives agents gated access to Figma for:
- Reading files, specific nodes, components, and version history.
- Rendering nodes to image URLs (PNG/SVG/PDF).
- Listing and posting file comments.
- Listing files in a project and projects in a team.
All operations are gated by PBAC policy. Every call flows: agent → gateway → /introspect (with this connector's resource_type) → OPA decision → Figma API → response.
The connector supports two auth modes, chosen per managed resource at install time:
- Per-user passthrough (
idp_passthrough, recommended) — the gateway forwards each calling user's own Figma OAuth token (captured when they log in to PolicyArc through the Figma IdP), asAuthorization: Bearer. Figma enforces its own file/project permissions, and its audit shows the real person. - Shared service token (
static) — every call uses one operator-held Figma personal access token via theX-Figma-Tokenheader (Figma PATs are not Bearer tokens). PolicyArc still enforces per-user policy and audit in front, but Figma sees a single identity.
Note on auth: Figma's OAuth is OAuth 2.0, not OpenID Connect — it issues no
id_token. PolicyArc still uses it as a login IdP the same way it uses GitHub: the subject is derived from the Bearer-authed userinfo endpoint (GET /v1/me). The bundledfigmaIdP preset wires this up.
Prerequisites
-
A Figma account with access to the files you want to reach.
-
Passthrough mode: a Figma IdP registered in PolicyArc with provider key
figma. Pick Figma in the IdP setup wizard — the bundled preset fills in the endpoints (authorizehttps://www.figma.com/oauth, tokenhttps://api.figma.com/v1/oauth/token, userinfohttps://api.figma.com/v1/me). You supply the Client ID / secret from a Figma OAuth app (figma.com/developers/apps) whose redirect URL is the AS's/oauth2/callback. Users must log in to PolicyArc through that Figma IdP — the gateway replays the token captured at login.Token refresh: Figma refreshes at a distinct URL (
/v1/oauth/refresh); if the deployment can't target it, users re-authenticate at token expiry. Static mode is unaffected. -
Static mode: a Figma personal access token with the scopes you want to gate, stored in a PolicyArc secret.
Install
Pick the auth mode in the install form's Authentication field (defaults to
idp_passthrough). The access-token field only appears when static is
selected; passthrough installs need no secret.
Verify
Request a token with a Figma scope and call through the gateway:
curl -X POST https://<your-as>/token \
-u "<agent-client-id>:<agent-client-secret>" \
-d "grant_type=client_credentials&scope=fig:file:read"
curl https://<your-as>/gateway/identos.figma/v1/files/<file_key> \
-H "Authorization: Bearer <token>"
A 200 with the file JSON confirms: token issued → introspect allowed → gateway proxied → upstream responded.
What can go wrong
| Symptom | Cause | Fix |
|---|---|---|
403 from Figma | Token lacks access to the file or the needed scope | Check the token's scopes and the user's file/project access. |
404 from Figma | Wrong file_key/project_id/team_id | Confirm the key from the Figma URL. |
403 from the gateway | Agent lacks the required scope | Request a token with the fig:* scope matching the route. |
404 at the gateway | Wrong path | Gateway path is /gateway/identos.figma/<Figma REST path> — Figma paths start with /v1/.... |
502 "no stored IdP token" (passthrough mode) | The caller never logged in through the figma IdP (or used client_credentials, which has no user context) | Re-authenticate via Figma. |
Scopes
| Scope | Meaning | Routes |
|---|---|---|
fig:user:read | Read the current user | get_me |
fig:file:read | Read files/nodes/images/components/versions | get_file, get_file_nodes, get_images, get_file_components, list_file_versions |
fig:comments:read | Read comments | list_comments |
fig:comments:write | Post comments | post_comment |
fig:projects:read | List project/team files | list_project_files, list_team_projects |
Policy authors can write rules targeting input.resource.type == "urn:connector:identos:figma". Per-file rules use the resource_id (figma://file/{file_key}).
Setup fields
| Field | Required | Default | Purpose |
|---|---|---|---|
upstream_auth.type | yes | idp_passthrough | Authentication — idp_passthrough (per-user, default) or static (shared token). |
token_env | conditional | — | Secret holding the Figma personal access token. Static mode only; hidden when idp_passthrough is selected. |
MCP tools
| Tool | Scope | Description |
|---|---|---|
get_me | fig:user:read | Get the authenticated Figma user. |
get_file | fig:file:read | Get a file's document tree. |
get_file_nodes | fig:file:read | Get specific nodes from a file. |
get_images | fig:file:read | Render nodes to image URLs. |
get_file_components | fig:file:read | List components in a file. |
list_file_versions | fig:file:read | List a file's version history. |
list_comments | fig:comments:read | List comments on a file. |
post_comment | fig:comments:write | Post a comment on a file. |
list_project_files | fig:projects:read | List files in a project. |
list_team_projects | fig:projects:read | List projects in a team. |
Reference
- Manifest:
connectors/identos.figma/connector.v1.jsonin the repo. - IdP preset:
src/main/resources/idp-presets/figma.json. - Upstream API docs: figma.com/developers/api
Manifest reference
- ID:
identos.figma - Version:
1.0.0 - Resource type:
urn:connector:identos:figma - Capabilities:
mcp
Supported auth modes
| Type | Details |
|---|---|
idp_passthrough | requires IdP figma |
static | scheme header; header X-Figma-Token; setup fields: token_env |
Setup fields
| ID | Label | Default | Secret? | Notes |
|---|---|---|---|---|
upstream_auth.type | Authentication | idp_passthrough | no | idp_passthrough forwards each user's own Figma OAuth token (recommended). static uses a single shared personal access token via the X-Figma-Token header. |
token_env | Personal access token | — | yes | Pick a secret containing the Figma personal access token. Required only for the static auth mode. / shown when upstream_auth.type == 'static' |
Scopes
| Scope |
|---|
fig:user:read |
fig:file:read |
fig:comments:read |
fig:comments:write |
fig:projects:read |
Routes
| Method | Pattern | Scope | Resource template |
|---|---|---|---|
GET | /v1/me | fig:user:read | figma://me |
GET | /v1/files/{file_key} | fig:file:read | figma://file/{{file_key}} |
GET | /v1/files/{file_key}/nodes | fig:file:read | figma://file/{{file_key}} |
GET | /v1/images/{file_key} | fig:file:read | figma://file/{{file_key}} |
GET | /v1/files/{file_key}/components | fig:file:read | figma://file/{{file_key}} |
GET | /v1/files/{file_key}/versions | fig:file:read | figma://file/{{file_key}} |
GET | /v1/files/{file_key}/comments | fig:comments:read | figma://file/{{file_key}} |
POST | /v1/files/{file_key}/comments | fig:comments:write | figma://file/{{file_key}} |
GET | /v1/projects/{project_id}/files | fig:projects:read | figma://project/{{project_id}} |
GET | /v1/teams/{team_id}/projects | fig:projects:read | figma://team/{{team_id}} |
MCP tools
| Name | Scope | Description |
|---|---|---|
get_me | fig:user:read | Get the authenticated Figma user. |
get_file | fig:file:read | Get a Figma file's document tree. |
get_file_nodes | fig:file:read | Get specific nodes from a Figma file. |
get_images | fig:file:read | Render nodes to image URLs (PNG/SVG/PDF). |
get_file_components | fig:file:read | List components defined in a Figma file. |
list_file_versions | fig:file:read | List the version history of a Figma file. |
list_comments | fig:comments:read | List comments on a Figma file. |
post_comment | fig:comments:write | Post a comment on a Figma file. |
list_project_files | fig:projects:read | List files in a Figma project. |
list_team_projects | fig:projects:read | List projects in a Figma team. |