**Authorization** answers the question that comes right after [authentication](/docs/concepts/authentication): _now that we know who you are, what are you allowed to do?_ Authdog enforces authorization on the server, per environment, using one of three models you choose to match how your product thinks about access.

For a task-oriented walkthrough of setting up roles, see [Roles & permissions](/docs/permissions).

## Authentication vs authorization

They are distinct steps and it pays to keep them separate:

- **Authentication** establishes identity — the [session](/docs/concepts/sessions-tokens) proves _who_ the caller is.
- **Authorization** evaluates a decision — given that identity (and sometimes the resource and context), _is this action allowed?_

A request is authenticated once; it may be authorized many times, once per protected action.

## Pick one model per environment

Each Authdog environment runs exactly **one** authorization model. This keeps enforcement unambiguous — a single engine decides every request — and lets you use a lightweight model in one environment and a richer one in another without rewriting your app.

| Model | Decides based on | Best when |
| --- | --- | --- |
| **RBAC** | the roles a user holds | access maps cleanly to job functions |
| **ABAC** | attributes of user, resource, and context | rules depend on data (department, ownership, time) |
| **FGA** | relationships between users and objects | access is per-object and hierarchical (folders, docs, teams) |

### RBAC — role-based access control

The default. You define **roles**, grant each role a set of **permissions**, and give users roles. A user's effective permissions are the union of every role they hold. Roles can be assigned directly, inherited through an [organization](/docs/organizations) membership, or granted automatically from IdP/HRIS groups via [provisioning](/docs/concepts/provisioning) group-to-role mappings.

```
role: editor      permissions: [post.read, post.write]
role: admin       permissions: [post.*, user.manage]
user jane -> [editor]     ⇒ can post.read, post.write
```

RBAC is seat-based and easy to reason about — start here unless you already know you need more.

### ABAC — attribute-based access control

When access depends on _data_ rather than a fixed role — "a manager can approve expenses under $5,000 in their own department" — RBAC's role explosion gets painful. ABAC evaluates a **policy** against attributes of the subject, the resource, and the request context.

Authdog policies are written in **Rego** (the Open Policy Agent language) and evaluated **at the edge**, in-process, with no external policy server and no network hop. Policies are authored per environment and versioned.

```rego
package authdog.authz

default allow = false

allow {
    input.user.department == input.resource.department
    input.action == "approve"
    input.resource.amount < 5000
}
```

### FGA — fine-grained (relationship) authorization

For per-object permissions that follow relationships — "users who can view a folder can view every document inside it" — Authdog offers a **Zanzibar-style** model. You write **relationship tuples** (`document:readme#viewer@user:jane`) and an authorization model describing how relations rewrite and inherit, then ask `check(user, relation, object)`.

```
tuple: folder:eng#viewer@user:jane
tuple: document:spec#parent@folder:eng
check(user:jane, viewer, document:spec) -> allowed (inherited via parent)
```

FGA shines for collaborative, document-centric products where access is defined object-by-object.

## How enforcement works

Whichever model an environment uses, the decision happens **server-side** before your resolver or handler runs — the client cannot bypass it. The engine reads the caller's identity from the validated [session](/docs/concepts/sessions-tokens), loads the environment's roles/policies/tuples, and returns allow or deny (fail-closed on any error). Tenant owners always retain management access.

## Choosing a model

- Reach for **RBAC** first — most apps never outgrow it.
- Move to **ABAC** when decisions depend on resource or contextual data.
- Move to **FGA** when access is defined per object and inherited through hierarchies.

You can run different models in different environments, so it's safe to prototype a richer model in staging.

## Related

- [Roles & permissions](/docs/permissions) — set up RBAC in practice
- [Organizations](/docs/organizations) — org-scoped role assignment
- [Provisioning](/docs/concepts/provisioning) — auto-granting roles from IdP/HRIS groups
- [Sessions & tokens](/docs/concepts/sessions-tokens) — the identity every decision is keyed on
