Seiichi Arai
11/05/2025, 9:04 AM<http://localhost:8787> aren’t allowed as URL inputs, which makes local testing difficult.
2. One (URL, method) → only one (resource, action)
Each (url - method) can be mapped to only a single (resource-action).
Some endpoints return information across multiple resources, so we need to map to multiple resource/action pairs.
3. Multi-tenancy support
The provided example flow doesn’t seem to support a multi-tenant setup (no clear way to include tenantId).
fetch('<https://proxy.api.permit.io/proxy/xxxxxxxxxxxxxxxxxxxxxxxx?url=><PROXIED_URL>', {
method: '<HTTP_METHOD>',
headers: {
'Authorization': 'Bearer <USER_JWT>'
}
});
If I’m missing a configuration or workaround for any of the above, I’d appreciate pointers. Thanks!Ask Inkeep
11/05/2025, 9:04 AMAsk Inkeep
11/05/2025, 9:04 AM/allowed_url endpoint, you can specify the tenant (1) (2) :
{
"user": {
"key": "<mailto:raz@permit.io|raz@permit.io>"
},
"url": "<https://example.com/endpoint?param=value>",
"http_method": "POST",
"tenant": "default"
}
(1)
The fetch request you showed is for the FoAz proxy. For proper multi-tenant support, consider using the PDP directly with the /allowed_url endpoint instead of the proxy approach (1) (2) .
Given FoAz's deprecated status, I'd recommend migrating to the newer URL Mapping feature or using the PDP directly for better flexibility and ongoing support.Ask Inkeep
11/05/2025, 9:04 AMOr Weis
11/05/2025, 9:20 AMURL + verb (additional potential meta data like body content) to a specific policy object for enforcement - are you maybe missing the ability to describe parts of your incoming calls?
3. See AI answer - @Alon Boshi - let’s improve this in the docsSeiichi Arai
11/05/2025, 9:46 AMSeiichi Arai
11/05/2025, 9:48 AMAlon Boshi
11/05/2025, 11:19 AMAlon Boshi
11/05/2025, 1:38 PMAlon Boshi
11/05/2025, 2:04 PMcurl --location '<https://api.permit.io/v2/facts/support/urlmapping/proxy_configs>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer permit_key_yourKey' \
--data '{
"secret": "notUsed",
"key": "test_http",
"name": "test_http",
"auth_mechanism": "Bearer",
"mapping_rules": [
{
"url": "^<http://localhost/users/(?P><user_id>[0-9]+)/profile$",
"http_method": "post",
"resource": "customers",
"action": "create",
"url_type": "regex",
"priority": "1"
}
]
}'
Note that user_id can be used in resource.attribute based ABAC rules (similar to your tenant need). Note that the values are mapped to resource.attributes, and so it will show up as resource.tenant and not tenant.id .Alon Boshi
11/05/2025, 2:05 PMcurl --location '<http://localhost:7766/allowed_url>' \
--header 'x-permit-sdk-language: <string>' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer permit_key_yourKey' \
--data '{
"user": {
"key": "bob"
},
"http_method": "post",
"url": "<http://localhost/users/123/profile>",
"tenant": "default"
}'
Response:
{
"allow": true,
"query": {},
"debug": {
"rbac": {
"allow": true,
"allowing_roles": [
"admin"
],
"code": "allow",
"reason": "user 'bob' has the role 'admin' in tenant 'default', role 'admin' has the 'create' permission on resources of type 'customers'"
},
"request": {
"action": "create",
"resource": {
"attributes": {
"type": "customers",
"user_id": "123"
},
"type": "customers"
},
"tenant": "default",
"user": {
"attributes": {
"key": "bob",
"roles": [
"admin"
],
"tenants": [
"default"
]
},
"key": "bob",
"synced": true
}
}
},
"result": true
}
See screenshots for policy setup.Seiichi Arai
11/05/2025, 8:24 PMThe (URL, method) pair is like a translation key between the API request and the internal logic.
Each pair must be unique; otherwise, the backend wouldn’t know which internal resource or action to trigger.Regarding #2, I understand the current concept of URL mapping, but I think it’s a bit inflexible. There are situations where a user may want to assign one URL–method to multiple resource-action pairs, for example: •
GET <https://example.com/organizations/1/groups/1/members> ⇔ Member:read
Returns the list of members associated with organization 1 and group 1.
• GET <https://example.com/organizations/1/members> ⇔ Member:read
• GET <https://example.com/organizations/1/members> ⇔ Group:read
Returns the member list with group info in organization 1.
I know the principle of RESTful APIs recommends returning a single resource, but in practice it’s sometimes unavoidable to expose endpoints that return data across multiple resources.permit support automation2
11/05/2025, 8:25 PMThomas
11/05/2025, 8:33 PMThomas
11/05/2025, 8:37 PM/allowed_url does a single mapping between one resource and it's action. You can create a priority list of urls that match, and the top one will be the one that is evaluated, but really the goal is to provide a translation of url + http_verb to resource + action so that we can forward the request to OPA.Seiichi Arai
11/06/2025, 1:57 PMallowed_url api is processed, it seems only the highest-priority entry is taken into account.
I assume that’s the current behavior of the PDP.
https://github.com/permitio/PDP/blob/main/horizon/enforcer/utils/mapping_rules_utils.py#L162
As for the UI showing two registrations were treated as a single entry, I suspect that’s to keep it consistent with this behavior.Thomas
11/06/2025, 2:43 PMI assume that’s the current behavior of the PDP.correct.
As for the UI showing two registrations were treated as a single entry, I suspect that’s to keep it consistent with this behavior.no, foaz isn't technically the same as the regex url mapping. I would ignore what foaz UI shows you.