Considering that, you're right, and this is a design gap worth fixing

The standard pattern for multi-tenant resource servers is issuer-based
tenant resolution, which Spring Security supports natively via
*JwtIssuerAuthenticationManagerResolver*. Each Keycloak realm has a unique
iss value in its JWTs. That issuer URL is a stable
(cryptographically-scoped identifier for the realm) no custom claims
needed, no shared realm, no coordination between tenants. The resource
server just maps *iss → tenant-id* and builds a per-issuer *JwtDecoder*
that validates tokens against the correct JWKS endpoint.

The result is a three-tier resolution hierarchy:

  iss → issuer map (realm-per-tenant, zero custom claims)
      → tenant-claim-name (single-realm, claim-based)
          → Fineract-Platform-TenantId header / query param (tooling/CI
fallback)

This covers the full deployment without forcing any particular IdP topology.

Does this direction align with what you had in mind? If so, I can update
the PR with these changes

Best regards
Alberto


On Wed, Jun 3, 2026 at 11:16 AM Arnold Galovics <
[email protected]> wrote:

> Hi Alberto,
>
> Thanks for the reply.
>
> I still think this is not enough. Having a separate custom claim in the
> JWT is fine for really really small deployments where you own everything.
>
> In slightly bigger deployments maybe one Keycloak instance is the one
> serving as an auth server but multiple realms are there (with separate
> clients at this point).
>
> The way you describe separation would mean the only option is to have one
> Keycloak instance with a single Realm and with a single client and within
> that realm, all users get JWTs with their respective tenant IDs. I'd hardly
> call that separation and wouldn't fly in any medium deployments.
>
> I'd hold off your PR before people start utilizing and depending on this
> singular OIDC configuration because migration in the future might be more
> costly than doing it the proper way at the starting line.
>
> Thanks.
> Best,
> Arnold
>
>
> Arnold Gálovics
>
> *CEO, Co-Founder*
>
> *+36 30 904 1885*
>
> https://docktape.com
>
> Docktape Technologies
>
>
>
>
> On Wed, Jun 3, 2026 at 2:25 PM Jose Alberto Hernandez <
> [email protected]> wrote:
>
>> Hello! Sorry for the late reply
>>
>> A single OIDC config means sharing the same IdP, not the same tenant. One
>> Keycloak instance can serve multiple tenants perfectly well using a custom
>> *fineract_tenant* claim in the token.
>>
>> The implementation already handles multi-tenancy correctly
>> *OidcTenantAwareFilter* resolves the tenant from the JWT claim before
>> any authentication happens, and *OidcAppUserResolutionService* maps the
>> identity to a per-tenant *AppUser*, just like Basic Auth does today.
>>
>> Per-tenant IdP configuration (different realms/providers per tenant) is a
>> valid but significantly more complex feature — it would require storing
>> OIDC config per tenant in the database and dynamic issuer resolution at
>> request time. That deserves its own JIRA, not a blocker on this PR.
>>
>> What do you think?
>>
>> Thanks and regards
>> Alberto
>>
>> On Wed, Jun 3, 2026 at 3:01 AM Arnold Galovics <
>> [email protected]> wrote:
>>
>>> Hey guys,
>>>
>>> Just putting a ping here.
>>>
>>> Best,
>>> Arnold
>>>
>>> Arnold Gálovics
>>>
>>> *CEO, Co-Founder*
>>>
>>> *+36 30 904 1885*
>>>
>>> https://docktape.com
>>>
>>> Docktape Technologies
>>>
>>>
>>>
>>>
>>> On Fri, May 29, 2026 at 9:03 AM Arnold Galovics <
>>> [email protected]> wrote:
>>>
>>>> Hi guys,
>>>>
>>>> I'm still digesting this, but one thing we for sure need: tenant-based
>>>> OIDC configuration.
>>>>
>>>> I think it's naive to think that a single OIDC configuration will be
>>>> fine for all tenants at once. We need to be able to configure the different
>>>> OIDC providers (even if they are different Keycloak realms) based on
>>>> tenants.
>>>> If you think about it, this is the same thing as we have today with
>>>> Fineract with the internal user authentication. The users are different for
>>>> each tenant.
>>>>
>>>> Alberto, does your change account for this?
>>>>
>>>> Thanks,
>>>> Best,
>>>> Arnold
>>>>
>>>> Arnold Gálovics
>>>>
>>>> *CEO, Co-Founder*
>>>>
>>>> *+36 30 904 1885*
>>>>
>>>> https://docktape.com
>>>>
>>>> Docktape Technologies
>>>>
>>>>
>>>>
>>>>
>>>> On Thu, May 28, 2026 at 7:30 PM Jose Alberto Hernandez <
>>>> [email protected]> wrote:
>>>>
>>>>> Adam, thanks for the feedback and comments.
>>>>>
>>>>> About the Auto User creation, one suggestion, we can allow the User
>>>>> creation, but someone else will need to enable the user, as kind of 
>>>>> approve
>>>>> control.
>>>>>
>>>>> And for the IdP options for now It was tested with Google and
>>>>> KeyCloak, we can test more, the main idea on this implementation is try to
>>>>> be IdP agnostic, to avoid to have custom implementations
>>>>>
>>>>> BTW. We can Include in the Vote the initial list of the IdP vendors to
>>>>> be avallable
>>>>>
>>>>> Thanks
>>>>> Best Regards
>>>>> Alberto
>>>>>
>>>>> On Thu, May 28, 2026 at 5:24 AM Ádám Sághy <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Hi Alberto,
>>>>>>
>>>>>>
>>>>>> Thank you for the proposal and the initial information.
>>>>>>
>>>>>>
>>>>>> Before we proceed with voting, I’d like to clarify a few points:
>>>>>>
>>>>>>
>>>>>> *Automated User and Role Assignment*
>>>>>>
>>>>>>
>>>>>> I’m not particularly fond of the idea of automating user creation and
>>>>>> role assignments.
>>>>>>
>>>>>>
>>>>>> I can’t help but wonder how it could be abused if enabled or why we
>>>>>> should even have something like that for Fineract.
>>>>>>
>>>>>>
>>>>>> I understand the convenience it offers, but I believe we need to be
>>>>>> strict and explicit in implementing multiple validations to prevent
>>>>>> accidental privilege escalation or ensuring those who shouldn’t have 
>>>>>> access
>>>>>> are not granted access to Apache Fineract.
>>>>>>
>>>>>>
>>>>>> Considering Fineract is a core financial system, access and roles
>>>>>> should be limited and strictly audited. I simply don’t see the need for
>>>>>> automation in registering users and providing access.
>>>>>>
>>>>>>
>>>>>> I wonder what the community thinks about this.
>>>>>>
>>>>>>
>>>>>> *Lookup by username vs email address*
>>>>>>
>>>>>>
>>>>>> This part looks fine, we can have multiple unique identifiers to look
>>>>>> up and map JWT token holder to Fineract user account, but again, we need 
>>>>>> to
>>>>>> make sure the validation and look up methods are straightforward and
>>>>>> explicit.
>>>>>>
>>>>>>
>>>>>> *Multiple providers are listed*
>>>>>>
>>>>>>
>>>>>> While I am okay to support multiple providers, but implementation
>>>>>> wise, I don’t think we should target more than 1 or 2 at first, and the
>>>>>> rest can be implemented based on need. I don’t want to introduce custom
>>>>>> implementations into the system without maintainers who are interested in
>>>>>> keeping up to date and using it in production.
>>>>>>
>>>>>>
>>>>>> What do you think?
>>>>>>
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Adam
>>>>>>
>>>>>>
>>>>>> On May 26, 2026, at 3:22 AM, Jose Alberto Hernandez <
>>>>>> [email protected]> wrote:
>>>>>>
>>>>>>   Hello Fineract community,
>>>>>>
>>>>>>   I would like to open a vote on FINERACT-2616: OIDC Federation
>>>>>> Support for External Identity Providers
>>>>>> <https://issues.apache.org/jira/browse/FINERACT-2616>
>>>>>>
>>>>>>   This allows organizations with an existing corporate IdP (Keycloak,
>>>>>> Google Workspace, Azure AD, Okta, Auth0) to enable SSO without forking
>>>>>> authentication logic or maintaining a parallel user database. The feature
>>>>>> is fully opt-in (*fineract.security.oidc-federation.enabled=true*)
>>>>>> and does not affect existing Basic Auth or OAuth2 deployments.
>>>>>>
>>>>>>   Fineract PR raised <https://github.com/apache/fineract/pull/5883>
>>>>>>
>>>>>>   ---
>>>>>>   The core of this contribution is *OidcAppUserResolutionServiceImpl*,
>>>>>> which bridges an external OIDC identity to a Fineract AppUser using a 
>>>>>> *three-step
>>>>>> strategy* on every authenticated request:
>>>>>>
>>>>>>   1. *Lookup by username* — using the configured usernameClaim
>>>>>> (default: preferred_username)
>>>>>>   2. *Fallback by email *— matches users pre-existing in Fineract by
>>>>>> their corporate email
>>>>>>   3. *Auto-creation* — when enabled via
>>>>>> *fineract.security.oidc-federation.auto-create-**user=true*,
>>>>>> provisions a new *AppUser* on first login, assigned to the head
>>>>>> office with the configured defaultRoles merged with any roles extracted
>>>>>> from the OIDC token. Throws *OidcUserNotFoundException* when
>>>>>> auto-create is disabled and no match is found.
>>>>>>   ---
>>>>>>   Please vote:
>>>>>>
>>>>>>   [ ] +1  approve
>>>>>>   [ ] +0  no objection
>>>>>>   [ ] -1  object because:
>>>>>>
>>>>>>   Thank you,
>>>>>>   Jose Alberto Hernandez
>>>>>>
>>>>>>
>>>>>>

Reply via email to