Strict mode for Ory Permissions
What is strict mode?
Strict mode makes the Ory Permissions engine treat your OPL as the single source of truth during every check. Without strict mode, the engine doesn't use your OPL declarations to filter which tuples it follows — it may follow subject-set pointers that your OPL doesn't specify.
Strict mode is disabled by default. Enable it in the Ory Console under Permissions > Configuration.
Why enable strict mode?
Strict mode improves both performance and correctness:
- Fewer queries. Ory Keto skips evaluation steps that are impossible given your schema — following undeclared subject-set
pointer types, and direct tuple checks on
permitsrules. - No stale grants. Tuples that reference relations removed from your OPL no longer grant access.
- Explicit errors when limits are reached. Ory Permissions enforces depth and width limits to prevent unbounded graph
traversal. In non-strict mode, hitting a limit silently returns
{ "allowed": false }— identical to a legitimate denial. In strict mode, the engine returns an explicit error so you can tell the check was cut short.
| Scenario | Non-strict | Strict |
|---|---|---|
| Limit hit during single check | { "allowed": false } | 422 Unprocessable Entity with reason |
| Limit hit during batch check | { "allowed": false } | { "allowed": false, "error": "max depth reached" } |
Ory Network enforces fixed depth and width limits that cannot be changed in the console. If you hit a limit, contact Ory support to discuss your use case.
Patterns that break in strict mode
These patterns work in non-strict mode but break after enabling strict mode.
Subject-set tuples for undeclared types
This covers any tuple that points to a subject-set type your OPL doesn't declare for that relation.
Example: viewers is declared as User[], but a tuple pointing to a Group subject-set was written:
class File implements Namespace {
related: {
viewers: User[] // only Users allowed
}
}
Writing a tuple like this — which assigns a Group subject-set to the viewers relation — will be ignored in strict mode:
keto relation-tuple create Group:engineering#members viewers File:readme
Declare the type in OPL to keep it working:
viewers: (User | SubjectSet<Group, "members">)[]
The same applies in reverse: if viewers is declared as SubjectSet<Group, "members">[] but a direct user tuple was written:
File:readme#viewers@User:alice
Strict mode ignores it because User is not a declared type for that relation.
Tuples written directly against permit relations
Example: canView is a computed permit, but a tuple was written against it directly:
class File implements Namespace {
related: {
editors: User[]
viewers: User[]
}
permits = {
canView: (ctx: Context) => this.related.editors.includes(ctx.subject) || this.related.viewers.includes(ctx.subject),
}
}
File:readme#canView@User:alice
Strict mode skips direct tuple checks on permits rules. Write tuples against editors or viewers instead.
Stale tuples from a renamed or removed relation
If you renamed or removed a relation in OPL but didn't clean up the old tuples, in rare setups, Ory Keto in non-strict mode still follows them. Strict mode ignores them immediately.
How to check if you're ready
Audit two things before enabling:
-
Tuple writes — every relation you write tuples against should exist in your OPL, and the subject type should match what the relation declares. For example, if your application writes:
Document:readme#editors@User:alicecheck that the
Documentnamespace in your OPL declares aneditorsrelation, and that it acceptsUseras a subject type:class Document implements Namespace {related: {editors: User[]}} -
Check requests — every relation you check should be defined in your OPL. For example, if your application calls:
is User:alice allowed to editors on Document:readmeverify that
editorsis declared in theDocumentnamespace.
If both are consistent with your OPL, enabling strict mode produces identical results to non-strict mode — with faster permission checks.
See the Ory Permission Language guide.
Enabling and disabling
Go to the Ory Console, select your project, and navigate to Permissions > Configuration. Toggle Strict mode on or off and save. The change takes effect immediately — no restart required, and no data is modified.
