Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore Conditional Relationship Tuple evaluation errors if ListObjects result is already determined #1511

Open
6 tasks done
jon-whit opened this issue Apr 3, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@jon-whit
Copy link
Member

jon-whit commented Apr 3, 2024

Checklist

  • I have looked into the README and have not found a suitable solution or answer.
  • I have looked into the documentation and have not found a suitable solution or answer.
  • I have searched the issues and have not found a suitable solution or answer.
  • I have upgraded to the latest version of OpenFGA and the issue still persists.
  • I have searched the OpenFGA Community and have not found a suitable solution or answer.
  • I agree to the terms within the OpenFGA Code of Conduct.

Description

tl;dr - We should avoid returning an error in ListObjects for Conditional Relationship Tuple evaluation errors if we've already determined a determinate result for that object.

Given an FGA model such as:

type user

type org
  relations
    define viewer: [user]

type folder
  relations
    define viewer: [user]

type document
  relations
    define parent: [folder with condx, org with condy]
    define viewer: viewer from parent

condition condx(x: int) {
  x < 10
}

condition condy(y: int) {
  y > 25
}
  • document:1#parent@folder:x, condition: condx
  • document:1#parent@org:acme, condition: condy
  • folder:x#viewer@user:jon
  • org:acme#viewer@user:jon

Check(document:1#viewer@user:jon, context: {"x": 5}) will always return {allowed: true} through the branch of evaluation that involves folder:x#viewer@user:jon.

ListObjects(document#viewer, user:jon, context: {"x": 5}) will return an error (error code 2000). This is because we'll see the document:1#parent@org:acme relationship, but we won't be able to evaluate it because context parameter y is missing.

The OpenFGA server shouldn't return an error for the ListObjects case, because it is able to find document:1 through the folder:x#viewer branch and so the other parent relationship with org:acme that is unresolvable should be irrelevant.

Expectation

I expect the following:

Check(document:1#viewer@user:jon, context: {"x": 5}) --> {allowed: true} - through folder:x#viewer
Check(document:1#viewer@user:jon, context: {"y": 26}) --> {allowed: true} - through org:acme#viewer

ListObjects(document#viewer, user:jon, context: {"x": 5}) --> ["document:1"] - through folder:x#viewer
ListObjects(document#viewer, user:jon, context: {"y": 26}) --> ["document:1"] - through org:acme#viewer

Reproduction

  1. Write the authorization model
curl --location 'http://localhost:8080/stores/01HSNVPXRVE6MGW080RPZ4C880/authorization-models' \
--header 'Content-Type: application/json' \
--data '{
  "schema_version": "1.1",
  "type_definitions": [
    {
      "type": "user",
      "relations": {},
      "metadata": null
    },
    {
      "type": "org",
      "relations": {
        "viewer": {
          "this": {}
        }
      },
      "metadata": {
        "relations": {
          "viewer": {
            "directly_related_user_types": [
              {
                "type": "user"
              }
            ]
          }
        }
      }
    },
    {
      "type": "folder",
      "relations": {
        "viewer": {
          "this": {}
        }
      },
      "metadata": {
        "relations": {
          "viewer": {
            "directly_related_user_types": [
              {
                "type": "user"
              }
            ]
          }
        }
      }
    },
    {
      "type": "document",
      "relations": {
        "parent": {
          "this": {}
        },
        "viewer": {
          "tupleToUserset": {
            "computedUserset": {
              "relation": "viewer"
            },
            "tupleset": {
              "relation": "parent"
            }
          }
        }
      },
      "metadata": {
        "relations": {
          "parent": {
            "directly_related_user_types": [
              {
                "type": "folder",
                "condition": "condx"
              },
              {
                "type": "org",
                "condition": "condy"
              }
            ]
          },
          "viewer": {
            "directly_related_user_types": []
          }
        }
      }
    }
  ],
  "conditions": {
    "condx": {
      "name": "condx",
      "expression": "x < 10",
      "parameters": {
        "x": {
          "type_name": "TYPE_NAME_INT"
        }
      }
    },
    "condy": {
      "name": "condy",
      "expression": "y > 25",
      "parameters": {
        "y": {
          "type_name": "TYPE_NAME_INT"
        }
      }
    }
  }
}'
  1. Write the tuples
curl --location 'http://localhost:8080/stores/01HSNVPXRVE6MGW080RPZ4C880/write' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6Img2d2J4LXVEckxLOVU5TTBPby1rNiJ9.eyJodHRwczovL2ZnYS5kZXYvY2xhaW1zL3N0b3JlX3RpZXIiOiJmcmVlIiwiaHR0cHM6Ly9mZ2EuZGV2L2NsYWltcy9jdXN0b21lcl9pZCI6IjAxR1YxVERaSkFGVjNCRzEzWU1aQ1JKUUJNIiwiaHR0cHM6Ly9mZ2EuZGV2L2NsYWltcy9zdG9yZV9pZCI6IjAxR1YxVEUxMDhOOEVaSjBTUDFOWDBDNDJEIiwiaXNzIjoiaHR0cHM6Ly9zYW5kY2FzdGxlLWRldi51cy5hdXRoMC5jb20vIiwic3ViIjoicndYUGxocHBzOE1rZjZmNmJQVkRnWEJTSVVNU0dyVlZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vYXBpLnN0YWdpbmcuZmdhLmRldi8iLCJpYXQiOjE2NzgzMjAzMjQsImV4cCI6MTY3ODQwNjcyNCwiYXpwIjoicndYUGxocHBzOE1rZjZmNmJQVkRnWEJTSVVNU0dyVlYiLCJzY29wZSI6InJlYWQ6dHVwbGVzIHdyaXRlOnR1cGxlcyBjaGVjazp0dXBsZXMgZXhwYW5kOnR1cGxlcyByZWFkOmF1dGhvcml6YXRpb25fbW9kZWxzIHdyaXRlOmF1dGhvcml6YXRpb25fbW9kZWxzIHJlYWQ6YXNzZXJ0aW9ucyB3cml0ZTphc3NlcnRpb25zIHJlYWQ6Y2hhbmdlcyBsaXN0Om9iamVjdHMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.q2w4oNPrlZrv8ms29U3vPK0ZCZOOcbMOuSBeoC5MiD_bHN_RG2Xf4wuw21aCbF0ZOWqyfRTzEAhBxtfHjiIX5GEvIUEHdFPy-EE03LssQx11q1l3mKvef_ud1JpTqRVKlhaxGeURAwb8Y4ru0ahs0S2xW6hTjvb19NEsrDOMJkAixwru-Qy-UkoD9GYPKW9uWQ7YSx1TidboETdTs9bXfBtL5JPIGd6dpHNGOFGftFUw-dx0c7ntXWiKJEAH7CYoI1rmxtgnx7brKdpLTpFf0L3HQoIgy8xc6JteZxxOK51BstzL25imYTak9iPDnOVMGCeFRCvRU0aWLNBp5AasAw' \
--data '{
    "writes": {
      "tuple_keys": [
          {
            "object": "document:1",
            "relation": "parent",
            "user": "folder:x",
            "condition": {
                "name": "condx"
            }
          },
          {
            "object": "document:1",
            "relation": "parent",
            "user": "org:acme",
            "condition": {
                "name": "condy"
            }
          },
          {
            "object": "folder:x",
            "relation": "viewer",
            "user": "user:jon"
          },
          {
            "object": "org:acme",
            "relation": "viewer",
            "user": "user:jon"
          }
      ]
    }
}'
  1. Call ListObjects
curl --location 'http://localhost:8080/stores/01HSNVPXRVE6MGW080RPZ4C880/list-objects' \
--header 'Content-Type: application/json' \
--data '{
    "type": "document",
    "relation": "viewer",
    "user": "user:jon",
    "context": {
        "x": 5
    }
}'

I expect step #3 above to return ["document:1"] not an error. Similarly,

Store data

No response

OpenFGA version

v1.5.1

How are you running OpenFGA?

As a binary

What datastore are you using?

In-Memory

OpenFGA Flags

./openfga run

Logs

No response

@jon-whit jon-whit added the bug Something isn't working label Apr 3, 2024
@miparnisari
Copy link
Member

Agree on the bug, however:

The OpenFGA server shouldn't return an error for the ListObjects case, because it is able to find document:1 through the folder:x#viewer branch and so the other parent relationship with org:acme that is unresolvable should be irrelevant.

We'll have to change our design quite a bit to accomodate for this, e.g. associate each evaluation error with a tuple, accumulate all errors until the very end (how do we bound this?), and compare those tuples with the actual results sent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants