Skip to main content
This guide walks you through setting up Permify, modeling a simple authorization policy, storing authorization data, and performing your first access check.
Permify requires PostgreSQL 13.8 or higher for production use. The quick-start below uses in-memory storage so you can get started without a database.

Set up Permify

1

Run Permify with Docker

Pull and start the Permify container with a single command:
docker run -p 3476:3476 -p 3478:3478 ghcr.io/permify/permify serve
This starts Permify with the following defaults:
PortProtocolDescription
3476REST / HTTPREST API endpoint
3478gRPCgRPC service endpoint
Authorization data is stored in memory by default. To persist data, configure a PostgreSQL database in a config YAML file and mount it into the container.
You can override any configuration option with flags. Run docker run ghcr.io/permify/permify --help to see all available flags. Environment variables are also supported — convert flag names by uppercasing and prefixing with PERMIFY_ (e.g. --log-level becomes PERMIFY_LOG_LEVEL).
2

Verify the service is running

Send a health check request to confirm Permify is up:
curl localhost:3476/healthz
A successful response confirms the service is ready to accept requests.
3

Write your authorization schema

Permify uses its own schema language to model entities, relations, and permissions. For this quickstart, we’ll model a simple organization where admins can edit files and both admins and members can view them.POST /v1/tenants/{tenant_id}/schemas/write
Request
{
  "schema": "entity user {} entity organization { relation admin @user relation member @user action view_files = admin or member action edit_files = admin }"
}
curl --location --request POST 'localhost:3476/v1/tenants/t1/schemas/write' \
--header 'Content-Type: application/json' \
--data-raw '{
  "schema": "entity user {} entity organization { relation admin @user relation member @user action view_files = admin or member action edit_files = admin }"
}'
All Permify APIs require a tenant_id. Permify supports multi-tenancy by default. Use the pre-inserted tenant t1 if you don’t need multiple tenants.
When sending a schema through the API, it must be provided as a single string. Use the Permify Playground to build and copy your schema as a formatted string.
4

Write authorization data

Now grant a user an admin role on an organization. This creates a relational tuple that Permify uses when evaluating access.POST /v1/tenants/{tenant_id}/data/write
cURL
curl --location --request POST 'localhost:3476/v1/tenants/t1/data/write' \
--header 'Content-Type: application/json' \
--data-raw '{
  "metadata": {
    "schema_version": ""
  },
  "tuples": [
    {
      "entity": {
        "type": "organization",
        "id": "1"
      },
      "relation": "admin",
      "subject": {
        "type": "user",
        "id": "1",
        "relation": ""
      }
    }
  ]
}'
This creates the tuple organization:1#admin@user:1, meaning user 1 (Ashley) has the admin role on organization 1.The response includes a snap_token:
Response
{
  "snap_token": "FxHhb4CrLBc="
}
Use snap_token values in subsequent check requests to ensure you’re reading the most up-to-date authorization data. See Snap Tokens for details.
5

Perform an access check

Check whether user 1 can view files on organization 1.POST /v1/tenants/{tenant_id}/permissions/check
cURL
curl --location --request POST 'localhost:3476/v1/tenants/t1/permissions/check' \
--header 'Content-Type: application/json' \
--data-raw '{
  "metadata": {
    "schema_version": "",
    "snap_token": "",
    "depth": 20
  },
  "entity": {
    "type": "organization",
    "id": "1"
  },
  "permission": "view_files",
  "subject": {
    "type": "user",
    "id": "1",
    "relation": ""
  }
}'
Response
{
  "can": "RESULT_ALLOW",
  "metadata": {
    "check_count": 0
  }
}
RESULT_ALLOW means the permission check passed. RESULT_DENY means it was rejected.

What’s next

You’ve completed the core Permify workflow: run the service, define a schema, write data, and check permissions. From here:
  • Modeling Authorization — learn the full Permify Schema language: entities, relations, permissions, and operators.
  • Syncing Data — understand how to keep your authorization data in sync with your application.
  • Enforcing Permissions — explore the full set of permission APIs including bulk check, lookup entity, and lookup subject.
  • Testing Authorization — write automated tests for your authorization model.
Our team is happy to help you get started. Schedule a call with a Permify engineer or join the Discord community to discuss.

Build docs developers (and LLMs) love