-
-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Preflight checklist
- I could not find a solution in the existing issues, docs, nor discussions.
- I agree to follow this project's Code of Conduct.
- I have read and am following this repository's Contribution Guidelines.
- I have joined the Ory Community Slack.
- I am signed up to the Ory Security Patch Newsletter.
Ory Network Project
No response
Describe the bug
- Ory keto 0.14.0
- Ory client php-library ory/client v1.21.1
PHP ory client library, when calling:
$permResult = Ory::permission()->checkPermission(
'Plan',
$planId,
'includes_feature',
null,
'Feature',
$featureCheckId,
'', // this is the problem, empty string
);
Causes error because subject_set.relation needs to be empty but because it is empty, it is not included in the request causing this error:
[400] Client error: `GET http://keto:4466/relation-tuples/check/openapi?namespace=Plan&object=planId&relation=includes_feature&subject_set.namespace=Feature&subject_set.object=featId` resulted in a `400 Bad Request` response:{"error":{"code":400,"status":"Bad Request","message":"incomplete subject, provide \"subject_id\" or a complete \"subjec (truncated...)
And keto log:
keto-1 | time=2025-07-30T23:44:02Z level=info msg=completed handling request http_request=map[headers:map[accept:application/json content-type:application/json user-agent:OpenAPI-Generator/1.0.0/PHP] host:keto:4466 method:GET path:/relation-tuples/check/openapi query:namespace=Plan&object=planId&relation=includes_feature&subject_set.namespace=Feature&subject_set.object=featId remote:172.19.0.37:50472 scheme:http] http_response=map[headers:map[content-type:application/json] size:133 status:400 text_status:Bad Request took:86.667µs]
As you can see, the subject_set.relation is missing from the request even though it was defined in the code.
When trying to do the same request with curl with the empty string subject_set.releation:
# curl -s "http://localhost:4466/relation-tuples/check/openapi" \
> -G \
> --data-urlencode "namespace=Plan" \
> --data-urlencode "object=planId" \
> --data-urlencode "relation=includes_feature" \
> --data-urlencode "subject_set.namespace=Feature" \
> --data-urlencode "subject_set.object=featId" \
> --data-urlencode "subject_set.relation="
{"allowed":true}
It works, but when doing without it like the PHP -library:
# curl -s "http://localhost:4466/relation-tuples/check/openapi" \
> -G \
> --data-urlencode "namespace=Plan" \
> --data-urlencode "object=planId" \
> --data-urlencode "relation=includes_feature" \
> --data-urlencode "subject_set.namespace=Feature" \
> --data-urlencode "subject_set.object=featId"
{"error":{"code":400,"status":"Bad Request","message":"incomplete subject, provide \"subject_id\" or a complete \"subject_set.*\""}}
It does not work, just like the PHP ory/client library because the empty string relation is missing.
So, my conclusion:
PHP ory/client library is not working correctly with the check permissions call when using subject_set.realation value "" (emtpy string) the ObjectSerializer thinks it is not required and removes it because it's empty value.
Lines: 230-240:
# Check if we should omit this parameter from the query. This should only happen when:
# - Parameter is NOT required; AND
# - its value is set to a value that is equivalent to "empty", depending on its OpenAPI type. For
# example, 0 as "int" or "boolean" is NOT an empty value.
if (self::isEmptyValue($value, $openApiType)) {
if ($required) {
return ["{$paramName}" => ''];
} else {
return [];
}
}
Lines: 198-200:
# For string values, '' is considered empty.
case 'string':
return $value === '';
Reproducing the bug
$permResult = Ory::permission()->checkPermission(
'Plan',
$planId,
'includes_feature',
null,
'Feature',
$featureCheckId,
'', // this is the problem, empty string
);
Relevant log output
Relevant configuration
Version
v1.21.1
On which operating system are you observing this issue?
Linux
In which environment are you deploying?
Docker Compose
Additional Context
No response