[keycloak-user] Obtaining permissions for resources which are not registered as Keycloak Resources

Marcel Német marcel.nemet at gmail.com
Mon Mar 12 05:41:04 EDT 2018


Hi,

We have an application with a large number of documents which are being
sent between companies. A company can have multiple users. We have many
companies and users can (on behalf of their company) send documents to
other company. Then the document can be accessed either by the users of the
sending company or the users of the receiving company. All documents can be
also accessed by our customer-care operators (but this is a simple case
which can be easily covered by the role-based access control). Our data and
users are in SQL Server DB, so we would like to use user federation
interfaces to get the users.

I would like to solve the problem in following way:
1. Using the user federation "company ID" custom attribute to the identity
token of each user.
2. Write a rule-based Policy in Java or JavaScript named "Only users which
belong to a sender or receiver company"
3. When somebody wants to access a document with ID "abc-123" which was
sent by company "bbb" and received by company "ccc" the Java or JavaScript
policy could - based on the resource ID "abc-123" and based on the "company
ID" custom attribute - query our database to see whether the "company ID"
of the logged-in user is a sender company or a receiver company of a given
document
3*. Optionally the sender and receiver company of the document could be
sent along as additional attributes in the permission ticket by the policy
enforcer, then the resource server would do the reading from the database
and Keycloak Policy can decide without DB connection. But I am not sure
this is secure, the permission ticket from policy enforcer could be
manipulated and the company ID of a hacker's company could be added as a
sending company, then the hacker could access all documents. But I guess
permissions tickets are protected against manipulation.

The problems which I am facing:
Regarding the step 3., the only way to get "document ID" to the
$evaluation.permission variable of the Java/JavaScript Policy is to create
a Keycloak resource for every single document with a matching name and a
matching URI (e.g. name= "abc-123"  and URI= "/document/ abc-123").

It seems complicated for me to create a resource for every document which
we have and then delete those resources when we delete the documents since
the same policy applies to all documents anyway. We have huge numbers of
documents being sent every day between companies. At the same time, if we
do not create a Keycloak resource for every document, then I believe we can
not configure the policy enforcer to use the "/document/{id}" wildcard. The
Authorisation server will not receive the document ID unless there is a
Keycloak resource with the same name. Ideally, the Keycloak server should
be able to grant permissions even if it does not have a resource registered
and apply policies registered with URI /document/*. The
$evaluation.permission variable should hold the also the full URI not the
one with a wildcard. I understand that currently, the URI in
$evaluation.permission will be "document/*" even when a user is accessing
"/document/abc-123" (unless we create a Keycloak resource for every
document with a matching URI).

To summarize:
It would be great if the policy enforcer could obtain permissions to access
document  "abc-123" even without creating resource "abc-123" in Keycloak.
The idea is that the policy enforcer asks "Can this user access
document abc-123?"
and the Java policy in the Keycloak can decide based on the ID of the
resource and additional data inside the identity token or based on queries
to our DB.
Is there a workaround or recommended solution?

I have read through the previous mail-list topics below, and I saw that
some user "hacked" the policy enforcer to send the precise URI from the
policy enforcer. Or is there another way to pass the document ID to
Keycloak Policy (i.e. inside $evaluation.permission) without creating a
Keycloak resource for every document? Is there a feature request in Jira
which would cover such use cases? Allowing Keycloak to grant permissions
for resources without having to register all resources in Keycloak would
make it a more general solution.

Related topics from the mailing list:

"Performance with a large number of resources":
http://lists.jboss.org/pipermail/keycloak-user/2017-May/010583.html

and

"Additional attributes for an authorization request":
http://keycloak-user.88327.x6.nabble.com/keycloak-user-Additional-attributes-for-an-authorization-request-td2571.html

Kind regards,
Marcel


More information about the keycloak-user mailing list