Identify the caller
A session or bearer token supplies the principal for the request.
Write role-first rules that follow your schema. Access decides which rows and fields a caller may use. Better Auth handles sign-in and credentials.
.grants(({ grant, me }) => [ grant("signedIn", "update", "Note", { where: { authorId: me.id }, }),]).denies(({ deny }) => [ deny("*", "*", { if: { claims: { banned: true } }, }),]);Caller Ada · id user_adaAction update NoteRow authorId: "user_ada"Banned falseALLOW · author matches callerThe author can edit their own note. This is a local illustration of the quickstart rules.
As your application grows, permission checks spread across handlers and services. Access gives those decisions a home: role-first rules, typed from your schema, with an explanation behind each decision.
Resource names, fields, relations and enum values are checked against your schema. Mistakes surface at the key that names them.
Explore the guideNothing is allowed until a grant allows it. Any matching deny wins, regardless of rule order. Missing values fail closed.
Explore the guideApply decisions to sessions, bearer tokens, MCP agents and server code. Agents are held to their user’s grants and token scopes.
Explore the guideRecord authorization decisions in the audit log. Trace the rule that decided, so permission changes have a reason you can inspect.
Explore the guideBetter Auth handles sign-in and credentials. Access resolves permissions. The framework validates and runs the operation. Each part has a clear job.
A session or bearer token supplies the principal for the request.
Access evaluates grants and denies for the resource, action, rows and fields.
The framework applies the decision. Refused requests return 403 A4002.
Start with the Note example. Write your first rules, allow a request, and see another refused.
Build with AccessBetter Auth handles sign-in and issues credentials. Access adds authorization: which rows and fields a caller may use.
Yes. Use the policy engine alone with your own authentication, add the Access plugin to your existing Better Auth setup, or set both up together with createAccess.
The deny wins. Rule order does not change the result. A request with no matching grant is denied too.
Each service can own a namespace in the Access registry. The CLI can push, pull and verify policy files; a generated client supports services that do not run on Aventara.