Access Request API
Manage access requests through the Permit Elements API from your own interface. This page is for developers who build a custom access request flow on top of Permit Elements, the embeddable UI components. A user asks for a role on a tenant, resource, or resource instance, and a reviewer approves or denies the request.
The requests on this page run as a user signed in to an element, with the session that your server-side login route creates. To call the same operations from a backend with your API key and no element user session, see Access Request API with an API key.
Prerequisites
- An environment API key, used to initialize the Permit SDK in your backend. See Get your API key.
- The ID or key of your project and environment. See Get the project and environment IDs.
- The ID of the element configuration, used as
elements_config_id. See List the elements in an environment. - Users synced to Permit and assigned to the tenant they request access in.
Sign in the element user
Initialize the Permit SDK
Initialize one instance of the Permit SDK in your backend. The same instance serves your permission checks and Permit Elements. Pass your environment API key to the Permit constructor.
const { Permit } = require("permitio");
const permit = new Permit(
{token: permit_key_SECRET}
);
Add a server-side login route
Create a route in your backend that signs the current user in to the element with loginAs. Match the route to the authentication method your application uses, such as a bearer token or cookies.
The loginAs method takes the unique ID of the user, usually read from the user's JSON Web Token (JWT), and the key or ID of the tenant:
permit.elements.loginAs({ userId, tenantId });
If the user is not a member of the tenant passed to loginAs, the login fails with the error USER_NOT_FOUND.
The session applies to one tenant. To switch a user to a different tenant, sign the user out and call loginAs again with the other tenant.
Passing the tenant is required for a server-side login.
Access request endpoints
All paths start with https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}. Replace <COOKIE FROM LOGIN> in the examples with the session cookie from the login route.
| Method | Path suffix | Operation | Who calls it |
|---|---|---|---|
POST | /access_requests | Create an access request | Requesting user |
GET | /access_requests/{access_request_id} | Get an access request | Reviewer |
GET | /access_requests | List access requests | Reviewer, or a user for their own requests |
PATCH | /access_requests/{access_request_id}/reviewer | Update the reviewer comment or role | Reviewer |
PUT | /access_requests/{access_request_id}/approve | Approve an access request | Reviewer |
PUT | /access_requests/{access_request_id}/deny | Deny an access request | Reviewer |
PUT | /access_requests/{access_request_id}/cancel | Cancel an access request | Requesting user |
Reviewers are users with the permission level that the element allows to manage requests, such as an admin. See Permission levels.
An access request has one of these status values: pending, approved, denied, or canceled.
Create an access request
Send a POST request to /access_requests with the details of the requested access.
| Field | Required | Description |
|---|---|---|
access_request_details.tenant | Yes | ID or key of the tenant the user requests access in |
access_request_details.role | Yes | ID or key of the requested role |
access_request_details.resource | No | ID or key of the resource the role applies to |
access_request_details.resource_instance | No | ID or key of the resource instance the role applies to |
reason | No | Business justification from the requesting user |
curl -X POST 'https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}/access_requests' \
-H 'cookie: <COOKIE FROM LOGIN>' \
-H 'origin: https://api.permit.io' \
-H 'Content-Type: application/json' \
--data-raw '{
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "done onboarding"
}'
The API returns the created access request:
{
"id": "b7a6cfc2-6a4e-4d0f-9d0a-3f0f1f0b6a11",
"requesting_user_id": "1c1e4ada-f282-40e6-b3b7-20b3a51c93b5",
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "done onboarding",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
"environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "access_request",
"status": "pending",
"reviewer_user_id": null,
"reviewed_at": null,
"reviewer_comment": null
}
The response includes the request's id, which you pass as {access_request_id} in the other calls.
The user who creates the access request must be a member of the tenant that the request is for.
Reviewer actions
Get an access request
Send a GET request to /access_requests/{access_request_id}.
curl 'https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}/access_requests/{access_request_id}' \
-H 'cookie: <COOKIE FROM LOGIN>' \
-H 'origin: https://api.permit.io'
The API returns the access request:
{
"id": "b7a6cfc2-6a4e-4d0f-9d0a-3f0f1f0b6a11",
"requesting_user_id": "1c1e4ada-f282-40e6-b3b7-20b3a51c93b5",
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "string",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
"environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "access_request",
"status": "approved",
"reviewer_user_id": "1b287364-14ff-4b72-8953-b40399093a6f",
"reviewed_at": "2019-08-24T14:15:22Z",
"reviewer_comment": "new employee"
}
List access requests
Send a GET request to /access_requests. Filter and paginate the list with these query parameters:
| Query parameter | Description |
|---|---|
status | Only requests with this status: pending, approved, denied, or canceled |
tenant | Only requests in this tenant |
role | Only requests for this role |
resource | Only requests for this resource |
resource_instance_id | For ReBAC elements, only requests for this resource instance ID or key |
page | Page number, starting at 1. Default 1. |
per_page | Results per page, maximum 100. Default 30. |
curl -G 'https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}/access_requests' \
-H 'cookie: <COOKIE FROM LOGIN>' \
-H 'origin: https://api.permit.io' \
--data-urlencode 'status=pending' \
--data-urlencode 'tenant=<TENANT_KEY>' \
--data-urlencode 'role=<ROLE_KEY>' \
--data-urlencode 'resource=<RESOURCE_KEY>' \
--data-urlencode 'resource_instance_id=<RESOURCE_INSTANCE_KEY>' \
--data-urlencode 'page=1' \
--data-urlencode 'per_page=30'
The API returns a page of access requests:
{
"data": [
{
"id": "b7a6cfc2-6a4e-4d0f-9d0a-3f0f1f0b6a11",
"requesting_user_id": "1c1e4ada-f282-40e6-b3b7-20b3a51c93b5",
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "done onboarding",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
"environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "access_request",
"status": "approved",
"reviewer_user_id": "1b287364-14ff-4b72-8953-b40399093a6f",
"reviewed_at": "2019-08-24T14:15:22Z",
"reviewer_comment": "new employee"
}
],
"total_count": 1,
"page_count": 1
}
Users who are not reviewers see only their own access requests in the list.
Update the reviewer comment or role
Send a PATCH request to /access_requests/{access_request_id}/reviewer. Both body fields are optional:
| Field | Description |
|---|---|
reviewer_comment | Comment from the reviewer |
role | ID or key of the role for the access request |
curl -X PATCH 'https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}/access_requests/{access_request_id}/reviewer' \
-H 'cookie: <COOKIE FROM LOGIN>' \
-H 'origin: https://api.permit.io' \
-H 'Content-Type: application/json' \
--data-raw '{
"reviewer_comment": "new employee",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
}'
The API returns the updated access request:
{
"id": "b7a6cfc2-6a4e-4d0f-9d0a-3f0f1f0b6a11",
"requesting_user_id": "1c1e4ada-f282-40e6-b3b7-20b3a51c93b5",
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "done onboarding",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
"environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "access_request",
"status": "approved",
"reviewer_user_id": "1b287364-14ff-4b72-8953-b40399093a6f",
"reviewed_at": "2019-08-24T14:15:22Z",
"reviewer_comment": "new employee"
}
Approve an access request
Send a PUT request to /access_requests/{access_request_id}/approve. The body is optional and accepts reviewer_comment and role.
curl -X PUT 'https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}/access_requests/{access_request_id}/approve' \
-H 'cookie: <COOKIE FROM LOGIN>' \
-H 'origin: https://api.permit.io' \
-H 'Content-Type: application/json' \
--data-raw '{
"reviewer_comment": "new employee"
}'
The API returns the approved access request with status set to approved:
{
"id": "b7a6cfc2-6a4e-4d0f-9d0a-3f0f1f0b6a11",
"requesting_user_id": "1c1e4ada-f282-40e6-b3b7-20b3a51c93b5",
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "done onboarding",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
"environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "access_request",
"status": "approved",
"reviewer_user_id": "1b287364-14ff-4b72-8953-b40399093a6f",
"reviewed_at": "2019-08-24T14:15:22Z",
"reviewer_comment": "new employee"
}
Deny an access request
Send a PUT request to /access_requests/{access_request_id}/deny. The body is optional and accepts reviewer_comment.
curl -X PUT 'https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}/access_requests/{access_request_id}/deny' \
-H 'cookie: <COOKIE FROM LOGIN>' \
-H 'origin: https://api.permit.io' \
-H 'Content-Type: application/json' \
--data-raw '{
"reviewer_comment": "need more info"
}'
The API returns the denied access request:
{
"id": "b7a6cfc2-6a4e-4d0f-9d0a-3f0f1f0b6a11",
"requesting_user_id": "1c1e4ada-f282-40e6-b3b7-20b3a51c93b5",
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "done onboarding",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
"environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "access_request",
"status": "denied",
"reviewer_user_id": "1b287364-14ff-4b72-8953-b40399093a6f",
"reviewed_at": "2019-08-24T14:15:22Z",
"reviewer_comment": "need more info"
}
Requesting user actions
Cancel an access request
Send a PUT request to /access_requests/{access_request_id}/cancel. The request has no body.
curl -X PUT 'https://api.permit.io/v2/elements/{proj_id}/{env_id}/config/{elements_config_id}/access_requests/{access_request_id}/cancel' \
-H 'cookie: <COOKIE FROM LOGIN>' \
-H 'origin: https://api.permit.io'
The API returns the canceled access request:
{
"id": "b7a6cfc2-6a4e-4d0f-9d0a-3f0f1f0b6a11",
"requesting_user_id": "1c1e4ada-f282-40e6-b3b7-20b3a51c93b5",
"access_request_details": {
"tenant": "34f5c98e-f430-457b-a812-92637d0c6fd0",
"resource": "4d5215ed-38bb-48ed-879a-fdb9ca58522f",
"resource_instance": "2d98d9f8-e1b7-4f1d-baad-2edbf6fa6c66",
"role": "ac4e70c8-d5be-48af-93eb-760f58fc91a9"
},
"reason": "done onboarding",
"organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6",
"project_id": "405d8375-3514-403b-8c43-83ae74cfe0e9",
"environment_id": "40ef0e48-a11f-4963-a229-e396c9f7e7c4",
"created_at": "2019-08-24T14:15:22Z",
"updated_at": "2019-08-24T14:15:22Z",
"type": "access_request",
"status": "canceled",
"reviewer_user_id": null,
"reviewed_at": null,
"reviewer_comment": null
}