[keycloak-user] Data filtering in SQL

Pedro Igor Silva psilva at redhat.com
Fri Nov 9 07:29:00 EST 2018


On Thu, Nov 8, 2018 at 9:27 PM Byrd, Rob M <rmbyrd at dstsystems.com> wrote:

> Pedro,
>
>
>
> That is helping my understanding some, thank you.  I understand your
> recommendations on dealing with separating the employee's Salary field in
> my example too.  Please see follow-up questions below.
>
>
>
> String resource attributes statically in keycloak:
>
> 2.1) I had been thinking of Resource as a *type* of resource to this
> point not a specific instance.  But now I don't see how your suggestion of
> basically using the resource attribute to store a foreign key (ie. pet's
> veterinarian) will work unless we are talking about each individual pet
> instance being a keycloak resource.  Similarly it was mentioned pet 1 and
> pet 2 could have a meaningful Owner in keycloak, which again is making me
> think that *instances* are being suggested to store along with
> entity-relationships basically.  So, should I instead be thinking of
> keycloak resources as storing single instances of items in our system?
>
You should not think of Keycloak as storing *only* single instances, but
with the necessary support to store single instances. That was my point
when I mentioned that you can have a 1:1 or 1:N mapping between keycloak
resources and your resources.

The work to manage resources in Keycloak is quite trivial, keep them in
sync with your real resources too. Performance of authorization requests
for specific resources is quite good. It is a trade-off, the flexibility we
give regarding governing access to individual resources vs the drawbacks of
managing these resources in Keycloak. But again, you are not forced to use
this approach, it really depends on your requirements. For instance, we
support privacy through User-Managed Access (UMA), users are allowed to
manage permissions for their own resources, share resources with others,
allow/approve access to specific scopes/actions, and revoke access, where
you have loosely coupled clients and resource servers, resource servers in
control over the context that a permission should be granted, etc.

I'm not pushing you to any specific solution but trying to clarify what we
have, what we can do, what we can improve and how we could help "data
filtering" use cases. Btw, thanks you and Dmitry for starting this.

> 2.2) This relatively static storage of resources plus extra attributes
> like foreign keys seems to basically push/duplicate our business model of
> data into keycloak, to some degree, correct?  And the more keycloak needs
> to decide, the more gets duplicated into keycloak?
>
Not really, but true for data filtering. That is another
point/drawback/concern that I tried to make when I said that data filtering
is not among our target use cases. We can support it, but not something we
discussed in the details like we are doing in this thread.

Attributes can be used to define specific security related data associated
with a resource which are not part of your business model. Thus, allowing
you to keep your business model decoupled from security aspects that govern
access to your resources.

>
>
> Push claims:
>
> 2.3) The push claim alternative seems to be having application logic fetch
> more context as needed for the permission evaluation.  This might work okay
> when going after a single entity or asking singular questions of the
> application logic – but for lists, such as a user seeing his list of 100
> transaction history records amongst the 1 million transaction history
> records on the system, would a question be asked for each of the 1 million
> records, one at a time?
>
Pushing claims is not the correct approach to solve this problem.

First, Keycloak is optmized to only evaluate policies for resources where
the subject is the owner. So, considering that I decided to manage all 1
million resources in Keycloak, each resource would have a user as the
resource owner. During evaluation the policy engine is going to evaluate
permissions fo 100 resources, not 1 million.

You may ask now, would that scale ? Depends on how you obtain permissions
from the server. If you are asking the server for all permissions and users
can have 1 million resources over time, it won't scale. However, if you ask
permissions for individual transactions or a small set of transactions, it
will scale.

>
>
> Post-filtering of records:
>
> 2.4) A use case I still seek clarification on is the "post-filtering of
> records", which I was trying to get at with my previous question #5.
> Stated in another way - say a financial database has 1 million transaction
> records across thousands of users. Every user is allowed to see transaction
> history records view, but only the ones they transacted.  So, a single user
> viewing all transactions of the transaction history feature/resource should
> (obviously) only be able to see all HIS transactions, not all 1 million on
> the database.  Spring Security would have @PostAuth for this (though its
> drawback is slow db performance on first query that does a db table scan
> and brings back everything to the middle tier, which then inefficiently
> whittles it down to just what pertains to the user).  My question is what
> ways would this post-filtering of records be handled in Keycloak?  With
> what I know so far, I am guessing at keycloak basic options:
>
> a) Have each of 1mil transaction records managed by Keycloak, add a
> "creator" attribute for who instigated the transaction, and have that user
> identifier stored on each record so Keycloak can do the filtering down to
> the 100 correct records
>
b) Receive a push claim, for each of the 1mil transaction records,
> indicating who the "creator" is, so it may be matched against the current
> user and thus filter down to the 100 correct records
>
> c) During evaluation, the policy engine can call out to a service
> somewhere to get the primary keys of the subset of records this user can
> see (this may be like a Claim Information Point), then whittle the full
> list down to just those matching primary keys (kind of like sending an IN
> list of primary keys in a SQL WHERE clause)
>
> d) Something more like the “partial evaluation” that OPA blog and Dmitry
> has been talking about
>
You don't need to create a "creator" attribute. Resources in Keycloak
always have a owner. It can be the resource server (the application) itself
or some user in your realm. See
https://www.keycloak.org/docs/latest/authorization_services/index.html#_resource_overview
.

I just realized that we have another option in Keycloak that might be
helpful to solve data filtering. I think it is similar to what you linked
from OPA docs. Some background first about the capability that may help
with that.

In Keycloak, policies are allowed to push back claims to resource server
(the application protecting the resources you want to access). Quite
similar to Advice/Obligation in XACML. The idea is push back additional
constratins to the application in order to indicate additional checks that
should be performed by the policy enforcer. As a note, our CIPs do that in
order to reinforce access to resources based on any claim pushed to
Keycloak when evaluating permissions.

Let me give you an example. Consider a Transaction resource that you
created in Keycloak. This is a generic resource representing all your
transactions. Suppose you have a specific scope that represents an
operation that lists all user transactions. Let's call this scope
"transaction:list". This scope is associated with the Transaction resource.
So you have:

Resource: Transaction
Scopes: transaction:list

Now, in addition to any other policy that applies to the Transaction
resource (role, group, whatever) you have a specific permissions that
govern access to the "transaction:list" scope. This permissions is granted
by a "List Transaction Policy" as follows:

var permission = $evaluation.getPermission();
var identity = $evaluation.getContext().getIdentity();

permission.addClaim('data.filter.userId', identity.getId());

$evaluation.grant();

Now, the client application acting on behalf of your user tries to access
your application at "/api/v1/transaction" using HTTP GET. You know that GET
method on that endpoint is associated with the "transaction:list" scope, so
you ask Keycloak for permissions to "Transaction" resources +
"transaction:list" scope.

As a result, Keycloak will give you a response as follows:

"permissions": [
      {
        "scopes": [
          "album:list"
        ],
        "claims": {
          "data.filter.userId": [
            "e68fa92d-6167-438f-844b-78c7abfc0dd2"
          ]
        },
        "rsid": "d3aaaf68-50cf-4c5c-97b9-99910a7bfb27",
        "rsname": "Transaction Resource"
      }
]

In your application you can use the permission granted above, and the
"data.filter.userId" claim to create a query in your database as follows:

StringBuilder filter = new StringBuilder();
Map<String, Object> queryParams = new HashMap<String, Object>();

for (Map.Entry<String, Set<String>> entry : permission.getClaims().entrySet()) {

    if (filter.length() != 0) {
        filter.append(" and ");
    }

    String key = entry.getKey();

    if (key.startsWith("data.filter")) {
        String left = key.substring(key.lastIndexOf('.') + 1);
        filter.append(left).append(" = :").append(left);
        queryParams.put(left, entry.getValue());
    }
};

Query query = this.entityManager.createQuery("from Transaction where "
+ filter.toString());

for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
    query.setParameter(entry.getKey(), entry.getValue());
}

The key points here are:

* You are using a single resource to represent all transactions in your system

* You are using a specific policy to protect the "transaction:list"
operation by pushing back to your application how access should be
enforced

* Access management is still centralized and you can push back the
"data.filter" claim with any information you want in order to indicate
to the application how data must be filtered

* Your policies are using information already available from the
eluvation context (like user id, user attributes, user roles, groups)
without being forced to push any claim to the server

In fact, I can use this in one of our quickstarts that is using a
database and protecting data. So we could introduce something similar
to this in order to filter recors in addition to protect API
endpoints.

How that sounds to you ?


>
> General:
>
> 2.5) In general, it seems to me the bigger the chunks of extra context
> provided by application logic to the policy engine, the less detail about
> the actual constraints being enforced you have controlled and visible in
> the policy layer… somewhat defeating the purpose of the policy layer.  Does
> that sound correct?  I could see us offloading a ton of detail to the push
> claims – rather than, say, duplicating more of our business model in
> keycloak – and then realizing very little of our actual policy permission
> details are visible or controllable in the policy layer.  So I am not sure
> what we are getting at that point.
>
>                 a) An answer might be drawing the line at only role-based
> access control in the policy layer since that affinity is more easily
> provided as input (thought that could even be debated)
>
>                 b) Maybe we try to define and draw the line at
> “resource-based” controls only in the policy layer
>
>                 c) Maybe we make the unit of work for each push claim so
> granular that truly all of the policy rules that are occurring are
> basically expressed in the policy layer (thus allowing control, flexibility
> and visibility in one consolidated place)
>
>
>
> Thanks for your time.
>
>
>
> Rob Byrd
>
> DST
>
> Solutions Lead
>
> SS&C Technologies Inc.   |   1055 Broadway, Kansas City, MO 64105
>
> t: (816) 435-7286  *| *m (816) 509-0119
>
> *rmbyrd at dstsystems.com <rmbyrd at dstsystems.com>*  |  *www.ssctech.com
> <http://www.ssctech.com/>*
>
> Follow us: [image: cid:image001.png at 01D412C1.A14C5770]
> <https://www.linkedin.com/company/ss-c-technologies/> |  [image:
> cid:image002.png at 01D412C1.A14C5770] <https://twitter.com/ssctechnologies> |
> [image: cid:image003.png at 01D412C1.A14C5770]
> <https://www.facebook.com/ssctechnologies/>
>
>
>
> *From:* Pedro Igor Silva [mailto:psilva at redhat.com]
> *Sent:* Thursday, November 8, 2018 2:20 PM
> *To:* Byrd, Rob M <rmbyrd at dstsystems.com>
> *Cc:* Dmitry Telegin <dt at acutus.pro>; keycloak-user <
> keycloak-user at lists.jboss.org>
> *Subject:* Re: [keycloak-user] Data filtering in SQL
>
>
>
>
>
> On Thu, Nov 8, 2018 at 5:44 PM Byrd, Rob M <rmbyrd at dstsystems.com> wrote:
>
> Thanks Dmitry and Pedro,
>
>
>
> Pardon my simple-minded response below, but I am wondering how these
> specific items would work?  Dmitry, yes I agree your GET
> /projects/<project> and GET /projects scenario is on point for the issue –
> I hope my questions below can further clarify the discussion.  Here, I will
> have to make a “go or no-go” decision in about a week. J  I would love to
> take on the challenge of searching for the “holy grail” in this, but atm
> will need to figure out what Keycloak (or OPA, etc.) can confidently do
> today.
>
>
>
> Thanks for the great discussion and continued help!
>
>
>
> Questions
>
> 1) Simple role-based authorization policy seems doable.
>
>    - Ex: “Only veterinarians are allowed to read pet profiles.”
>
>
>
> 2) But how to answer once more context is needed, such as one resource’s
> affinity to another?  Literally how does the application figure it out?
> Like the below example would need a pet-veterinarian mapping resolved
> somehow, it seems:
>
>    - “Only the treating veterinarian is allowed to read a pet’s profile.”
>
> Just like in OPA, but using a different approach, you can also push
> information (the input in OPA) to your policies. We call this "pushing
> claims" [1]. In our policy enforcer we also have the concept of a Claim
> Information Point [2] (similar concent as a PIP) which you can configure to
> automatically push claims to your policies when checking access for a
> particular resource. There is also a CIP that allows you to fetch claims
> from external services.
>
>
>
> Besides, a resource in Keycloak has attributes, which can be anything you
> want. So you could, for instance, have a Pet Foo resources in Keycloak and
> update a "veterinarian" attribute associated with it. So you could have a
> policy that checks if the user making the request is the same defined in
> the attribute.
>
>
>
> [1]
> https://www.keycloak.org/docs/latest/authorization_services/index.html#_service_pushing_claims
>
> [2]
> https://www.keycloak.org/docs/latest/authorization_services/index.html#_enforcer_claim_information_point
>
>
>
>
>    -
>
>
>
> 3) Keycloak has taken an example of “Pet owners can access their own pet’s
> profiles.” and said we can write policies saying that "Only Owner" can
> access "/api/petservice/pet/{id}".  But how does the policy engine figure
> out who is the owner of /pet/2 vs /pet/3?
>
>  I can think two options. Like I mentioned before, we are resource-based
> and resources have an owner. So you can write policies that check if the
> resource owner is the user making the authorization request. Another option
> is to push claims.
>
> 4) Similarly, an OPA blog
> https://blog.openpolicyagent.org/write-policy-in-opa-enforce-policy-in-sql-d9d24db93bf4
> gives the example where “Only the treating veterinarian is allowed to read
> a pet’s profile, and only when signed in from a device at the pet’s
> clinic”.  Again, it is easy enough to provide the OPA engine the target pet
> and the current device location, but how exactly is it determined who is
> the treating veterinarian of that pet and what clinic the pet belongs to?
>
> 5) In general, the security difficulty is constraining what a user can
> see/do in a particular feature, so how exactly would a policy engine bring
> back a subset of records that particular user can see (based on their
> affiliated company, etc.)?
>
> 6) Similarly, how exactly would a policy engine bring back all records but
> not the fields a user should not see (such as employee salary field, unless
> the user is a HR VIP)?  These last two could be likened to @PostAuth
> post-filtering in spring security.
>
> You can have all those resources protected by Keycloak and make
> authorization requests to obtain the resources a user has access. We
> provide a REST API to create resources. And that is the point I tried to
> make when I said that data security is not really among the use cases we
> are trying to solve. Although it is possible. Keycloak allows you to send a
> "give me all" permission request. That means returning permissions for any
> resource, managed by Keycloak, that an user can access. But yeah, depending
> on how many resources you have you may end up with a huge response and a
> bad performance.
>
>
>
> Another approach is define a single Employee resource with a Salary scope
> to represent all your employees. So you could enforce access to your real
> employees and their salary based on the decisions made by the server for
> this single resource.
>
>
>
> The decision for one approach or another really depends on how fine
> grained you want to be, like I mentioned before. Do you need to manage
> indivudual employees or they all share the same access policies ?
>
>
>
> See this
> https://github.com/keycloak/keycloak-quickstarts/tree/master/app-authz-rest-employee
> .
>
>
>
> Regarding  fields (e.g: salary) you could consider it as a scope
> associated with a resource. In Keycloak you can define permissions for
> scopes, not only for resources.
>
>
>
>
>
> Rob Byrd
>
> DST
>
> Solutions Lead
>
> SS&C Technologies Inc.   |   1055 Broadway, Kansas City, MO 64105
>
> t: (816) 435-7286  *| *m (816) 509-0119
>
> *rmbyrd at dstsystems.com <rmbyrd at dstsystems.com>*  |  *www.ssctech.com
> <http://www.ssctech.com/>*
>
> Follow us: [image: cid:image001.png at 01D412C1.A14C5770]
> <https://www.linkedin.com/company/ss-c-technologies/> |  [image:
> cid:image002.png at 01D412C1.A14C5770] <https://twitter.com/ssctechnologies> |
> [image: cid:image003.png at 01D412C1.A14C5770]
> <https://www.facebook.com/ssctechnologies/>
>
>
>
> *From:* Pedro Igor Silva [mailto:psilva at redhat.com]
> *Sent:* Thursday, November 8, 2018 6:42 AM
> *To:* Dmitry Telegin <dt at acutus.pro>
> *Cc:* Byrd, Rob M <rmbyrd at dstsystems.com>; keycloak-user <
> keycloak-user at lists.jboss.org>
> *Subject:* Re: [keycloak-user] Data filtering in SQL
>
>
>
> Hi Dmitry,
>
>
>
> Agree with you when you mention application vs data security. I also agree
> that Keycloak can also solve data security problems.
>
>
>
> Privacy is one of the main reasons behind our UMA support a very important
> aspect of data security. In addition to privacy, we also added extensions
> to UMA and OAuth2 standards to enable applications to use Keycloak as a
> Policy Decision Point, mainly target for application security.
>
>
>
> As PDP (and PAP), Keycloak allows you to govern access to protected
> resources and to obtain authorization decisions as a result of the
> evaluation of policies associated with these resources. Being based on UMA
> and OAuth2 we support token-based authorization but also access control
> based on the permissions granted by the server. So, yeah, it should be
> possible to filter data based on those permissions as well dynamically
> create WHERE clauses.
>
>
>
> My main concerns about data security are scalability and manageability,
> two aspects that are closely related to how much fine-grained you want to
> be. Like I said, in Keycloak you can protect a set of one or more resources
> as well as scope specific permissions, which can span access decisions for
> one or more resources.
>
>
>
> We are using data security when you enable permissions to users or groups,
> where results are filtered based on the evaluation of these permissions.
> Performance wise, evaluation is quite satisfactory, being the main
> challenges the trade-off between usability vs performance. Recently we had
> important changes to improve the performance of our token endpoint and
> policy evaluation engine and I think we can perform well when fetching
> permissions from the server for a set of one or more resources.
>
>
>
> I'm happy to discuss how we can leverage what we have for data security if
> the community is interested.
>
>
>
> Regards.
>
> Pedro Igor
>
>
>
> On Wed, Nov 7, 2018 at 8:47 PM Dmitry Telegin <dt at acutus.pro> wrote:
>
> Hi Rob,
>
> On Tue, 2018-11-06 at 16:28 +0000, Byrd, Rob M wrote:
> > (Hope this is the correct way to reply - let me know if not)
> >
> > Thanks.  So my concern is really with the whole idea that an Enterprise
> Application's security constraints could really be all implemented based on
> url-patterns, is that what you guys are thinking?
>
> Cannot speak for Keycloak guys, but will put in my 2¢ as an architect -
> URL-based (or rather resource-based) authorization covers only one aspect
> of the application security. Data filtering is equally important, but it's
> just another facet of the problem, and needs to be solved accordingly.
> Indeed, Keycloak doesn't provide OOTB any means for automatically limiting
> subsets of data shown to the user, as Keycloak has a completely different
> scope (namely Web SSO/IDM solution).
>
> However, you can still use Keycloak as a central warehouse for your
> security (meta)data, and use it the way you want. Like I said before,
> nothing stops you from defining some policies in Keycloak, then retrieving
> them and converting to a WHERE clause for your SQL/JPQL/NoSQL query.
>
> Speaking of NoSQL - this might be not directly relevant to your problem,
> but still interesting. A similar problem has surfaced in the discussion
> following my talk on Apache Sling + Keycloak [1] earlier this year; the
> central point was: "okay, we can have Keycloak path-based authorization in
> Sling, but how do we limit the content visible to the user?"
> That time we came up with some sort of hybrid solution, like path-based
> security + JCR ACLs and/or application-level rules; but now I think this
> might be something similar, like generating JCR's equivalent to the WHERE
> clause based on Keycloak policy definition.
>
> Just to make sure I understand the case, let's imagine:
> - there are users and groups (live in Keycloak);
> - there are, say, "projects" (live in business tier + DB);
> - there is a policy in Keycloak saying "projects should be accessible only
> to the members of the respective groups";
> - based on that:
>  - GET /projects/<project> should return 200 + representation if the user
> is a member of the group, 403 otherwise;
>  - GET /projects should return the list of projects the current user has
> access to.
>
> Is this correct?
>
> [1]
> https://adapt.to/2018/en/schedule/modern-authentication-in-sling-with-openid-connect-and-keycloak.html
>
> Cheers,
> Dmitry Telegin
> CTO, Acutus s.r.o.
> Keycloak Consulting and Training
>
> Pod lipami street 339/52, 130 00 Prague 3, Czech Republic
> +42 (022) 888-30-71
> E-mail: info at acutus.pro
>
> >
> > For example, mostly a user can visit most features (urls) in an
> application, but it is the subset of things they can see/do within the
> feature that is the crux of the security issue - and it does not seem
> feasible to architect urls in such a way that they can be used as the key
> to security.  Thoughts?
> >
> > Thanks!
> >
> > Rob Byrd
> > DST
> > Solutions Lead
> > SS&C Technologies Inc.   |   1055 Broadway, Kansas City, MO 64105
> > t: (816) 435-7286  | m (816) 509-0119
> > rmbyrd at dstsystems.com  |  www.ssctech.com
> > Follow us:  |   |
> >
> > -----Original Message-----
> > > From: Dmitry Telegin [mailto:dt at acutus.pro]
> > Sent: Friday, November 2, 2018 12:22 AM
> > > To: Byrd, Rob M <rmbyrd at dstsystems.com>; keycloak-user at lists.jboss.org
> > Subject: Re: [keycloak-user] Data filtering in SQL
> >
> > Hello Rob,
> >
> > If I get it right, it's all about generating SQL WHERE clause from
> Keycloak policies? I think this is doable, as Keycloak has a well-defined
> object model for authorization policies, and it's easy to obtain policy
> definitions in JSON format. I think Pedro Igor will tell you more about
> that.
> >
> > You should pay attention to the following:
> > - there are differences in semantics between OPA and Keycloak policies.
> For example, Keycloak policies do not operate HTTP methods but rather use
> more generic notion of scopes;
> > - not every policy type can be easily converted to a WHERE clause. It
> should be trivial for User/Group/Role policies, but is virtually impossible
> for Script and Rules, as they are just blackboxes that evaluate to true or
> false. Unless of course your DBMS has a built-in JavaScript engine :)
> >
> > Good luck!
> > Dmitry Telegin
> > CTO, Acutus s.r.o.
> > Keycloak Consulting and Training
> >
> > Pod lipami street 339/52, 130 00 Prague 3, Czech Republic
> > +42 (022) 888-30-71
> > E-mail: info at acutus.pro
> >
> > On Thu, 2018-11-01 at 21:39 +0000, Byrd, Rob M wrote:
> > > I am comparing OPA authorization to Keycloak - how could I enforce
> Keycloak policy in the SQL closest to the data for good performance,
> including returning subsets of lists?  OPA discusses this at
> https://blog.openpolicyagent.org/write-policy-in-opa-enforce-policy-in-sql-d9d24db93bf4
> .
> > >
> > > Thanks!
> > >
> > > Rob Byrd
> > > DST
> > > Solutions Lead
> > > SS&C Technologies Inc.   |   1055 Broadway, Kansas City, MO 64105
> > > t: (816) 435-7286  | m (816) 509-0119
> > > rmbyrd at dstsystems.com<mailto:rmbyrd at dstsystems.com>  |
> www.ssctech.com<http://www.ssctech.com/>;;
> > > > > Follow us: [cid:image001.png at 01D412C1.A14C5770] <
> https://www.linkedin.com/company/ss-c-technologies/>  |  [
> cid:image002.png at 01D412C1.A14C5770] <https://twitter.com/ssctechnologies
> >  |  [cid:image003.png at 01D412C1.A14C5770] <
> https://www.facebook.com/ssctechnologies/>
> > >
> > >
> > >
> > > Please consider the environment before printing this email and any
> attachments.
> > >
> > > This e-mail and any attachments are intended only for the individual
> or company to which it is addressed and may contain information which is
> privileged, confidential and prohibited from disclosure or unauthorized use
> under applicable law. If you are not the intended recipient of this e-mail,
> you are hereby notified that any use, dissemination, or copying of this
> e-mail or the information contained in this e-mail is strictly prohibited
> by the sender. If you have received this transmission in error, please
> return the material received to the sender and delete all copies from your
> system.
> > > _______________________________________________
> > > keycloak-user mailing list
> > > keycloak-user at lists.jboss.org
> > > https://lists.jboss.org/mailman/listinfo/keycloak-user
> >
> >
> > Please consider the environment before printing this email and any
> attachments.
> >
> > This e-mail and any attachments are intended only for the individual or
> company to which it is addressed and may contain information which is
> privileged, confidential and prohibited from disclosure or unauthorized use
> under applicable law. If you are not the intended recipient of this e-mail,
> you are hereby notified that any use, dissemination, or copying of this
> e-mail or the information contained in this e-mail is strictly prohibited
> by the sender. If you have received this transmission in error, please
> return the material received to the sender and delete all copies from your
> system.
> _______________________________________________
> keycloak-user mailing list
> keycloak-user at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/keycloak-user
>
> ------------------------------
>
> Please consider the environment before printing this email and any
> attachments.
>
> This e-mail and any attachments are intended only for the individual or
> company to which it is addressed and may contain information which is
> privileged, confidential and prohibited from disclosure or unauthorized use
> under applicable law. If you are not the intended recipient of this e-mail,
> you are hereby notified that any use, dissemination, or copying of this
> e-mail or the information contained in this e-mail is strictly prohibited
> by the sender. If you have received this transmission in error, please
> return the material received to the sender and delete all copies from your
> system.
>
> ------------------------------
> Please consider the environment before printing this email and any
> attachments.
>
> This e-mail and any attachments are intended only for the individual or
> company to which it is addressed and may contain information which is
> privileged, confidential and prohibited from disclosure or unauthorized use
> under applicable law. If you are not the intended recipient of this e-mail,
> you are hereby notified that any use, dissemination, or copying of this
> e-mail or the information contained in this e-mail is strictly prohibited
> by the sender. If you have received this transmission in error, please
> return the material received to the sender and delete all copies from your
> system.
>
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 588 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20181109/846bddbb/attachment-0004.png 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 607 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20181109/846bddbb/attachment-0005.png 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image003.png
Type: image/png
Size: 566 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20181109/846bddbb/attachment-0006.png 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image001.png
Type: image/png
Size: 588 bytes
Desc: not available
Url : http://lists.jboss.org/pipermail/keycloak-user/attachments/20181109/846bddbb/attachment-0007.png 


More information about the keycloak-user mailing list