Hi guys, is there anybody who has successfully bui...
# talk-keto
m
Hi guys, is there anybody who has successfully built something like an AWS IAM inspired permission management model with the Keto OPL? Currently trying to implement that and finding it hard to grasp how it could be done, there are some things that might not be possible like precedence of effects (explicit
deny
denies all other
allow
effects and things like that). Also it seems like the subject-set rewrite relations are not “visualized” in any of the keto expand commands which makes it difficult to follow the logic sometimes.
something I just came across, shouldn’t it be possible in the managed ory web app to create relation tuples with a subject that has an empty relation? I can do that with the cli, see the first entry, the app complains.
uhhh, and why can I create the same relation-tuple multiple times?
Copy code
❯ keto relation-tuple get                                                                                             
NAMESPACE       OBJECT  RELATION NAME   SUBJECT
Resource        r1      creator         Policy:r1-dev
Resource        r1      creator         Policy:r1-dev
Resource        r1      creator         Policy:r1-dev
Policy          r1-dev  bind            Role:dev
Policy          r1-dev  bind            Role:dev
I feel like this should give me a different error message as well:
Copy code
❯ keto check Policy:r1-dev creator Resource r1
Could not make request: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
Error: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
yeah, I tried with the official userset-rewrite example again and it seems like the service is down:
Copy code
❯ keto check User:Patrik view File private
Could not make request: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
Error: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
I have everything set up correctly tho:
Copy code
❯ keto status                             
SERVING

kubricks-artifact/keto-scratch on  ory-migrate [!] via  v16.17.0 on ☁️  (eu-central-1) on ☁️   
❯ keto relation-tuple get                                                                
NAMESPACE       OBJECT                  RELATION NAME   SUBJECT
Role            dev                     bind            User:u1
Folder          keto/src/               parents         Folder:keto/
File            keto/README.md          parents         Folder:keto/
File            private                 owners          User:Henning
File            keto/src/main.go        parents         Folder:keto/src/
Folder          keto/                   viewers         Group:developer#members
Group           developer               members         User:Henning
Group           developer               members         patrik
Group           developer               members         User:Patrik
Policy          r1-dev                  bind            Role:dev
Resource        r1                      creator         Policy:r1-dev

NEXT PAGE TOKEN
IS LAST PAGE    true
Is there a reason for the limitation that a transitive check (i.e. a
traverse
call) is not possible in the body of the lambda inside a
traverse
call. Docs:
Copy code
TransitiveCheck = "this" "." "related" "." RelationName "." "transitive" "(" Var "=>" ( PermissionCall | IncludesCheck ) ")" .
PermissionCall  = Var "." "permits" "." PermissionName "(" "ctx" ")" .
Example: See the permits section of the
S3ResourceType
, the
can_create
permission has two nested
traverse
calls.
Copy code
class Role implements Namespace {
  related: {
    principal: Project[]
  }
  permits = {
    can_assume: (ctx: Context) => this.related.principal.traverse((p) => p.related.access.includes(ctx.subject))
  }
}

class Policy implements Namespace {
  related: {
    attach: Role[]
  }
}

class S3ResourceType implements Namespace {
  related: {
    create: Policy[]
    edit: Policy[]
    read: Policy[]
  }

  permits = {
    can_create: (ctx: Context) => this.related.create.traverse((p) => p.related.attach.traverse((r) => r.permits.can_assume(ctx)))
  }
}
Solved it by putting the nested traverse call into a permission of the Policy… That should always be possible anyhow.
s
hey thanks for all the feedback, actually a lot of the things are know issues: • https://github.com/ory/keto/issues/1060https://github.com/ory/keto/issues/292 • the empty subject set relations are already fixed but not yet released to prod • did the errors persist or was it only temporary? I will try to trace them in our monitoring
I created an issue for the nested traverses: https://github.com/ory/keto/issues/1131
m
Thanks for getting back! Hope you had a nice weekend. Yeah, I saw those existing issues after I posted here, sorry about that. Unfortunately the errors did indeed persist, and I’m facing new ones. It’s a bit puzzling, tbh, I feel like there shouldn’t be any. I have this namespace configuration now which is accepted by the editor in the frontend. I’m still playing around to come up with something like AWS IAM to get a feel for keto.
Copy code
import { Namespace, SubjectSet, Context } from "@ory/keto-namespace-types"

class User implements Namespace { }

class Group implements Namespace {
  related: {
    member: (User | Group)[]
  }
}

class Project implements Namespace {
  related: {
    access: (User | Group)[]
  }
}

class Role implements Namespace {
  related: {
    principal: Project[]
  }
  permits = {
    can_assume: (ctx: Context) => this.related.principal.traverse((p) => p.related.access.includes(ctx.subject))
  }
}

class Policy implements Namespace {
  related: {
    allow: Role[]
  }
  permits = {
    allow: (ctx: Context) => this.related.allow.traverse((r) => r.permits.can_assume(ctx))
  }
}

class ResourcePolicy implements Namespace {
  related: {
    trust: (User | Group)[]
  }
}

class S3ResourceType implements Namespace {
  related: {
    create: Policy[]
    write: Policy[]
    read: Policy[]
  }

  permits = {
    can_create: (ctx: Context) => this.related.create.traverse((p) => p.permits.allow(ctx)),
    can_write: (ctx: Context) => this.related.write.traverse((p) => p.permits.allow(ctx)),
    can_read: (ctx: Context) =>
      this.related.read.traverse((p) => p.permits.allow(ctx)) ||
      this.related.write.traverse((p) => p.permits.allow(ctx))
  }
}

class S3Resource implements Namespace {
  related: {
    instance: S3ResourceType[]
    write: ResourcePolicy[]
    read: ResourcePolicy[]
  }
  permits = {
    can_write: (ctx: Context) =>
      this.related.instance.traverse((i) => i.permits.can_write(ctx)) ||
      this.related.write.traverse((rp) => rp.related.trust.includes(ctx.subject)),
    can_read: (ctx: Context) =>
      this.related.instance.traverse((i) => i.permits.can_read(ctx)) || 
      this.related.read.traverse((rp) => rp.related.trust.includes(ctx.subject)) ||
      this.related.write.traverse((rp) => rp.related.trust.includes(ctx.subject))
  }
}
I deleted all relation tuples and now I’m trying to add new ones, but I run into segmentation faults with no interpretable error message: This is my rbac_`tuples.json` with relation tuples for the above configuration:
Copy code
[
  {
    "namespace": "Group",
    "object": "ops",
    "relation": "member",
    "subject": {
      "namespace": "User",
      "object": "hans"
    }
  }
]
And I get this error message:
Copy code
❯ keto relation-tuple create rbac_tuples.json
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x4be0b79]

goroutine 1 [running]:
<http://github.com/ory/keto/ketoapi.(*RelationTuple).ToProto(...)|github.com/ory/keto/ketoapi.(*RelationTuple).ToProto(...)>
        /project/ketoapi/enc_proto.go:55
<http://github.com/ory/keto/cmd/relationtuple.transactRelationTuples.func1|github.com/ory/keto/cmd/relationtuple.transactRelationTuples.func1>(0xc000321b80, {0xc0002cc2a0, 0x1, 0x1?})
        /project/cmd/relationtuple/delete.go:49 +0x5f9
<http://github.com/spf13/cobra.(*Command).execute(0xc000321b80|github.com/spf13/cobra.(*Command).execute(0xc000321b80>, {0xc0002cc280, 0x1, 0x1})
        /go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:872 +0x694
<http://github.com/spf13/cobra.(*Command).ExecuteC(0xc000321400)|github.com/spf13/cobra.(*Command).ExecuteC(0xc000321400)>
        /go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:990 +0x3bd
<http://github.com/spf13/cobra.(*Command).Execute(...)|github.com/spf13/cobra.(*Command).Execute(...)>
        /go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:918
<http://github.com/spf13/cobra.(*Command).ExecuteContext(...)|github.com/spf13/cobra.(*Command).ExecuteContext(...)>
        /go/pkg/mod/github.com/spf13/cobra@v1.5.0/command.go:911
<http://github.com/ory/keto/cmd.Execute()|github.com/ory/keto/cmd.Execute()>
        /project/cmd/root.go:74 +0x96
main.main()
        /project/main.go:25 +0x69
As for the
keto check
command with the userser rewrite example namespace configuration I still get that error from above:
Copy code
❯ keto check User:Patrik view File private
Could not make request: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
Error: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
s
OK, I will take a look into those now as they seem pretty critical 😅
m
lovely, thank you
this might be helpful
Copy code
❯ keto version                               
Version:                        v0.10.0-alpha.0
Build Commit:   52259a30d0be0257f1bb7ef591ae769808450230
Build Timestamp:        2022-09-27T13:05:05Z
and this:
Copy code
❯ system_profiler SPSoftwareDataType
Software:

    System Software Overview:

      System Version: macOS 12.6 (21G115)
      Kernel Version: Darwin 21.6.0
s
I'd recommend the Ory CLI btw: https://github.com/ory/cli it also has the keto subcommands
I think both issues are actually related to the Keto CLI you might be able to make it work somehow, but I think using the Ory CLI will work just out of the box
or rather the
Copy code
❯ keto check User:Patrik view File private
Could not make request: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
Error: rpc error: code = Unimplemented desc = unexpected HTTP status code received from server: 404 (Not Found); transport: received unexpected content-type "application/json"
the other one is caused by the wrong key in the json, it should be
subject_set
instead of
subject
m
thank you for investigating! Sorry about that last one…
s
Haha no worries, the error is really misleading there
m
Hey, I found something else, added a comment here: https://github.com/ory/keto/pull/657
s
There were some breaking changes, mostly with naming you should use v1alpha2
m
thanks for the hint 🙂 I’m now building a grpc client based on the grpc client the keto cli uses, then I want to test the behaviour of my OPL namespace config. So far so good, but I came across this disclaimer here and I am a bit puzzled as to what experience you made here to warrant it: https://www.ory.sh/docs/keto/guides/access-control-list-design-best-practices I can only imagine it’s a performance issue, but traversing the DAG, starting from a object to be checked, should scale linearly with its depth no?
s
we are still working on a good benchmark and recommend to bench keto with your model if you encounter performance issues, please reach out so we can come up with improvements
d
hi Patrik, I just bumped into the nested traverse issue as well, I think it’s a pretty essential feature to make multiple hops of traverse. Is there any update/ETA on this issue? https://github.com/ory/keto/issues/1131