Skip to main content
figma-enterprise-rbac Configure Figma Enterprise features: OAuth 2.0, team management, and access control.
Use when implementing OAuth flows, managing team/project access via API,
or building Enterprise-level Figma integrations.
Trigger with phrases like "figma enterprise", "figma OAuth",
"figma team management", "figma access control", "figma SCIM".
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill figma-enterprise-rbac명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... jeremylongshore
jeremylongshore/claude-code-plugins-plus-skills
GitHub 저장소 열기 name figma-enterprise-rbac description Configure Figma Enterprise features: OAuth 2.0, team management, and access control.
Use when implementing OAuth flows, managing team/project access via API,
or building Enterprise-level Figma integrations.
Trigger with phrases like "figma enterprise", "figma OAuth",
"figma team management", "figma access control", "figma SCIM".
allowed-tools Read, Write, Edit version 1.6.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","figma"] compatibility Designed for Claude Code
Figma Enterprise RBAC
Overview
Figma Enterprise features accessible via the REST API: OAuth 2.0 for user-facing apps, team/project management, and the Variables API (Enterprise-only). This skill covers building OAuth integrations and managing organizational access.
Prerequisites
Figma Enterprise or Organization plan
OAuth app registered in Figma developer dashboard
Understanding of OAuth 2.0 authorization code flow
Instructions
Step 1: OAuth 2.0 App Setup
function getAuthUrl (state : string ): string {
const params = new URLSearchParams ({
client_id : process.env .FIGMA_CLIENT_ID !,
redirect_uri : process.env .FIGMA_REDIRECT_URI !,
scope : 'file_content:read,file_comments:write,file_variables:read' ,
state,
response_type : 'code' ,
});
return `https://www.figma.com/oauth?${params} ` ;
}
async function exchangeCode (code : string ): Promise <{
access_token : string ;
refresh_token : string ;
expires_in : number ;
user_id : ;
}> {
res = ( , {
: ,
: { : },
: ({
: process. . !,
: process. . !,
: process. . !,
code,
: ,
}),
});
(!res. ) {
error = res. ();
( );
}
res. ();
}
( ): <{
: ;
: ;
}> {
res = ( , {
: ,
: { : },
: ({
: process. . !,
: process. . !,
: refreshToken,
}),
});
(!res. ) ( );
res. ();
}
string
const
await
fetch
'https://api.figma.com/v1/oauth/token'
method
'POST'
headers
'Content-Type'
'application/x-www-form-urlencoded'
body
new
URLSearchParams
client_id
env
FIGMA_CLIENT_ID
client_secret
env
FIGMA_CLIENT_SECRET
redirect_uri
env
FIGMA_REDIRECT_URI
grant_type
'authorization_code'
if
ok
const
await
text
throw
new
Error
`Token exchange failed: ${res.status} ${error} `
return
json
async
function
refreshAccessToken
refreshToken : string
Promise
access_token
string
expires_in
number
const
await
fetch
'https://api.figma.com/v1/oauth/refresh'
method
'POST'
headers
'Content-Type'
'application/x-www-form-urlencoded'
body
new
URLSearchParams
client_id
env
FIGMA_CLIENT_ID
client_secret
env
FIGMA_CLIENT_SECRET
refresh_token
if
ok
throw
new
Error
`Token refresh failed: ${res.status} `
return
json
Step 2: OAuth Callback Handler
app.get ('/auth/figma/callback' , async (req, res) => {
const { code, state } = req.query ;
if (state !== req.session .oauthState ) {
return res.status (403 ).json ({ error : 'Invalid state parameter' });
}
try {
const tokens = await exchangeCode (code as string );
const userRes = await fetch ('https://api.figma.com/v1/me' , {
headers : { Authorization : `Bearer ${tokens.access_token} ` },
});
const user = await userRes.json ();
await saveUserTokens (user.id , {
accessToken : tokens.access_token ,
refreshToken : tokens.refresh_token ,
expiresAt : new Date (Date .now () + tokens.expires_in * 1000 ),
});
res.redirect ('/dashboard?connected=figma' );
} catch (error) {
console .error ('Figma OAuth error:' , error);
res.redirect ('/settings?error=figma_auth_failed' );
}
});
Step 3: Team and Project Management
async function getTeamProjects (teamId : string , token : string ) {
const res = await fetch (
`https://api.figma.com/v1/teams/${teamId} /projects` ,
{ headers : { Authorization : `Bearer ${token} ` } }
);
return res.json ();
}
async function getProjectFiles (projectId : string , token : string ) {
const res = await fetch (
`https://api.figma.com/v1/projects/${projectId} /files` ,
{ headers : { Authorization : `Bearer ${token} ` } }
);
return res.json ();
}
async function getTeamComponents (teamId : string , token : string ) {
const res = await fetch (
`https://api.figma.com/v1/teams/${teamId} /components` ,
{ headers : { Authorization : `Bearer ${token} ` } }
);
return res.json ();
}
async function getTeamStyles (teamId : string , token : string ) {
const res = await fetch (
`https://api.figma.com/v1/teams/${teamId} /styles` ,
{ headers : { Authorization : `Bearer ${token} ` } }
);
return res.json ();
}
Step 4: Variables API (Enterprise Only)
async function getLocalVariables (fileKey : string , token : string ) {
const res = await fetch (
`https://api.figma.com/v1/files/${fileKey} /variables/local` ,
{ headers : { Authorization : `Bearer ${token} ` } }
);
if (res.status === 403 ) {
throw new Error ('Variables API requires Figma Enterprise plan' );
}
return res.json ();
}
async function getPublishedVariables (fileKey : string , token : string ) {
const res = await fetch (
`https://api.figma.com/v1/files/${fileKey} /variables/published` ,
{ headers : { Authorization : `Bearer ${token} ` } }
);
return res.json ();
}
async function updateVariables (
fileKey : string ,
changes : VariableChanges ,
token : string
) {
const res = await fetch (
`https://api.figma.com/v1/files/${fileKey} /variables` ,
{
method : 'POST' ,
headers : {
Authorization : `Bearer ${token} ` ,
'Content-Type' : 'application/json' ,
},
body : JSON .stringify (changes),
}
);
return res.json ();
}
Step 5: Access Control Middleware
async function requireFigmaAccess (fileKey : string ) {
return async (req : Request , res : Response , next : NextFunction ) => {
const userToken = await getUserFigmaToken (req.user .id );
if (!userToken) {
return res.status (403 ).json ({ error : 'Figma account not connected' });
}
const check = await fetch (
`https://api.figma.com/v1/files/${fileKey} ?depth=1` ,
{ headers : { Authorization : `Bearer ${userToken} ` } }
);
if (check.status === 403 ) {
return res.status (403 ).json ({ error : 'No access to this Figma file' });
}
next ();
};
}
Output
OAuth 2.0 flow with authorization, token exchange, and refresh
Team/project/file listing via API
Variables API access (Enterprise)
Access control middleware for file-level permissions
Error Handling Error Cause Solution OAuth code expired Exchange took >30s Exchange immediately on callback Token refresh failed Refresh token revoked Re-authenticate user through OAuth flow 403 on Variables API Not Enterprise plan Use styles API instead (available on all plans) Team components empty No published components Publish components in Figma first
Examples Complete the OAuth flow locally and inspect the granted user (Steps 1-2):
curl -s -H "Authorization: Bearer ${FIGMA_OAUTH_TOKEN} " https://api.figma.com/v1/me \
| jq '{handle, email}'
List a project's files as that user — RBAC means you only see what the user can (Step 3):
curl -s -H "Authorization: Bearer ${FIGMA_OAUTH_TOKEN} " \
"https://api.figma.com/v1/projects/${PROJECT_ID} /files" | jq '.files[].name'
A 403 here is working access control, not a bug — route it through the Step 5 middleware. Variables API (Enterprise-only) usage: references/variables-api-enterprise-only.md.
Resources
Next Steps For major migrations, see figma-migration-deep-dive.