61

I am trying to wrap my head around the concept of bearer-only clients in Keycloak.

I understand the concept of public vs confidential and the concept of service accounts and the grant_type=client_credentials stuff. But with bearer-only, I'm stuck.

Googling only reveals fragments of discussions saying:

You cannot obtain a token from keycloak with a bearer-only client.

The docs are unclear as well. All they say is:

Bearer-only access type means that the application only allows bearer token requests.

Ok, if my app only allows bearer token requests, how do I obtain this token if I cannot get it from Keycloak using client id / client secret?

And if you can't obtain a token, what can you at all? Why do these clients exist? Can somebody please provide an example of using this type of client?

kurtgn
  • 8,140
  • 13
  • 55
  • 91
  • This isn't a complete answer but I think I have a good guess. It seems to me like these types of clients are mainly useful to Java developers using the official Keycloak libraries (the Java "Adapter"). Seems like the adapter will behave differently given a client id of a bearer only client. Don't ask me for any details but consider this mention of bearer only clients in the guide: https://www.keycloak.org/docs/latest/securing_apps/#java-configuration. It's a leaky Java abstraction in other words, which is why it seems so wierd to us non-java folks. – Segfault Mar 04 '21 at 01:16
  • @Segfault It's not a "leaky Java abstraction". Please see the answers and comments below for a better understanding understanding of this admittedly poorly documented feature. Any OIDC/OAUTH adapter, in any language, that does proper audience validation can take advantage of this feature, among other benefits. – DavidS Dec 29 '21 at 18:53
  • @DavidS In my opinion, it is a "leaky Java abstraction" because using this feature requires you to have the official Keycloak Java adapter in your server application. If your application is Ruby, or some other platform, then this "bearer-only" application is useless. It is a server side configuration that affects the behavior of the client application. Any OIDC/OAUTH adapter, in any language, can do this exact thing without ever needing to create a "bearer-only" client application in Keycloak server, it's pointless. – Segfault Dec 30 '21 at 12:35
  • @Segfault I think I understand what you're saying, the problem is it's demonstrably incorrect. It a server side configuration that affects the behaviour of _server side_ token generation, such as automatically setting the `aud` and `azp` claim where its appropriate. The Ruby application would check these claims during token validation. – DavidS Dec 30 '21 at 21:49
  • @DavidS can't you automatically set `aud` and `azp` claims with any client, not a bearer-only client? Doesn't the bearer-only configuration setting configure the behavior of the official java adapter? Anything you want to accomplish with keycloak can still be accomplished if they did not have such a thing as bearer-only clients? – Segfault Dec 31 '21 at 13:35
  • @Segfault (1) Keycloak cannot automatically set the aud claim if it is unaware the client exists: for example, if you have a public web client that calls a bearer only client. (2) The Java adapter uses the keyword “bearer-only” to configure behaviour, yes, but this isn’t a requirement. (3) You could accomplish some but not all of the behaviour by adding token attributes statically, but not everything, and the behaviour wouldn’t be dynamic. – DavidS Jan 01 '22 at 17:33
  • @DavidS Keycloak can set the aud claim automatically if the client exists as a normal client, and not a bearer-only client. If you don't want it to make tokens, you can just set it to confidential and don't tell anyone the client secret, then it cannot make tokens. Bearer-only clients are not required for this. – Segfault Jan 03 '22 at 14:59
  • @Segfault Sure, but I don’t see why anyone would do that when they can specify it explicitly. A confidential client with flows disabled and a secret you never share versus simply bearer-only. I think we’re pretty far from “leaky Java abstraction” by this point, so if you don’t mind this will be my final comment. Please read some of the answers and comments below if you’d like to learn more, or ask another question. – DavidS Jan 03 '22 at 16:43
  • @DavidS The question was: why do you need this. The answer is, you don't, unless you're using the official java adapter, in which case you use it to configure that applications behavior. Therefore, it is a leaky java abstraction. I see we're not going to agree on this, but really it's a semantic argument and I also will not comment further. Thanks! – Segfault Jan 04 '22 at 15:05
  • @Segfault I'm surprised and disappointed you have read my comments and still drawn that factually incorrect conclusion. This has _nothing_ to do with the Java adapter or Java. This "bearer-only" validation can and should be done with any token validation library, and setting the client to "bearer-only" has a concrete and demonstrable effect on client capabilities and token generation, which again has nothing to do with Java. Your conclusion at this point seems obstinate and factually incorrect, not "semantic", I'm sorry to say. – DavidS Jan 04 '22 at 18:03
  • @Segfault Auth0 also supports the same configuration. When creating a client in Auth0, you create either an "Application" or an "API". An API in Auth0 is a bearer-only client. There is no secret and no way to obtain a token from the client. – DavidS Jan 04 '22 at 18:16

4 Answers4

85

Bearer-only access type meaning

Bearer-only access type means that the application only allows bearer token requests. If this is turned on, this application cannot participate in browser logins.

So if you select your client as bearer-only then in that case keycloak adapter will not attempt to authenticate users, but only verify bearer tokens. That why keycloak documentation also mentioned bearer-only application will not allow the login from browser.

And if you can't obtain a token, what can you at all? Why do these clients exist?

Your client can't be set as bearer-only on Keycloak Server. You can still use bearer-only on the adapter configuration though. Keycloak doesn't allow "bearer only" clients (when setting up your client on the server) to obtain tokens from the server. Try to change your client to "confidential" on the server and set bearer-only on your adapter configuration (keycloak.json).

So if you understand above statement then if you have two microservice which are talking to each other in the case, caller will be confidential and callee will be bearer-only

And Keycloak also mentioned

Bearer only client are web service that never initiate a login .It’s typically used for securing the back-end.

So if you want to use any adapter you can use bearer-only depend on the need

EDIT-

Lets go in more details ..Let see one example i have a web-app and one rest-api for web-app i am using React/Angular/JSF any front end technology and for back-end i am using Java based rest-api OR Nodejs.

Now for above requirement i have to secure both the products(web-app,rest-api) so what will be my work of action? How will I secure both the apps through Keycloak?

So here is details explanation

  1. I have to create two client inside a realm in keycloak
  2. Client A will be use by web-app
  3. Client B will be used by rest-api
  4. So now question will be why two client?
  5. For web-app we want to force user to login via GUI then only generate the token
  6. For rest-api we dont want GUI based api as these api consume by web-app but still secure the access to rest-api.
  7. Now Go to Client A and make its Access Type public client so web-app will ask to login via keycloak GUI or your login page then generate the token
  8. So same token which generated in above step used by rest-api and according to user role and other information data will fetch. So Access Type of Client B will be bearer-only so web-app generated token is passed to rest-api and it is then used to authorize the user .

Hope it will help. Someone want to add more he/she free to add.

FenderBender
  • 87
  • 1
  • 9
Subodh Joshi
  • 12,717
  • 29
  • 108
  • 202
  • 4
    thanks Subodh for your explanation! So this means that if my client is bearer-only, the only option available to me is making verification requests to Keycloak to make sure the token is valid. Right? But if this is the case, why call Keycloak at all? If my client has a public Keycloak key, it can verify it using this key without ever calling Keycloak. – kurtgn Nov 18 '19 at 15:25
  • @kurtgn If you are using any adapter then only i will suggest to use the `bearer-only` otherwise make your client `confidential` – Subodh Joshi Nov 18 '19 at 15:34
  • No, i’m not using adapters, i am coding in Python, thereare no python-specific adapters for Keycloak, so I have to use generic OIDC libs – kurtgn Nov 18 '19 at 18:25
  • Which library you are using with Keycloak+Python Integration? – Subodh Joshi Nov 19 '19 at 08:07
  • This one https://docs.authlib.org/en/stable/client/django.html – kurtgn Nov 20 '19 at 03:49
  • @kurtgn Please have a look on this [link](https://medium.com/@sairamkrish/keycloak-integration-part-3-integration-with-python-django-backend-5dac3b4a8e4e) – Subodh Joshi Nov 20 '19 at 10:06
  • Thansk for the link, but I didn't find any mention of `bearer-only` clients there. – kurtgn Nov 20 '19 at 13:32
  • That what I mentioned you from starting why you using bearer-only used for microservice to microservice talk – Subodh Joshi Nov 20 '19 at 13:35
  • Callees don't need to be`bearer-only`, in fact, they don't need to be anything. We are running several microservices, and we have a client to authorize and present the token. Tokens are signed, so the callees just need to verify the signature and the expiration. There is no need to call KeyCloak for this. So @kurtgn question still stands, what is the `bearer-only` for? – irbull Dec 05 '19 at 07:54
  • @irbull I do agree with you, the question still stands. any update about that, did you find out ? – Seb Jun 26 '20 at 08:50
  • 1
    bearer-only in rest-api with keylocak is only offline validation? What happens if the token was invalidated by a logout or if I close all session in admin console? I've tested my rest-api using a token previously obtained when I login, then I logout before than token expire, and the api still response. Why te adapter doesn't verify against keycloak server? – Hector Aug 21 '20 at 17:13
  • @Hector How u generated your token via keycloak rest-api or from your web-app? – Subodh Joshi Aug 21 '20 at 17:32
  • @SubodhJoshi token is generated by react app, or even with postman, the thing is when I close session either app react or web admin console I can use this token to call a api until the token expire. I test with backend api written in node and spring boot using keycloak adapters. – Hector Aug 22 '20 at 19:19
  • @Hector you have to tell more detail Like your web-application/backed API's client `Access Type` ? `toke-life-span'/``session-timeoue' etc. – Subodh Joshi Aug 23 '20 at 10:47
  • @SubodhJoshi in Keycloak I have a client for my react-app, the access type is public or confidential, and for my backend rest api I connect to this client, also I tried with a new client only for my back api with access type _bearer-olnly_. In my rest api I use keycloak connect adapter to secure my endpoint using only protect('realm:user') method, following the quickstart-examples node adapter in github. I set Access Token Lifespan in 1 hour, so if I logout before token expire, and I still call the api using postman using previous token generated at login moment. – Hector Aug 24 '20 at 13:41
  • Reviewing the keycloak-connect code in github, I view the *protect* method only verify if token has role, not verify with keycloak server if token is still valid. – Hector Aug 24 '20 at 13:44
  • 1
    "Your client can't be set as bearer-only on Keycloak Server. You can still use bearer-only on the adapter configuration though." I think this is incorrect. In client configuration, you can set public, confidential, or bearer-only. The answer correctly explains the use of bearer-only clients, but it doesn't explain why you would want to register them in Keycloak. A client application does not need to be registered to do token validation. – DavidS Dec 29 '21 at 18:25
14

Short answer: you can't obtain an access token using a bearer-only client, so authentication flow configuration is irrelevant, but keycloak may still need to know such a bearer only client to manage role / or audience

More details bearer-only clients usefully represents back-end applications, like web service, called by front application and secured by the authorization server (= keycloak)

Backend / Web service application are not called directly by user, so they can't play in the Oauth2.0 user interactive flow. Setting "bearer-only" document this fact to keycloak server, allowing administrator to configure client without otherwise mandatory values (example redirect uri…) and allowing usefull error messages if someone trying to obtain a token for such a client

However, this doesn't mean you cannot configure specific roles for this client: so it need to appear in keycloak realm.

In addition bearer-only client need to verify the received access token, especially, if this (recommenden) adapter feature "verify-token-audience" is activated, bearer-only client need to verify that the access token has been issued for it: the bearer-only client must be in the audience attribute of the access token: see https://www.keycloak.org/docs/latest/server_admin/index.html#_audience

for audience managing by keycloak, bearer-only clients needs to be registered in keycloak realm.

Thomas LIMIN
  • 387
  • 4
  • 9
  • I think this should be the accepted answer – prietosanti May 13 '21 at 19:43
  • This answer is useful but a bit misleading. "a bearer only client need to verify access tokens, so it need to be registered in keycloak": you don't really need to register the client to verify access tokens. Anyone can read and verify tokens; they're not encrypted. I do think the final sentence is very helpful though, "for audience managing by keycloak, bearer-only clients needs to be registered in keycloak realm." Keycloak can't set the `aud` automatically if it doesn't know the client exists. – DavidS Dec 29 '21 at 18:29
12

In my understanding, it is used when you have some internal service. Let's say you have ServiceA and ServiceB. A user calls ServiceA which in hand calls ServiceB. ServiceB is never called by the user directly, only by other services. ServiceA will get a token using the user's credentials. And then will use this token to call ServiceB. ServiceB will never initiate a login. It will just use the token to verify permissions.

In this case, ServiceA will be confidential and ServiceB will be bearer-only clients.

Yuriy P
  • 1,330
  • 9
  • 16
  • 1
    So this means that if my client is bearer-only, the only option available to me is making verification requests to Keycloak to make sure the token from `ServiceA` is valid. Right? But if this is the case, why call Keycloak at all? If my client has a public Keycloak key, it can verify it using this key without ever calling Keycloak. – kurtgn Nov 18 '19 at 15:27
  • Because of token scope. Service A should have an other scope than Service B, so you need Keycload for token exchange – Julian Egner Nov 22 '19 at 15:40
  • @JulianEgner This makes sense, except Token Exchange is currently in Tech Preview, not fully supported, and must be explicitly turned on with an Env Variable. Is `bearer-only` really in place just to support this use-case which isn't ready yet? – irbull Dec 05 '19 at 07:44
  • @irbull where did you get the info that token exchange would be in tech preview? – Julian Egner Dec 05 '19 at 09:59
  • @JulianEgner It was listed at the very bottom of their docs. Listed in https://www.keycloak.org/docs/latest/securing_apps/index.html#_token-exchange it says "Token Exchange is Technology Preview and is not fully supported. This feature is disabled by default." – irbull Dec 05 '19 at 15:15
  • Thanks for the explanation, but if I may add a question, why bearer clients in keycloak has client secret? if they are only use to verify tokens, where should we use the client secret of a bearer clients? – Azel Jun 01 '20 at 08:41
  • I think the details of this post are correct, it doesn't really answer the question of why we would bother registered bearer-only clients in Keycloak. ServiceB doesn't need to be registered in Keycloak to inspect and validate the token. – DavidS Dec 29 '21 at 20:34
3

An other idea why bearer only clients exist could be that client are misused for role containers sometimes, see the following discussion on the Keycloak User mailing list https://lists.jboss.org/pipermail/keycloak-user/2016-April/005731.html

E. g. the default client "realm-management" is a bearer only client, that contains roles to manage things in a realm. There is no need to invoke a login on a client like this, so public and confidential doesn't make any sense.

ben9390
  • 31
  • 3
  • That's a helpful link, but I don't think it's evidence that using a client as a role container is "misuse". They're discussing the built-in Keycloak clients, and they note "We're also going to remove 'broker' and 'realm-management', these are just used as a 'container' for roles and will be replaced with role namespaces", but this doesn't mean that it's a "misuse": I'd say it's a design alternative. That said, I'm not even sure what they mean by "role namespaces". I'm aware of client roles, realm roles, and groups. Maybe they mean realm roles, which are global to the realm. – DavidS Dec 29 '21 at 18:36