ory / keto

Open Source (Go) implementation of "Zanzibar: Google's Consistent, Global Authorization System". Ships gRPC, REST APIs, newSQL, and an easy and granular permission language. Supports ACL, RBAC, and other access models.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=keto
Apache License 2.0
4.7k stars 342 forks source link

Does the object support the expression like '/cats/*' to indicate all items starts with '/cats/' #1484

Open ghujki opened 6 months ago

ghujki commented 6 months ago

Preflight checklist

Ory Network Project

No response

Describe the bug

The object doesn`t support expression of '*'

Reproducing the bug

I added this to the API when I following the cats example to allow anyone to view the items under the folder of /cats { "namespace": "videos", "object": "/cats/*", "relation": "view", "subject_id": "*" }

but it doesn`t work as expected

Relevant log output

{
    "allowed": false
}

Relevant configuration

No response

Version

keto_0.11.1-alpha.0-windows_64bit

On which operating system are you observing this issue?

None

In which environment are you deploying?

None

Additional Context

No response

cmmoran commented 5 months ago

I think you may be taking a narrow view of what object is. In your scenario, an object represents an entity within some arbitrary hierarchy. This isn't always the case. Some objects are just objects; no hierarchy at all.

I would submit that it's not keto's job to figure this out. This can be solved via constructs currently available within keto.

For example, if you add a parent relation to your videos namespace, you could add a permits that would allow view on an arbitrary object if that object has a parent that allows view on the given subject.

/* ... omitted for brevity ... */

// Note, I'm using "Videos" but the correct namespace name _should be_ "Video" (singular)
class Videos implements Namespace {
  related: {
    owner: Videos[]
  }

  permits = {
    can_view: (ctx: Context): boolean =>
      this.related.owner.traverse((o) => o.permits(ctx))
  }
}

NOTE: I did not test the above logic. The parser in my brain says it's AOK. I wasn't aiming for code completion. I wished to give an example of one theoretical way this isn't really an issue and can be implemented in one of a few different ways.