---
title: Access Checks
description: Ask whether a user can perform an action on a resource.
showNextPage: true
originalPath: .tmp-workos-clone/packages/docs/content/fga/access-checks.mdx
---

## Overview

Access checks answer: "Can this user do this action on this resource?"

FGA looks at all the ways the user might have access—a role assigned directly on the resource, a role on a parent resource that grants inherited permissions, or an organization-level role. If any grant the permission, the user is authorized.

---

## A quick example

Alice wants to deploy an app. Here's her access:

```text
Org: Acme (Alice: org-member)
└─ Workspace: Engineering (Alice: workspace_admin)
   └─ Project: Web
      └─ App: Frontend
```

**Can Alice deploy App: Frontend?** Yes—her `workspace-admin` role includes `app:deploy`, which flows down to all apps in that workspace.

---

## Checking permissions

**JWT (fast)** – For org-wide permissions, check the token directly. No API call needed. Good for navigation and feature flags.

**API (precise)** – For resource-specific permissions, call the authorization API:

```bash
curl https://api.workos.com/authorization/organization_memberships/om_01HXYZ/check \
  -X POST \
  -H "Authorization: Bearer sk_example_123456789" \
  -H "Content-Type: application/json" \
  -d '{
    "permission_slug": "project:edit",
    "resource_id": "authz_resource_01HXYZ"
  }'
```

Response:

```json
{
  "authorized": true
}
```

For best performance, check the JWT first for org-wide permissions, then fall back to the API for resource-specific checks.

---

## Integrating access checks in your application

Here's how you might protect an API endpoint that updates a project. Before performing the operation, check whether the user has the `proj:edit` permission on the specific project they're trying to modify:

```javascript
import { WorkOS } from '@workos-inc/node';

const workos = new WorkOS(process.env.WORKOS_API_KEY);

app.patch('/projects/:projectId', async (req, res) => {
  const { organizationMembershipId } = req.user;
  const { projectId } = req.params;

  // Check if the user can edit this project
  const { authorized } = await workos.authorization.check({
    organizationMembershipId,
    permissionSlug: 'proj:edit',
    resourceExternalId: projectId,
    resourceTypeSlug: 'project',
  });

  if (!authorized) {
    return res.status(403).json({ error: 'Forbidden' });
  }

  // User is authorized — proceed with the update
  const project = await updateProject(projectId, req.body);
  return res.json(project);
});
```

The `check()` method evaluates all possible sources of access — direct assignments on the project, inherited permissions from a parent workspace, and organization-level roles. You don't need to check each level yourself.

---

## Common use cases

**Protecting actions** – Before a user performs an action, check if they're allowed. Return 403 if not.

**Showing or hiding UI** – Check permissions before rendering to show edit buttons, delete options, or admin settings only to authorized users.

**Filtering lists** – Only show resources the user can access in navigation and search results.

---

## Performance

- **Sub-50ms** response times (p95)
- **Strong consistency**—role changes take effect immediately
- **High availability** for production workloads
