[BUG] / permissions / check doesnt validates subject id passed in the payload
Describe the bug While performing check on the permissions, if the entity is associated with multiple subjects having different values for attributes, check validates only against the latest subject attribute value regardless of subject id specified.
To Reproduce
Steps to reproduce the behavior:
Schema:
"entity policy {\n\nrelation upload_condition @upload_policy\n\naction upload_document = upload_condition.upload_allowed\n\n}\n\nentity upload_policy {\n\n attribute max_size integer\n attribute min_size integer\n\n permission upload_allowed = is_valid_size(max_size, min_size)\n\n}\n\nrule is_valid_size(max_size integer, min_size integer) {\n (context.data.size >= min_size) && (context.data.size <= max_size)\n}"
Relations: policy 1 upload_condition upload_policy 1 policy 1 upload_condition upload_policy 2
Attributes: upload_policy 1 max_size integer 450 upload_policy 1 min_size integer 50
upload_policy 2 max_size integer 500
upload_policy 2 min_size integer 50
Check Request:
- name: admin_access_test
checks:
- entity: policy:1 subject: upload_policy:1 context: data: size: 500 assertions: upload_document: true entity_filters: [] subject_filters: []
Result: success
Environment: performed on playground as well using REST Api's
Expected behavior It should have validated against attribute max_size of upload_policy:1 and denied the access.
Hey @pooka96 , this actually isn't a bug. It's not based on the most recently assigned reference either. The logic works such that if any of the assigned references match, that's enough for access to be granted.
To explain with a simple example:
entity user {}
entity organization {
relation admin @user
}
entity repository {
relation parent @organization
permission edit = parent.admin
}
In this example, for user:1 to be able to edit repository:1, it's enough that repository:1 has any parent organization where user:1 is an admin.
If you can explain your use case more clearly, I can help you design a hierarchical model that fits it better
Let me rephrase my question. Following is the defined schema: `entity document {
relation upload_condition @rule
action upload_document = upload_condition.upload_allowed
}
entity rule {
attribute max_size integer attribute min_size integer
permission upload_allowed = is_valid_size(max_size, min_size)
}
rule is_valid_size(max_size integer, min_size integer) { (context.data.size >= min_size) && (context.data.size <= max_size) }`
Let's say i have list of documents and each documents have some rules defined on it. Document 1 has rule 1 -> max_size:500mb and min_size: 10mb Document 1 has rule 2 -> max_size:1gb and min_size:100mb
for certain scenario, rule1 will be applicable to document 1 or rule2 will be applicable to document 1
Check permission request payload: { "metadata": { "schema_version": "", "snap_token": "", "depth": 20 }, "entity": { "type": "document", "id": "1" }, "permission": "allowed_upload", "subject": { "type": "rule", "id": "1" }, "context":{ "data": { "size":50mb, } } } here, this check permission returns response denied. On debugging, found out that i can pass any random subject id here in payload and response will be given.
basically, many:1 (subject:entity) relations are not possible in permify only 1:1 is possible?
Approved
Hi @pooka96, after reviewing your issue, I can confirm this is not a bug but the intended behavior in Permify. In our evaluation engine, if any relation of the given entity meets the requested permission, the check returns a success response. This “any-pass” logic is part of how Permify works by design.
I’ve updated your initial schema so it now fully supports your use case with the intended behavior:
entity document {}
entity upload_policy {
relation applies_to @document
attribute max_size integer
attribute min_size integer
permission upload_allowed = is_valid_size(max_size, min_size)
}
rule is_valid_size(max_size integer, min_size integer) {
(context.data.size >= min_size) && (context.data.size <= max_size)
}
This way the relationship will be applied as "AND" condition.
Here you can find my requests to reproduce your case with updated schema:
Write Schema
curl --location 'http://localhost:3476/v1/tenants/t1/schemas/write' \
--header 'Content-Type: application/json' \
--data-raw '{
"schema": "entity document {}\n\nentity upload_policy {\n relation applies_to @document\n\n attribute max_size integer\n attribute min_size integer\n\n permission upload_allowed = is_valid_size(max_size, min_size)\n}\n\nrule is_valid_size(max_size integer, min_size integer) {\n (context.data.size >= min_size) && (context.data.size <= max_size)\n}\n\n\n"
}'
Write Tuples and Attributes
curl --location 'http://localhost:3476/v1/tenants/t1/data/write' \
--header 'Content-Type: application/json' \
--data-raw '{
"metadata": {
"schema_version": ""
},
"tuples": [
{
"entity": {
"type": "upload_policy",
"id": "1"
},
"relation": "applies_to",
"subject": {
"type": "document",
"id": "1"
}
},
{
"entity": {
"type": "upload_policy",
"id": "2"
},
"relation": "applies_to",
"subject": {
"type": "document",
"id": "1"
}
}
],
"attributes": [
{
"entity": {
"type": "upload_policy",
"id": "1"
},
"attribute": "max_size",
"value": {
"@type": "type.googleapis.com/base.v1.IntegerValue",
"data": 400
}
},
{
"entity": {
"type": "upload_policy",
"id": "1"
},
"attribute": "min_size",
"value": {
"@type": "type.googleapis.com/base.v1.IntegerValue",
"data": 50
}
},
{
"entity": {
"type": "upload_policy",
"id": "2"
},
"attribute": "max_size",
"value": {
"@type": "type.googleapis.com/base.v1.IntegerValue",
"data": 100
}
},
{
"entity": {
"type": "upload_policy",
"id": "2"
},
"attribute": "min_size",
"value": {
"@type": "type.googleapis.com/base.v1.IntegerValue",
"data": 50
}
}
]
}'
Perform Permission Check
curl --location 'http://localhost:3476/v1/tenants/t1/permissions/check' \
--header 'Content-Type: application/json' \
--data '{
"metadata": {
"snap_token": "",
"schema_version": "",
"depth": 20
},
"entity": {
"type": "upload_policy",
"id": "2"
},
"permission": "upload_allowed",
"subject": {
"type": "document",
"id": "1"
},
"context": {
"data": {
"size":300
}
}
}'
Approved