Microservice intercommunication and authority - jwt

This is more of an architecture question and not related to any specific technology. Let's say I have 2 rest microservices. A user has authority to service1, but not service2. However, service1 needs to access service2 for some side effect.
In my situation, service1 is actually public and you do not need a JWT to access it. Service2 requires an authenticated user.
One option I'm considering is that service2 allows calls from service1, but not from the user. That could be done with a generic JWT.
Does anyone have any suggestions? TIA!

In this case, service A should have permission to call service B, with a service user, and not with an end-user. If you are using oauth2.0, you should use client credentials. It is a grant type that is used to issue tokens to an authorized application using client id and client secret as credentials.
With this approach, service A will request a token to the OAuth server to access the endpoint of service B passing its client id and client secret and the OAuth server will give a token valid for service A to consume service B

Related

Authorization code grant type for service to service communication

I have two services: Service A and Service B
I have a central Identity Server that issues and validates tokens.
I need some of the resources of Service B to be accessed only by Service A.
How do I validate the audience, or how do I make sure that for ex.
the client credentials token of Service A is valid when calling
Service B, and tokens from other services are invalid.
Is it a bad practice or are there any issues in using authorization
code grant type for service to service authorization ?
When you issue a token for client credentials, then the subject of that token should be Service A. It will either be in the sub claim of a JWT (if you use JWTs for access tokens), or you will be able to get that information from an introspection endpoint (if you use opaque access tokens). Service B can use that information to reject any request with tokens where subject is not Service A.
Authorization code grant type assumes there is a resource owner (a user) and a browser available. It looks like in your case it will be impossible to implement authorization code flow, as you have two services talking directly to each other. Anyway client credentials should be enough for your needs.

How to use JWT Auth0 token for Cloud Run Service to Service communication if the Metaserver Token is overriding the Auth0 Token

Prerequisites
I have two Cloud Run services a frontend and a backend. The frontend is written in Vue.js/Nuxt.js and is using a Node backend therefore. The backend is written in Kotlin with Spring Boot.
Problem
To have an authenticated internal communication between the frontend and the backend I need to use a token thttps://cloud.google.com/run/docs/authenticating/service-to-service#javahat is fetched from the google metaserver. This is documented here: https://cloud.google.com/run/docs/authenticating/service-to-service#java
I did set it all up and it works.
For my second layer of security I integrated the Auth0 authentication provider both in my frontend and my backend. In my frontend a user can log in. The frontend is calling the backend API. Since only authorized users should be able to call the backend I integrated Spring Security to secure the backend API endpoints.
Now the backend verifies if the token of the caller's request are valid before allowing it to pass on to the API logic.
However this theory does not work. And that simply is because I delegate the API calls through the Node backend proxy. The proxy logic however is already applying a token to the request to the backend; it is the google metaserver token. So let me illustrate that:
Client (Browser) -> API Request with Auth0 Token -> Frontend Backend Proxy -> Overriding Auth0 Token with Google Metaserver Token -> Calling Backend API
Since the backend is receiving the metaserver token instead of the Auth0 Token it can never successfully authorize the API call.
Question
Due the fact that I was not able to find any articles about this problem I wonder if it's simply because I am doing it basically wrong.
What do I need to do to have a valid Cloud Run Service to Service communication (guaranteed by the metaserver token) but at the same time have a secured backend API with Auth0 authorization?
I see two workarounds to make this happen:
Authorize the API call in the Node backend proxy logic
Make the backend service public available thus the metaserver token is unnecessary
I don't like any of the above - especially the latter one. I would really like to have it working with my current setup but I have no idea how. There is no such thing like multiple authorization token, right?
Ok I figured out a third way to have a de-facto internal service to service communication.
To omit the meta-server token authentication but still restrict access from the internet I did the following for my backend cloud run service:
This makes the service available from the internet however the ingress is preventing any outsider from accessing the service. The service is available without IAM but only for internal traffic.
So my frontend is calling the backend API now via the Node backend proxy. Even though the frontend node-backend and the backend service are both somewhat "in the cloud" they do not share the same "internal network". In fact the frontend node-backend requests would be redirected via egress to the internet and call the backend service just like any other internet-user would do.
To make it work "like it is coming from internal" you have to do something similar like VPN but it's called VPC (Virtual Private Cloud). And luckily that is very simple. Just create a VPC Connector in GCP.
BUT be aware to create a so called Serverless VPC Access (Connector). Explained here: https://cloud.google.com/vpc/docs/serverless-vpc-access
After the Serverless VPC Access has been created you can select it in your Cloud Run Service "Connection" settings. For the backend service it can be simply selected. For the frontend service however it is important to select the second option:
At least that is important in my case since I am calling the backend service by it's assigned service URL instead of a private IP.
After all that is done my JWT token from the frontend is successfully delivered to the backend API without being overwritten by a MetaServer token.

Quarkus: how to authenticate between microservices?

We have a requirement where we need some service-to-service communication between two Quarkus microservices. The infrastructure is the following:
Authentication is done by another IDP application.
Service 1:
implements main domain logic
primarily used by the frontend
API is called with authenticated user (openID, JWT)
endpoints are secured with #RolesAllowed("XY")
Service 2:
should use secured API from Service 1
Service 1 API will not be called with authenticated user (execution by task scheduler and not frontend)
My main problem: if Service 2 would directly be called from the frontend, the solution would be to easily pass through the JWT token from Service 2 to Service 1. But since Service 2 is not called in the context of a user I don't have a JWT token which I can pass.
How should Service 2 authenticate with Service 1 in such a scenario?
Either you use the client credentials flow between Service 1 and Service 2, so that they can communicate securely without any user involvement. This means that they can communicate even when no user is present.
The alternative is to use Delegation Tokens, see these links
https://auth0.com/docs/tokens/delegation-tokens
https://www.scottbrady91.com/OAuth/Delegation-Patterns-for-OAuth-20
enter link description here

keycloak bearer-only clients: why do they exist?

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?
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
I have to create two client inside a realm in keycloak
Client A will be use by web-app
Client B will be used by rest-api
So now question will be why two client?
For web-app we want to force user to login via GUI then only generate the token
For rest-api we dont want GUI based api as these api consume by web-app but still secure the access to rest-api.
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
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.
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.
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.
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.

OAuth2 service to service authorization

We are building two separate REST services and are looking for a way to let them securely communicate with each other.
If we can esstablish a secure communication between service A and B we can reverse the impl. and will be able to communicate from B to A.
We thought about using OAuth2 for this but find little or no information on how you could implement service to service authorization with OAuth2.
We have questions like what kind of grant type to use in such a scenario.
The idea we have now is, creating an account for server A on server B so server A can authenticate itself at server B and initialize the client credentials grant type flow.
Your idea sounds okay. When Service A is a server, Service B is a client, and vice versa.