Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Permify/permify/llms.txt
Use this file to discover all available pages before exploring further.
Testing is essential when building and maintaining an authorization system. Permify provides a structured way to test your schema (authorization model) together with sample data and expected access check outcomes — all in a single YAML file.
How testing works
Permify validation uses a YAML file with three sections:
| Section | Purpose |
|---|
schema | The authorization model to test |
relationships | Sample authorization data (relational tuples) |
scenarios | Test cases: access checks, entity filters, and subject filters |
You can run validation:
- Locally using the
permify validate CLI command.
- In CI using the permify-validate-action GitHub Action.
- Coverage analysis using
permify coverage.
Schema validation file
Here is a complete example:
schema: >-
entity user {}
entity organization {
relation admin @user
relation member @user
action create_repository = (admin or member)
action delete = admin
}
entity repository {
relation owner @user @organization#member
relation parent @organization
action push = owner
action read = (owner and (parent.admin and parent.member))
action delete = (parent.member and (parent.admin or owner))
action edit = parent.member not owner
}
relationships:
- "organization:1#admin@user:1"
- "organization:1#member@user:1"
- "repository:1#owner@user:1"
- "repository:2#owner@user:2"
- "repository:2#owner@user:3"
- "repository:1#parent@organization:1#..."
- "organization:1#member@user:43"
- "repository:1#owner@user:43"
scenarios:
- name: "scenario 1"
description: "test description"
checks:
- entity: "repository:1"
subject: "user:1"
assertions:
push: true
owner: true
- entity: "repository:2"
subject: "user:1"
assertions:
push: false
- entity: "repository:3"
subject: "user:1"
context:
- "repository:3#owner@user:1"
assertions:
push: true
- entity: "repository:1"
subject: "user:43"
assertions:
edit: false
entity_filters:
- entity_type: "repository"
subject: "user:1"
context:
- "repository:3#owner@user:1"
- "repository:4#owner@user:1"
- "repository:5#owner@user:1"
assertions:
push: ["1", "3", "4", "5"]
edit: []
subject_filters:
- subject_reference: "user"
entity: "repository:1"
context:
- "organization:1#member@user:58"
assertions:
push: ["1", "43"]
edit: ["58"]
Defining the schema
You can embed the schema inline or reference an external file or URL:
schema: >-
entity user {}
entity organization {
...
}
schema: /path/to/your/schema/file.txt
schema: https://example.com/path/to/schema.txt
Creating test scenarios
Scenarios are test cases grouped under a name and description. Each scenario can contain access checks, entity filters, and subject filters.
scenarios:
- name: # name of the scenario
description: # description of the scenario
checks: # simple access check cases
entity_filters: # lookup-entity queries
subject_filters: # lookup-subject queries
Access checks
Use checks to test whether a subject can perform an action on an entity:
checks:
- entity: "repository:3" # resource to check access for
subject: "user:1" # subject performing the check
depth: 100 # traversal depth (default: 100, minimum: 3)
context: # contextual tuples evaluated alongside stored data
- "repository:3#owner@user:1"
assertions: # expected results for each action
push: true
The context field lets you inject additional relational tuples that are evaluated alongside your stored data for that specific check — useful for dynamic scenarios involving time, IP address, or other runtime conditions.
Depth configuration:
The depth parameter controls how deeply the permission engine traverses the relationship graph:
| Setting | Behavior |
|---|
0 or omitted | Defaults to 100 |
| Minimum allowed | 3 |
| Recommended for shallow hierarchies | 3–5 |
| Recommended for deep hierarchies | 20–50 |
If you encounter “depth not enough” errors, increase the depth for that check.
Entity filtering
Use entity_filters to test lookup-entity queries — which resources of a given type can a subject access?
entity_filters:
- entity_type: "repository" # type of entity to filter
subject: "user:1" # subject performing the lookup
depth: 100
context:
- "repository:3#owner@user:1"
- "repository:4#owner@user:1"
- "repository:5#owner@user:1"
assertions:
push: ["1", "3", "4", "5"] # expected entity IDs
edit: []
Unlike access checks, assertions for entity filters specify the IDs of entities expected to be returned, not a boolean.
Subject filtering
Use subject_filters to test lookup-subject queries — which subjects can perform an action on a given entity?
subject_filters:
- subject_reference: "user" # type of subject to filter
entity: "repository:1" # entity to check access on
depth: 100
context:
- "organization:1#member@user:58"
assertions:
push: ["1", "43"] # expected subject IDs
edit: ["58"]
Running tests locally
To validate a schema file locally, build Permify and run:
make build
./permify validate {path-to-your-validation-file.yaml}
A successful run prints a validation summary in the terminal. Failures show which assertions did not match the expected results.
Running tests in CI with GitHub Actions
Add the permify-validate-action to your GitHub Actions workflow:
steps:
- uses: "permify/permify-validate-action@v1.0.0"
with:
validationFile: "test.yaml"
steps:
- uses: "permify/permify-validate-action@v1.0.0"
with:
validationFile: "https://gist.github.com/permify-bot/bb8f95acb64525d2a41688ae0a6f4274"
Coverage analysis
Measure how well your test file covers your schema:
permify coverage {path-to-your-validation-file.yaml}
Coverage is calculated by analyzing which relationships and assertions in your schema are exercised by the validation file. Missing coverage highlights untested parts of your authorization model.
AST conversion
Convert your schema to an Abstract Syntax Tree (AST) for structural inspection or tooling integration:
permify ast {path-to-your-validation-file.yaml}
This confirms your schema is syntactically valid and can be consumed by downstream tools.
Best practices
- Store your schema in a version-controlled repository (e.g. Git) and require code review for all changes.
- Run the schema validator in your CI pipeline on every pull request using the GitHub Action.
- Use Permify’s in-memory database in unit tests so each test starts with a clean, isolated state.
- Write scenarios that cover both positive checks (access should be granted) and negative checks (access should be denied).
- Include
entity_filters and subject_filters scenarios to test your lookup queries, not just point-in-time access checks.
See the Authorization Service overview for guidance on managing schema changes in production.