Hi Marcel,
These are all valid concerns.
Currently, we are working with some improvements to policy enforcers and
evaluation API. Some of them can help you achieve what you want:
*
https://issues.jboss.org/browse/KEYCLOAK-6794
*
https://issues.jboss.org/browse/KEYCLOAK-6628
*
https://issues.jboss.org/browse/KEYCLOAK-6529
I do think your problem is pretty much related with KEYCLOAK-6529 as we are
planning to include some common information in a permission ticket such as:
* HTTP request information such as path, path parameters, request
parameters, etc.
* Provide some way that you, as a developer, can push any other claim to a
permission ticket
I have one question though. Have you implemented a custom Policy Provider
using the Policy Provider SPI ? Or are you just using a Javascript policy ?
Regards.
Pedro Igor
On Mon, Mar 12, 2018 at 6:41 AM, Marcel Német <marcel.nemet(a)gmail.com>
wrote:
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
_______________________________________________
keycloak-user mailing list
keycloak-user(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user