In the first scenario, we built a NodeJs service that on one end exposes the /token, /token/introspect, /certs endpoints to intercept the calls and forward them into keycloak (like a custom reverse proxy if you wish) but the responses are intercepted, analysed and completed by the customised access token and introspecting result. In your case, your API must be called and the result used to complete the token content. If the jwt is needed, it cannot be signed by Keycloak private key, so the NodeJs service must holds its own private key. Then the /certs endpoint should return the public key of the service aggregated with the public keys of keycloak.
In addition, once you have this done you should wrap keycloak behind a real reverse proxy (like nginx) and make it redirect the …/realmname/[token* or certs] to your service and the others endpoints to keycloak directly. Then from the client perspective, the nginx becomes the real IDP server.
In the second scenario we take a very different approach and uses the Keycloak enrichment mechanism :
- The keycloak authorization workflow enables to add custom authenticator that can perform actions on the keycloak data model. I have published this in the form of a library that I described at https://medium.com/application-security/how-to-create-a-keycloak-authenticator-as-a-microservice-ad332e287b58.
- Then in the custom implementation of your authenticator you would call your custom API and use the result to feed the keycloak data model - such as the user attributes and/or session notes
- Then, in keycloak mappers you can use these fields (user attributes and session notes) to feed the keycloak tokens
The choice between the 2 options is, in my opinion, based on whether you consider Keycloak a long term choice (scenario 2) or not (scenario 1). So use the scenario 1 mainly if you need later to change your IDP technology or be as much as possible independent from version changes.
I hope I have clarified things for you, if you need more, maybe we can have a longer chat and share some code (that I cannot publish) or co-construct a prototype