Mithies Ponnusamy
10/28/2025, 5:26 AMAsk Inkeep
10/28/2025, 5:26 AMpermit support automation2
10/28/2025, 5:26 AMAsk Inkeep
10/28/2025, 5:26 AM{
user_id: str
tenant_id: str
role: str
permission_level: str
type: ElementsWebhookType = "role_assignment"
}
Alternative Approach for Your Use Case
Since Permit.io doesn't provide built-in webhooks for general permission changes, you might need to:
1. Use the Permit.io API to poll for changes periodically
2. Implement your own change detection in your auth service
3. Create SSE events from your BFF when changes are detected
For syncing users and roles, the documentation shows examples of using the Permit SDK to sync changes (2) , (3) :
await permit.api.assignRole({
role: "admin",
tenant: "default",
user: email,
}) ;
(2)
If you need webhooks specifically for permission changes rather than Elements events, you may want to reach out to Permit.io support for additional options, as this functionality isn't documented in the available sources.Ask Inkeep
10/28/2025, 5:27 AMOr Weis
10/28/2025, 6:58 AMAsk Inkeep
10/28/2025, 6:58 AMAsk Inkeep
10/28/2025, 6:58 AMOPAL_SHOULD_REPORT_ON_DATA_UPDATES=True
(2)
OPAL_DEFAULT_UPDATE_CALLBACKS={"callbacks":["<http://opal_server:7002/data/callback_report>"]}
You can configure multiple callback URLs or add custom headers :
OPAL_DEFAULT_UPDATE_CALLBACKS={"callbacks":[("<http://opal_server:7002/data/callback_report>",{"headers":{"X-My-Token":"token"}}) ]}
How It Works
When permissions change in Permit.io, the PDP receives the update and will :
1. Successfully apply the data update
2. Call your configured webhook endpoint
3. Your backend receives the callback
4. You can then trigger SSE events to your frontend
The callback uses POST method with {"content-type": "application/json"} headers by default .
Alternative: Proxy Facts for Immediate Consistency
If you need immediate consistency, consider using the proxy facts feature with proxy_facts_via_pdp=True (3) . This ensures permission changes are immediately available:
permit = Permit(
token="<your-api-key>",
pdp="<http://localhost:7766>",
proxy_facts_via_pdp=True
)
This approach waits for data synchronization before returning, ensuring your frontend gets consistent permission data immediately after changes .Ask Inkeep
10/28/2025, 6:59 AMMithies Ponnusamy
10/29/2025, 5:37 AMpermit support automation2
10/29/2025, 5:38 AMMithies Ponnusamy
10/29/2025, 5:50 AMAlon Boshi
10/29/2025, 8:31 AMOr Weis
10/29/2025, 8:44 AMAsk Inkeep
10/29/2025, 8:44 AMAsk Inkeep
10/29/2025, 8:44 AMpermit.getUserPermissions function retrieves all user permissions across all registered resources and tenants (1) . This determines all user permissions for every registered resource across all tenants .
Basic Usage Examples
const { Permit } = require("permitio") ;
const permit = new Permit({token: "<YOUR_API_KEY>", ...}) ;
const userPermissions = await permit.getUserPermissions("<mailto:john@doe.com|john@doe.com>") ;
import io.permit.sdk.Permit;
import io.permit.sdk.PermitConfig;
import io.permit.sdk.enforcement.*;
import java.util.Arrays;
Permit permit = new Permit(
new PermitConfig.Builder("[YOUR_API_KEY]") .build()
) ;
UserPermissions permissions = permit.getUserPermissions(
new GetUserPermissionsQuery(
User.fromString("<mailto:john@doe.com|john@doe.com>")
)
) ;
Filtering Results
You can filter by tenants, resource_types, or specific resources :
const userPermissions = await permit.getUserPermissions(
"<mailto:john@doe.com|john@doe.com>",
["tenant-1", "tenant-2"], // tenants
["document:doc-1", "document:doc-2"] // resources
["document", "__tenant"], // resource_types
) ;
List Role Assignments (Local PDP API)
The permit.pdp_api.role_assignments.list function returns role assignments from the local PDP (2) . Available from PDP container version permitio/pdp-v2:0.3.0 and above .
from permit.models.pdp import RoleAssignmentRead
permissions: RoleAssignmentRead = permit.pdp_api.role_assignments.list() ;
Filter by User
from permit.models.pdp import RoleAssignmentRead
permissions: RoleAssignmentRead = permit.pdp_api.role_assignments.list(
user="John",
)
Filter by Resource Instance
from permit.models.pdp import RoleAssignmentRead
permissions: RoleAssignmentRead = permit.pdp_api.role_assignments.list(
resource_instance_key="document:onboarding-doc",
)
Additional Advanced Queries
Bulk Check
For checking multiple permissions in a single call (3) :
const permitted = await permit.bulkCheck([
{ user: "<mailto:anna@smith.com|anna@smith.com>", action: "read", resource: "contract" },
{ user: "<mailto:anna@smith.com|anna@smith.com>", action: "create", resource: "document" },
{ user: "<mailto:john@walker.com|john@walker.com>", action: "sign", resource: "contract" },
{ user: "<mailto:jane@jarvis.com|jane@jarvis.com>", action: "authorize", resource: "invoice" },
]) ;
Get Authorized Users
To retrieve users authorized for a specific action on a resource :
from permit import AuthorizedUsersResult
authorized_users: AuthorizedUsersResult = permit.authorized_users(
"read", "repo",
)
These APIs can be called directly from your local PDP to avoid network latency and provide faster responses (2) .Ask Inkeep
10/29/2025, 8:44 AMMithies Ponnusamy
10/30/2025, 10:20 AMAlon Boshi
10/30/2025, 10:23 AMMithies Ponnusamy
10/30/2025, 10:24 AMAlon Boshi
10/30/2025, 10:30 AMcallbacks field.
@Ask Inkeep Can you expand on that?Ask Inkeep
10/30/2025, 10:30 AMAsk Inkeep
10/30/2025, 10:30 AMOPAL_DEFAULT_UPDATE_CALLBACKS - it needs to be a JSON object with a callbacks field containing an array (1) .
The correct format should be:
OPAL_DEFAULT_UPDATE_CALLBACKS={"callbacks":["<http://host.docker.internal:8011/sse/pdp-update>"]}
Or with custom headers:
OPAL_DEFAULT_UPDATE_CALLBACKS={"callbacks":[("<http://host.docker.internal:8011/sse/pdp-update>",{"headers":{"Authorization":"Bearer token"}}) ]}
The PDP also supports the PDP_DATA_UPDATE_CALLBACKS configuration which expects a JSON array format (2) :
PDP_DATA_UPDATE_CALLBACKS=[{"url": "<http://example.com/callback>","key": "example","config": {"headers": {"Authorization": "Bearer token"},"method": "GET","data": {"key": "value"}}}]
The default config for callbacks is {"method": "POST"} .
For debugging this issue, could you share:
1. Which Workspace / Project / Env you are using
2. What calls you are performing (as SDK code or CURL)
3. Which PDP version you are running
4. The full PDP logs showing the crashAsk Inkeep
10/30/2025, 10:30 AMAlon Boshi
10/30/2025, 10:33 AMdocker run -it \
-p 7766:7000 \
--env PDP_API_KEY={your-api-key} \
--env PDP_DEBUG=True \
--env 'PDP_DATA_UPDATE_CALLBACKS=[{"url":{"your-webhoook"}]' \
permitio/pdp-v2:latestAlon Boshi
10/30/2025, 10:34 AMMithies Ponnusamy
10/30/2025, 10:38 AMMithies Ponnusamy
10/30/2025, 12:56 PMOr Weis
10/30/2025, 12:58 PMMithies Ponnusamy
10/30/2025, 1:12 PMOr Weis
10/30/2025, 1:14 PMMithies Ponnusamy
10/30/2025, 1:15 PMMithies Ponnusamy
10/30/2025, 1:16 PMOr Weis
10/30/2025, 1:17 PMbut it took around 10 to 15 sec while I try to fetch the policies and permission from the permit.io sdk and apiWhich APIs are you calling? - this doesn’t sound likely
Or Weis
10/30/2025, 1:19 PMOr Weis
10/30/2025, 1:20 PMOr Weis
10/30/2025, 1:20 PM