ory/keto

Compare `this` with `ctx.subject`

fracek opened this issue · 5 comments

Preflight checklist

Describe your problem

I'm using Keto to implement permission for my SaaS-like product. Users can interact with it through a cli program (using a personal access token) or directly from the website (with session cookies). PATs can be "admin" tokens or "view" tokens, only "admin" tokens can make changes to the account. I implemented the following partial OPL policy:

class AccessToken implements Namespace {
}

class Account implements Namespace {
  related: {
    token: AccessToken[]
    admin_token: AccessToken[]
  }

  permits = {
    edit: (ctx: Context): boolean =>
      // this == ctx ||
      this.related.admin_token.includes(ctx.subject),

    view: (ctx: Context): boolean =>
        this.permits.edit(ctx) ||
        this.related.token.includes(ctx.subject),
  }
}

What's missing is a way to add the tuple Account:alice#edit@Account:alice.

Describe your ideal solution

My ideal solution is to add a permission check like this == ctx.subject.

Workarounds or alternatives

Add a editor relation from Account to Account and check that this.related.editor.includes(ctx.subject).

Version

v0.10.0-alpha.0

Additional Context

No response

From the way we write this.related.token.includes(ctx.subject) I think we should make the syntax either this == ctx.subject or this.equals(ctx.subject).
The workaround is valid but obviously cumbersome and not really necessary.

hperl commented

If we implement this, then the this == ctx.subject call should not hit the database. Then, it would be beneficial to have a special syntax for this.

On the syntax itself, I'm not sure if this == ctx.subject or this.equals(ctx.subject) are already clear enough to convey what is happening.

From an implementation point of view, this would require:

  • adding support for this expression in the OPL parser
  • adding a new userset rewrites type (maybe SubjectEqualsObject), and attach it to the relation if we parsed the expression
  • implement the SubjectEqualsObject rewrite in the check engine (simple, just compare object and subject for a given relation tuple)

Of course, add tests to make sure your change was effective, and run the fuzzers if you touch parser code.

Hello contributors!

I am marking this issue as stale as it has not received any engagement from the community or maintainers for a year. That does not imply that the issue has no merit! If you feel strongly about this issue

  • open a PR referencing and resolving the issue;
  • leave a comment on it and discuss ideas on how you could contribute towards resolving it;
  • leave a comment and describe in detail why this issue is critical for your use case;
  • open a new issue with updated details and a plan for resolving the issue.

Throughout its lifetime, Ory has received over 10.000 issues and PRs. To sustain that growth, we need to prioritize and focus on issues that are important to the community. A good indication of importance, and thus priority, is activity on a topic.

Unfortunately, burnout has become a topic of concern amongst open-source projects.

It can lead to severe personal and health issues as well as opening catastrophic attack vectors.

The motivation for this automation is to help prioritize issues in the backlog and not ignore, reject, or belittle anyone.

If this issue was marked as stale erroneously you can exempt it by adding the backlog label, assigning someone, or setting a milestone for it.

Thank you for your understanding and to anyone who participated in the conversation! And as written above, please do participate in the conversation if this topic is important to you!

Thank you 🙏✌️

Thanks stale bot! I'm also subscribing to this issue.

Agreeing with the part where ideally this avoids hitting the database.

If we implement this, then the this == ctx.subject call should not hit the database. Then, it would be beneficial to have a special syntax for this.

My current workaround for this, is that our client library wrapping Keto calls is responsible for doing this comparison.
While that works, it would be even better if we can opt-in to this behavior using OPL. Keeps authorization logic in one place.

This would massively simplify our namespace definitions and make working with Keto a lot nicer than it already is. :) If you need a hand with testing or reviewing this, I'd be happy to help and give feedback if needed. I note there's some discussion about this on Slack in January (just within the 90-day cut-off!) and February, but I can't see any further follow-ups since then, hence chiming in here. :)