keto icon indicating copy to clipboard operation
keto copied to clipboard

Dataloss Bug

Open nburns opened this issue 2 years ago • 0 comments

Preflight checklist

Describe the bug

I'm creating a tuple with one object ('hire') and deleting a tuple with a different object ('retain') (BUT the other fields are the same) and the first tuple is being deleted, which is not what I'd expect.

Description of the issue with relation tuple syntax:

create products:hire#read@user-621166 -> ok
check products:hire#read@user-621166 -> allowed = true
delete products:retain#read@user-621166 -> ok (note we're deleting a different tuple the object is different)
check products:hire#read@user-621166 -> allowed = false (this should still be true)

Reproducing the bug

Run the following script:

#!/usr/bin/env bash
set -x
curl -v -X PUT http://localhost:4469/admin/relation-tuples --data '{"namespace": "products", "object": "hire", "relation": "read", "subject_id": "user-621166"}'
curl -v 'http://localhost:4468/relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166'
curl -v -X DELETE http://localhost:4469/admin/relation-tuples --data '{"namespace": "products", "object": "retain", "relation": "read", "subject_id": "user-621166"}'
curl -v 'http://localhost:4468/relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166'

output:

+ curl -v -X PUT http://localhost:4469/admin/relation-tuples --data '{"namespace": "products", "object": "hire", "relation": "read", "subject_id": "user-621166"}'
*   Trying 127.0.0.1:4469...
* Connected to localhost (127.0.0.1) port 4469 (#0)
> PUT /admin/relation-tuples HTTP/1.1
> Host: localhost:4469
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 92
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< Content-Type: application/json; charset=utf-8
< Location: /relation-tuples?namespace=products&object=hire&relation=read&subject_id=user-621166
< Date: Thu, 20 Oct 2022 16:27:08 GMT
< Content-Length: 86
<
{"namespace":"products","object":"hire","relation":"read","subject_id":"user-621166"}
* Connection #0 to host localhost left intact
+ curl -v 'http://localhost:4468/relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166'
*   Trying 127.0.0.1:4468...
* Connected to localhost (127.0.0.1) port 4468 (#0)
> GET /relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166 HTTP/1.1
> Host: localhost:4468
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Date: Thu, 20 Oct 2022 16:27:08 GMT
< Content-Length: 17
<
{"allowed":true}
* Connection #0 to host localhost left intact
+ curl -v -X DELETE http://localhost:4469/admin/relation-tuples --data '{"namespace": "products", "object": "retain", "relation": "read", "subject_id": "user-621166"}'
*   Trying 127.0.0.1:4469...
* Connected to localhost (127.0.0.1) port 4469 (#0)
> DELETE /admin/relation-tuples HTTP/1.1
> Host: localhost:4469
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 94
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 204 No Content
< Date: Thu, 20 Oct 2022 16:27:08 GMT
<
* Connection #0 to host localhost left intact
+ curl -v 'http://localhost:4468/relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166'
*   Trying 127.0.0.1:4468...
* Connected to localhost (127.0.0.1) port 4468 (#0)
> GET /relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166 HTTP/1.1
> Host: localhost:4468
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Date: Thu, 20 Oct 2022 16:27:08 GMT
< Content-Length: 18
<
{"allowed":false}
* Connection #0 to host localhost left intact
sync-access-to-keto nick@worky ~/c/workstep> ./keto-bug.sh &| pbcopy
sync-access-to-keto nick@worky ~/c/workstep> ./keto-bug.sh
+ curl -v -X PUT http://localhost:4469/admin/relation-tuples --data '{"namespace": "products", "object": "hire", "relation": "read", "subject_id": "user-621166"}'
*   Trying 127.0.0.1:4469...
* Connected to localhost (127.0.0.1) port 4469 (#0)
> PUT /admin/relation-tuples HTTP/1.1
> Host: localhost:4469
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 92
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 201 Created
< Content-Type: application/json; charset=utf-8
< Location: /relation-tuples?namespace=products&object=hire&relation=read&subject_id=user-621166
< Date: Thu, 20 Oct 2022 16:28:15 GMT
< Content-Length: 86
<
{"namespace":"products","object":"hire","relation":"read","subject_id":"user-621166"}
* Connection #0 to host localhost left intact
+ curl -v 'http://localhost:4468/relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166'
*   Trying 127.0.0.1:4468...
* Connected to localhost (127.0.0.1) port 4468 (#0)
> GET /relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166 HTTP/1.1
> Host: localhost:4468
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Date: Thu, 20 Oct 2022 16:28:15 GMT
< Content-Length: 17
<
{"allowed":true}
* Connection #0 to host localhost left intact
+ curl -v -X DELETE http://localhost:4469/admin/relation-tuples --data '{"namespace": "products", "object": "retain", "relation": "read", "subject_id": "user-621166"}'
*   Trying 127.0.0.1:4469...
* Connected to localhost (127.0.0.1) port 4469 (#0)
> DELETE /admin/relation-tuples HTTP/1.1
> Host: localhost:4469
> User-Agent: curl/7.79.1
> Accept: */*
> Content-Length: 94
> Content-Type: application/x-www-form-urlencoded
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 204 No Content
< Date: Thu, 20 Oct 2022 16:28:15 GMT
<
* Connection #0 to host localhost left intact
+ curl -v 'http://localhost:4468/relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166'
*   Trying 127.0.0.1:4468...
* Connected to localhost (127.0.0.1) port 4468 (#0)
> GET /relation-tuples/check/openapi?namespace=products&object=hire&relation=read&subject_id=user-621166 HTTP/1.1
> Host: localhost:4468
> User-Agent: curl/7.79.1
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=utf-8
< Date: Thu, 20 Oct 2022 16:28:15 GMT
< Content-Length: 18
<
{"allowed":false}
* Connection #0 to host localhost left intact

Notice how the last result is {"allowed":false} when it should be {"allowed":true} since the tuple being deleted has a different object (retain not hire)

Relevant log output

time=2022-10-20T09:27:08-07:00 level=info msg=started handling request http_request=map[headers:map[accept:*/* content-length:92 content-type:application/x-www-form-urlencoded user-agent:curl/7.79.1] host:localhost:4469 method:PUT path:/admin/relation-tuples query:<nil> remote:127.0.0.1:56209 scheme:http]
time=2022-10-20T09:27:08-07:00 level=debug msg=creating relation tuple audience=application namespace=products object=hire relation=read service_name=Ory Keto service_version=v0.10.0-alpha.0 subject_id=user-621166
time=2022-10-20T09:27:08-07:00 level=info msg=completed handling request http_request=map[headers:map[accept:*/* content-length:92 content-type:application/x-www-form-urlencoded user-agent:curl/7.79.1] host:localhost:4469 method:PUT path:/admin/relation-tuples query:<nil> remote:127.0.0.1:56209 scheme:http] http_response=map[headers:map[content-type:application/json; charset=utf-8 location:/relation-tuples?namespace=products&object=hire&relation=read&subject_id=user-621166] size:86 status:201 text_status:Created took:6.486625ms]
time=2022-10-20T09:27:08-07:00 level=info msg=started handling request http_request=map[headers:map[accept:*/* user-agent:curl/7.79.1] host:localhost:4468 method:GET path:/relation-tuples/check/openapi query:namespace=products&object=hire&relation=read&subject_id=user-621166 remote:127.0.0.1:56210 scheme:http]
time=2022-10-20T09:27:08-07:00 level=info msg=completed handling request http_request=map[headers:map[accept:*/* user-agent:curl/7.79.1] host:localhost:4468 method:GET path:/relation-tuples/check/openapi query:namespace=products&object=hire&relation=read&subject_id=user-621166 remote:127.0.0.1:56210 scheme:http] http_response=map[headers:map[content-type:application/json; charset=utf-8] size:17 status:200 text_status:OK took:3.053708ms]
time=2022-10-20T09:27:08-07:00 level=info msg=started handling request http_request=map[headers:map[accept:*/* content-length:94 content-type:application/x-www-form-urlencoded user-agent:curl/7.79.1] host:localhost:4469 method:DELETE path:/admin/relation-tuples query:<nil> remote:127.0.0.1:56211 scheme:http]
time=2022-10-20T09:27:08-07:00 level=debug msg=deleting relation tuples audience=application service_name=Ory Keto service_version=v0.10.0-alpha.0
time=2022-10-20T09:27:08-07:00 level=info msg=completed handling request http_request=map[headers:map[accept:*/* content-length:94 content-type:application/x-www-form-urlencoded user-agent:curl/7.79.1] host:localhost:4469 method:DELETE path:/admin/relation-tuples query:<nil> remote:127.0.0.1:56211 scheme:http] http_response=map[headers:map[] size:0 status:204 text_status:No Content took:3.932292ms]
time=2022-10-20T09:27:08-07:00 level=info msg=started handling request http_request=map[headers:map[accept:*/* user-agent:curl/7.79.1] host:localhost:4468 method:GET path:/relation-tuples/check/openapi query:namespace=products&object=hire&relation=read&subject_id=user-621166 remote:127.0.0.1:56212 scheme:http]
time=2022-10-20T09:27:08-07:00 level=info msg=completed handling request http_request=map[headers:map[accept:*/* user-agent:curl/7.79.1] host:localhost:4468 method:GET path:/relation-tuples/check/openapi query:namespace=products&object=hire&relation=read&subject_id=user-621166 remote:127.0.0.1:56212 scheme:http] http_response=map[headers:map[content-type:application/json; charset=utf-8] size:18 status:200 text_status:OK took:3.271ms]

Relevant configuration

dsn: postgresql://keto-test@localhost/keto_test

log:
  level: debug
  leak_sensitive_values: true

serve:
  read:
    host: 0.0.0.0
    port: 4468

  write:
    host: 0.0.0.0
    port: 4469

namespaces:
  - id: 0
    name: products

  - id: 10
    name: facilities

  - id: 20
    name: positions

Version

v0.10.0-alpha.0, 52259a30d0be0257f1bb7ef591ae769808450230

On which operating system are you observing this issue?

macOS

In which environment are you deploying?

No response

Additional Context

originally reported here: https://ory-community.slack.com/archives/C012RBZFMDG/p1666222984368799

nburns avatar Oct 20 '22 16:10 nburns