openfga / roadmap

OpenFGA Public Roadmap
2 stars 0 forks source link

Better ListObjects support for ABAC use cases #63

Open aaguiarz opened 4 months ago

aaguiarz commented 4 months ago

We want to improve ListObjects scenarios when it's called with missing context.

For example, consider the following model that enables access only to documents with a specific status:

model
  schema 1.1

type user

type document
  relations
    define can_access: [user with docs_in_draft_status]

condition docs_in_draft_status(status: string) {
  status == "draft"
}

If you want to list all the documents a user can view, you'll need to know the status of all of those documents. Given you don't know the documents the user has access too, you can't send the status of those as a parameter to ListObjects.

Our goal is to return a structure that you can use to filter documents on your side, similar to: (document.id = ‘1’ and document.status = ‘draft’) or (document.id = ‘2’ and.status = draft). This won’t scale to a large number of documents, but would be useful in some scenarios.

zachkirlew commented 4 months ago

Hey guys, we have the following case that would benefit from such behaviour.

We would like to be able to query the list of organisations an admin can view without having to include the org type in the context. Our schema might look like this:

model
  schema 1.1

type system
  relations
    define internal_account_manager: [admin]
    define external_account_manager: [admin]

type admin
  relations
    define system: [system]

type organization
  relations
    define system: [system]
    define can_view: [internal_account_manager from system with is_internal, external_account_manager from system with is_external]

condition is_internal_organization(organizationType: string) {
  organizationType == "internal"
}

condition is_external_organization(organizationType: string) {
  organizationType == "external"
}
aaguiarz commented 3 months ago

Hi @zachkirlew

In this case, wouldn't this work?

model: |
 model
  schema 1.1

  type system
    relations
      define internal_account_manager: [user]
      define external_account_manager: [user]

  type user

  type organization
    relations
      define system: [system]
      define can_view: internal_account_manager from system or external_account_manager from system

tuples:
  - user:  user:anne
    relation: internal_account_manager
    object: system:main

  - user:  user:peter
    relation: external_account_manager
    object: system:main

  - user: system:main
    relation: system
    object: organization:acme

tests:
  - check:
      - user: user:peter
        object: organization:acme
        assertions:
          can_view: true

      - user: user:anne
        object: organization:acme
        assertions:
          can_view: true
zachkirlew commented 3 months ago

@aaguiarz not quite. In your example there are two different users each with a different type of account manager role and they both can access internal or external.

In our model, an organisation has at most one type. It can be either internal or external, not both. We need to ensure that if organization:acme is internal, only user:anne can view as she has internal_account_manager and internal_account_manager gives access with internal organisations, or if another user had both internal_account_manager AND external_account_manager then they could view both internal and external.

We need a way of ensuring that the internal_account_manager role is only valid for internal organisations and external_account_manager role is only valid for external organisations. This way if we list all the organizations that user:anne can view we would hope to get back the IDs of internal organizations.