[keycloak-user] Using Keycloak for per field authorisation

Courtney Robinson courtney.robinson at hypi.io
Sun Aug 12 03:01:10 EDT 2018


 Checking the archives I see my response doesn't show up, I'm guessing
reply-all doesn't work since the mailing list user ends up being CC'd.
Sending again.

So far so good, I can see how to map some of these things directly to
>> Keycloak high level constructs. It falls apart for me with the API. We're
>> using Spring Boot but I struggle to see how I'd achieve this setup using
>> one of the adapters.
>>
>
> Did you have a chance to look our app-authz-spring* quickstarts ?
>

Yes, I didn't see where any of them did per field auth or mixed system
defined/default policies with user defined ones. Also bare in mind that
some of the terminology is new to me so even if it has been explained in
the examples or docs I may have misunderstood or not fully appreciated what
something implied.


>
>
>>
>> Take this scenario:
>> App 1 defines two types A{f1:Int, f2: String} and B{f3:Int, f4: String}
>> Org 1, User 1 can read,write A.f1 and B.f3, they can only read B.f4 and
>> cannot see or perform any other operation on A.f2 *normally* but in one
>> case they have had a specific instance of A shared with them and given
>> complete read/write/share/manage permission for that one instance and thus
>> A.f2 is available to them in this one instance.
>>
>
> I'm a little confused about what type A and B are. You also mentioned you
> may have an "instance of A".  Does that mean that types A and B represent
> generic resources which policies should be enforced on instances of A and B
> ? Are these instances user-managed resources ?
>

Types A and B are GraphQL objects. If you're not familiar then just think
of them as classes A and B with only class members/fields defined.
I'm not explaining this very well I think so another way to think about it
is like this.

By default I want to apply some global policies to classes A and B that
says for example, anyone in Organisation 1 can read/write classes A and B.
This is "system defined".
More concretely imagine classes User and Book. Two organisations Org1 and
Org2.
When we create a realm for each org, we want to tell Keycloak that some app
X has two types User and Book and any user in the current realm can
read/write fields of both User and Book within this realm.

We also want to tell Keycloak that an "admin" (I imagine a user with some
role or in a specific group) in this realm can add policies that override
the above behaviour.
Given one or more of these admins, they can then choose to create a policy
that says "Users from site A can read/write all fields of User and Book but
users from site B can only read some fields from User and all fields from
Book".

The other case I mentioned in my first email is where, a user in an
organisation has created e.g. a "Book" record. Under default policies only
they can see and manage this Book they created. They can then share this
book with site 2 so that users in site 2 can also read the book, they may
also share it with the whole organisation so anyone in the realm can read
it. The extension to this is when members of one site could normally only
see a subset of fields from Book but one one occasion a user shares a
single Book with one or more members giving then the permission to "manage"
this one Book. This lifts the limitation on this one instance of book
enabling the user it is shared with to access a field of Book they wouldn't
have been able to see before.


>
>
> Regarding how the adapter (policy enforcer in particular) work. It
> verifies permissions locally in case the client is sending a bearer token
> with permissions, otherwise the adapter will query the server for
> permissions associated with resource the client is trying to access
> (mapping is based on URIs).
>

I had a feeling. One of the reasons I'm so unclear about how to achieve
what we want is that it feels like a mixture of the auth policies Keycloak
supports is needed.
I've been thinking that for each app, default Keycloak policies are created
that e.g. allowed read only within an organisation.
Use Keycloak groups to represent "sites" e.g. offices in an organisation
and applied default policies to the groups.
Then, the key thing I thought was that I'd have to register each type and
it's fields in Keycloak as resources and then have a fixed list of scopes
read, write, update, delete, share etc
When an entry/instance (say of a Book) is shared, the model changes from
being type based to being based on the ID of the object i.e. the Book's ID

If I understood correctly, that means the size of the token will grow with
each object shared directly with a user, surely a problem.
In a similar vein, do I have to create an entry for every Book record in
keycloak to be able to do per book permissions?


More information about the keycloak-user mailing list