Preflight checklist
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
Preflight checklist
Ory Network Project
No response
Describe the bug
PHP ory client library, when calling:
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:
And keto log:
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:
It works, but when doing without it like the PHP -library:
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:
Lines: 198-200:
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