Once users can sign in, you decide what they can do. This page walks through setting up access control in your app. For the models behind it, see [Authorization (concept)](/docs/concepts/authorization).

## Pick a model for the environment

Each environment enforces **one** authorization model, chosen in the [Authdog console](https://console.authdog.com):

- **RBAC** — roles hold permissions; seat-based. The default and simplest to reason about.
- **ABAC** — Rego attribute policies, evaluated at the edge.
- **FGA** — Zanzibar-style relationship tuples for fine-grained, resource-level access.

The rest of this page uses RBAC, since it covers most apps. All three are enforced server-side.

## Define roles and permissions

In the console, create **permissions** as granular capability strings (for example `invoices:read`, `invoices:write`) and group them into **roles** (`admin`, `member`, `billing`). A role is just a named bundle of permissions.

Keep permissions fine-grained and compose them into a handful of roles — that keeps role assignment simple while route checks stay precise.

## Assign roles to users

A [user](/docs/users) can receive a role three ways:

- **Directly** — assign the role to the user in the console or via the API.
- **Via [organization](/docs/organizations) membership** — a user's role within an org grants that org's permissions.
- **Via IdP group mappings** — map an identity provider's groups to Authdog roles so access is granted automatically at sign-in. See [Provisioning](/docs/concepts/provisioning).

Group mappings are the recommended path for enterprise customers: deprovisioning in their IdP revokes access without any manual step on your side.

## Enforce a check on a route

Roles and permissions ride along in the validated session. Gate a route on a specific permission on your backend:

```ts
app.get("/invoices", requirePermission("invoices:read"), (req, res) => {
  res.json(listInvoices());
});
```

Always enforce on the server — client-side checks are for UX only, never a security boundary. See [Backend requests](/docs/backend) for wiring the gate into your framework.

## ABAC and FGA alternatives

If RBAC is too coarse for your domain:

- **ABAC** lets you write **Rego** policies over user, resource, and environment attributes — good for rules like "editors can edit only their own region."
- **FGA** stores **relationship tuples** (`user:alice editor document:42`) for per-object sharing, à la Google Docs.

Both are configured at the environment level and enforced server-side. See [Authorization (concept)](/docs/concepts/authorization) for how to choose.
