Hi,
This topic has been around for a while, and I'm glad to know that it
has finally been greenlit. Here we'll discuss the requirements for the
upcoming Realm Admin Resource SPI, as well as class/method naming and
any other relevant stuff.
An admin resource is a privileged (protected) resource that exposes
Keycloak data model and business logic via REST. A the moment, it is
possible to create ad-hoc admin resources on top of existing Realm
Resource SPI, but 1) it requires a lot of boilerplate and workarounds,
and 2) there are limitations. For a while, we've been developing a
Keycloak extension that utilizes such ad-hoc admin resources (for those
interested, it brings into Keycloak support for hardware OTP tokens
with full lifecycle) . We've tried to summarize our experience in
BeerCloak [1], where most techniques are demonstrated; I'll refer to
this example in the process.
Now what makes admin resource different from the regular realm
resource? I'll talk about some major features; feel free to share your
thoughts in case I've forgotten something.
Security
========
As admin resource most likely introduces some new functionality, it's
quite natural to limit access to this new functionality by custom
roles. For example, if we introduce feature "foo", most likely we'll
want "view-foo" and "manage-foo" roles. This requirement breaks down
to
the following steps:
* create roles for existing realms. That means adding roles to "*-
realm" clients of master realm and to "realm-management" client of
regular realms;
* ditto for each newly added realm;
* add roles to the "admin" realm role of master realm;
* server-side authorization: provide an instance of
o.k.services.resources.admin.AdminAuth (or subclass) to REST resource
methods so that they could call AdminAuth::hasAppRole;
* client-side authorization: add viewFoo and manageFoo properties to
the "access" AngularJS object.
All of the above is doable on top of Realm Resource SPI (see
BeerCloak), but the code is 99% boilerplate. In fact, the only thing
that the provider (ideally) has to do is to declare the two roles. The
actual implementation could be moved to the SPI. What we need is to
discuss how the roles should be declared (callback, annotation etc.)
Logging
=======
Most likely the admin resource will deal with custom JPA entities
defined using Entity SPI. Moreover, there will likely be a need to log
admin events about this entity and its operations. Currently, we are
limited to 4 generic operation types (see
o.k.events.admin.OperationType) and a list of 27 hardcoded
entity/resource types (see o.k.events.admin.ResourceType). This is a
serious limitation because any provider that defines custom entity
and/or REST operations will be unable to log its activity with Keycloak
API and present it with Keycloak GUI. As an example, the aforementioned
OTP extension would benefit from logging admin events with DEVICE
resource type and ENROLL/REVOKE/LOCK/UNLOCK/RESYNC additional operation
types. We can discuss now which way the provider would define its
custom resource operation and resource types. Under the hood, the
existing enums should be extended with the supplied values (possibly
using the extensible enum pattern [2][3]). The values should also
appear in
o.k.services.resources.admin.info.ServerInfoAdminResource::ENUMS so
that log filtering could be applied in the GUI.
Last time when we discussed this, Stian said:
Introducing this as part of a admin resource spi would make perfect
sense.
I agree that extending OperationType is more pertinent to Admin
Resource SPI ("I define an operation and I want to be able to log it").
At the same time, extending ResourceType seems to be more topical for
Entity SPI ("I define an entity and I want to log everything about
it"). We should decide if we should extend the said SPIs, or otherwise
create independent OperationTypeSpi+ResourceTypeSpi that could be mixed
into any provider, be it entity, admin resource or anything else.
At the moment, this couldn't be implemented without modifying Keycloak
sources.
Relation to FeatureProvider
===========================
Bill, once we discussed the potential FeatureProvider:
I was also thinking of having a FeatureProvider that would be an
"uber" component that could install sub components. i.e. an
authenticator, user federation provider, etc.
I think we could revisit this topic too, since both SPIs seem to be
closely related.
Thanks for reading this bulky post! Any feedback welcome,
Dmitry Telegin
CTO, CargoSoft LLC
http://cargosoft.ru/en/rm/about/
[1]
https://github.com/dteleguin/beercloak
[2]
https://blogs.oracle.com/darcy/mixing-in-an-enum
[3]
https://gist.github.com/KamilT/3192681 id="-x-evo-selection-start-
marker">