I have an attribute "ViewUsersOnly" (string array)...
# permit-saas
s
I have an attribute "ViewUsersOnly" (string array) in my resource and an attribute "company" (string) in users. I have a resource set that I created for my ABAC policy with a condition [resource.ViewUsersOnly] [array contains (ref)] [user.key] and it yields the resource when ViewUsersOnly contains the key of the user. But this resource set yields even after I changed the resource set to [resource.ViewUsersOnly] [array contains (ref)] [user.company]. Am I missing something?
a
Hi @Shyamalan Chemmery, I'm an AI assistant for Permit.io. I'll analyze available sources and get back to you shortly.
p
Hey, thanks for reaching out ! It seems our team is a little busy right now, a human will be with you within the next hour or so. In the meantime, can I help you ?
a
Based on the ABAC condition set examples in the documentation, when you use the
ref
operator in a condition, it creates a reference to compare attributes between the user and resource. (1) Looking at the documented examples, the
ref
operator is used to compare resource attributes with user attributes. For instance, in the Teleco Demo Application, there's a condition that checks if
resource.owner
equals
user.key
using:
Copy code
{
  "allOf": [
    {
      "allOf": [
        {
          "resource.owner": {
            "equals": {
              "ref": "user.key"
            }
          }
        }
      ]
    }
  ]
}
The issue you're experiencing might be related to how the condition is evaluated. When you changed from
user.key
to
user.company
, the condition
[resource.ViewUsersOnly] [array contains (ref) ] [user.company]
would check if the ViewUsersOnly array contains the value of the user's company attribute, not the user's key. If the resource set is still matching when it shouldn't, this could indicate that: 1. The ViewUsersOnly array might contain values that match the user's company attribute 2. There might be cached policy data that needs to be refreshed 3. The condition might need to be restructured To help our engineers investigate this further: 1. Which Workspace / Project / Env are you using? 2. What calls are you performing (as SDK code or CURL) ? 3. Which PDP version are you running? 4. Could you share relevant logs from your PDP? This information will help us understand if there's a caching issue or if the condition is being evaluated differently than expected.
To learn more, see the sources I considered: [[1] Teleco Demo Application](https://docs.permit.io/modeling/pink-mobile)
s
1. Workspace/Project/Env - sea.live/Default/Development 2. Calls - BulkCheck 3. PDP version - latest 4. PDP logs - 2025-11-13T003354.207589+0000 | opal_client.engine.logger | INFO | Received request. POST /v1/data/permit/bulk 2025-11-13T003354.231138+0000 | opal_client.engine.logger | INFO | Sent response. POST /v1/data/permit/bulk -> 200 2025-11-13T003354.232535+0000 | horizon.enforcer.api | INFO | is allowed = False | (michal@shell.com, distribute, market_order) | (michal@shell.com, reply, market_order) | (michal@shell.com, managepayload, market_order) | (michal@shell.com, readonly, market_order) | (michal@shell.com, distribute, market_order) | (michal@shell.com, reply, market_order) | (michal@shell.com, managepayload, market_order) | (michal@shell.com, readonly, market_order) | (michal@shell.com, distribute, market_order) | (michal@shell.com, reply, market_order) | (michal@shell.com, managepayload, market_order) | (michal@shell.com, readonly, market_order) | full_input={'checks': [{'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'distribute', 'resource': {'type': 'market_order', 'key': 'antoin01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'reply', 'resource': {'type': 'market_order', 'key': 'antoin01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'managepayload', 'resource': {'type': 'market_order', 'key': 'antoin01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'readonly', 'resource': {'type': 'market_order', 'key': 'antoin01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'distribute', 'resource': {'type': 'market_order', 'key': 'anton02', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'reply', 'resource': {'type': 'market_order', 'key': 'anton02', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'managepayload', 'resource': {'type': 'market_order', 'key': 'anton02', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'readonly', 'resource': {'type': 'market_order', 'key': 'anton02', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'distribute', 'resource': {'type': 'market_order', 'key': 'ivengen01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'reply', 'resource': {'type': 'market_order', 'key': 'ivengen01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'managepayload', 'resource': {'type': 'market_order', 'key': 'ivengen01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}, {'user': {'key': 'michal@shell.com', 'first_name': '', 'last_name': '', 'email': '', 'attributes': {}}, 'action': 'readonly', 'resource': {'type': 'market_order', 'key': 'ivengen01', 'tenant': 'default', 'attributes': {}, 'context': {'tenant': 'default'}}, 'context': {}, 'sdk': None}]} | debug={} 2025-11-13T003354.238246+0000 | uvicorn.protocols.http.httptools_impl | INFO | 172.17.0.1:51536 - "POST /allowed/bulk HTTP/1.1" 200 2025-11-13T003358.224587+0000 | opal_client.engine.logger | INFO | Logs uploaded successfully. {"plugin": "decision_logs", "time": "2025-11-13T003358Z"}
e
Thanks for providing all those details, @Shyamalan Chemmery. This will help us investigate the issue. Someone from the team will take a look and get back to you.
a
Hey @Shyamalan Chemmery, can you please add the audit log you get? trying to find this specific check
s
Thanks for reverting @Alon Boshi. The audit log for the response is below. This is after I changed the resource set to match with user.company - { "__data_use_debugger": true, "__input_use_debugger": true, "allow": true, "allowing_sources": [ "abac" ], "debug": { "abac": { "allow": true, "allowing_rules": [ { "resourceset": "resourceset_User_5fview_5fMO", "userset": "userset_Trade_5fuser" } ], "code": "allow", "reason": "user 'michal@shell.com' matched 'userset_Trade_5fuser' userset conditions, the given resource matched the 'resourceset_User_5fview_5fMO' resourceset conditions, users matching 'userset_Trade_5fuser' userset conditions has the 'readonly' permission on resources of type 'market_order' matching 'resourceset_User_5fview_5fMO' resourceset conditions" }, "custom": { "allow": true, "code": "custom_policy" }, "request": { "action": "readonly", "resource": { "attributes": { "DistributedCompanies": [ "Shell" ], "Quantity": 10000, "ViewOnlyUsers": [ "michal@shell.com" ], "type": "market_order" }, "type": "market_order" }, "tenant": "default", "user": { "attributes": { "company": "Shell", "email": "michal@shell.com", "key": "michal@shell.com", "roles": [ "Trade" ], "tenants": [ "default" ] }, "email": "", "first_name": "", "key": "michal@shell.com", "last_name": "", "synced": true } } }, "debugger_activated": true, "bulk_decision_id": "edb503b6-5527-4906-813d-240ca3eb74a8" }
a
Thanks for sharing that! I'll reproduce it and will circle back to you
👍 1
t
@Shyamalan Chemmery what is your custom policy?
Copy code
"custom": {
      "allow": true,
      "code": "custom_policy"
    }
s
Hi @Thomas the custom policy is a placeholder right now which effectively always returns true -package permit.custom import rego.v1 import data.permit.policies import data.permit.rbac default allow := false allow if { not input.resource.type == "market_order" } else if { input.resource.type == "market_order" # is_trade_user } # is_trade_user is true if.... is_trade_user if { "Trade" in rbac.allowing_roles }
a
Hey @Shyamalan Chemmery, We've found a resource shortage on some of our servers, causing an increase latency for loading policies. We've increased the memory and now it should be working much faster.
👍 1
s
Thanks for the update @Alon Boshi. I have rolled back the resource set (User View MO) to work with user.key. I have another resource set (Company distributed MO) which participates in a condition set to give "reply" & "readonly" action to a user set. It worked well to start with i.e., a qualifying user got both permissions. But even after I changed the condition set to remove "readonly" action, the condition set evaluates to true for the removed action. I have stopped, removed and re-run my local PDP container and restarted my client application too, with no luck. Looks like it is holding on to old decisions. I have given the audit log, for the spurious output, below. { "__data_use_debugger": true, "__input_use_debugger": true, "allow": true, "allowing_sources": [ "abac" ], "debug": { "abac": { "allow": true, "allowing_rules": [ { "resourceset": "resourceset_Company_5fdistributed_5fMO", "userset": "userset_Trade_5fuser" }, { "resourceset": "resourceset_User_5fview_5fMO", "userset": "userset_Trade_5fuser" } ], "code": "allow", "reason": "user 'michal@shell.com' matched 'userset_Trade_5fuser' userset conditions, the given resource matched the 'resourceset_Company_5fdistributed_5fMO' resourceset conditions, users matching 'userset_Trade_5fuser' userset conditions has the 'readonly' permission on resources of type 'market_order' matching 'resourceset_Company_5fdistributed_5fMO' resourceset conditions" }, "custom": { "allow": true, "code": "custom_policy" }, "request": { "action": "readonly", "resource": { "attributes": { "DistributedCompanies": [ "Shell" ], "Quantity": 10000, "ViewOnlyUsers": [ "michal@shell.com" ], "type": "market_order" }, "type": "market_order" }, "tenant": "default", "user": { "attributes": { "company": "Shell", "email": "michal@shell.com", "key": "michal@shell.com", "roles": [ "Trade" ], "tenants": [ "default" ] }, "email": "", "first_name": "", "key": "michal@shell.com", "last_name": "", "synced": true } } }, "debugger_activated": true, "bulk_decision_id": "89021476-f4e4-467b-bd75-67b6584861d3" }
@Alon Boshi looks like I found the issue. The PDP was evaluating true for the second resource set (User view MO) but stated the wrong resource set (Company distributed MO) in the "reason". I just disabled the condition set associated with "Company distributed MO" and now I can see the correct result, but the reason in audit log still states the wrong resource set. All this time the wrong resource set in the audit log reason was misleading us { "__data_use_debugger": true, "__input_use_debugger": true, "allow": true, "allowing_sources": [ "abac" ], "debug": { "abac": { "allow": true, "allowing_rules": [ { "resourceset": "resourceset_Company_5fdistributed_5fMO", "userset": "userset_Trade_5fuser" }, { "resourceset": "resourceset_User_5fview_5fMO", "userset": "userset_Trade_5fuser" } ], "code": "allow", "reason": "user 'michal@shell.com' matched 'userset_Trade_5fuser' userset conditions, the given resource matched the 'resourceset_Company_5fdistributed_5fMO' resourceset conditions, users matching 'userset_Trade_5fuser' userset conditions has the 'readonly' permission on resources of type 'market_order' matching 'resourceset_Company_5fdistributed_5fMO' resourceset conditions" }, "custom": { "allow": true, "code": "custom_policy" }, "request": { "action": "readonly", "resource": { "attributes": { "DistributedCompanies": [ "Shell" ], "Quantity": 10000, "ViewOnlyUsers": [ "michal@shell.com" ], "type": "market_order" }, "type": "market_order" }, "tenant": "default", "user": { "attributes": { "company": "Shell", "email": "michal@shell.com", "key": "michal@shell.com", "roles": [ "Trade" ], "tenants": [ "default" ] }, "email": "", "first_name": "", "key": "michal@shell.com", "last_name": "", "synced": true } } }, "debugger_activated": true, "bulk_decision_id": "59ff9a73-e46d-456c-ac4b-1d8aa0dda9af" }