Rethinking Authentication and Authorization in a Multi-Component Platform with OIDC
Modern platforms rarely consist of a single application. Instead, they are ecosystems: monitoring, logging, visualization, ITSM, and a fair amount of glue holding everything together.
In environments like NetEye, this translates into components such as Icinga 2 and Icinga Web 2 (along with all of their custom modules), Grafana, Elasticsearch/Kibana, GLPI, and more. Each of these tools brings value and, inevitably, its own idea of authentication and authorization.
At some point, “it works” stops being good enough and just become madness.
The Current Model: One Client to Rule Them All
Today, authentication is already centralized using Keycloak and OIDC. That may sound like the end of the story – but it isn’t.
In practice, only Icinga Web 2 acts as the OIDC client. All other components sit behind it and are accessed via proxy (specifically, PHP-FPM). This creates a model where:
Users authenticate once through Keycloak
Icinga Web 2 handles the session
Other services are accessed indirectly through it
At a glance, this looks like a clean single entry point.
In reality, it introduces a subtle but significant constraint: The entire platform depends on one application acting as a gateway.
Here’s an example of communication (in this case Grafana) in a sequence diagram:
The Hidden Cost of a Gateway-Centric Design
Using Icinga Web 2 as the central access point has a few side effects:
Single point of failure: If PHP-FPM or Icinga Web 2 is down, access to multiple services is impacted
Tight coupling between unrelated components: The monitoring UI becomes the access layer for logging, dashboards, and more
Limited scalability of integrations: Every new service needs to be integrated through the same gateway
Blurry responsibility boundaries: Icinga Web 2 handles authentication, session management, and indirectly influences authorization
This isn’t just a technical limitation – it’s an architectural one. And it becomes more visible as the number of integrated components grows.
Authentication Is Centralized – Authorization Is Not
Even with Keycloak in place, authorization remains fragmented:
Some permissions are defined in Icinga Web 2
Others live inside individual applications (e.g., Kibana roles)
There’s no consistent mapping of “who can do what” across the platform
OIDC answers the question:
“Who is the user?”
But not:
“What should this user be allowed to do everywhere?”
Without a shared model, each application interprets identity differently, and consistency quickly disappears.
The Evolution: From Gateway to Distributed OIDC Clients
The natural next step is to move away from the “single OIDC client + proxy” model toward a distributed OIDC architecture.
Instead of:
One client (Icinga Web 2)
Many proxied services
We move to:
Each application acts as its own OIDC client
All applications authenticate directly against Keycloak
This changes the access pattern fundamentally, no central gateway required!
And importantly: No shared failure domain for authentication flows
OK Fine, Looks Good on Paper, But What Do I Do Now?
Once each component becomes an independent OIDC client, we can properly separate concerns:
Authentication (AuthN) → handled by Keycloak
Authorization (AuthZ) → also centralized, but explicitly designed
That’s where centralized RBAC comes into play.
Rethinking Authorization: Beyond Keycloak Roles
At this point, a natural idea is to centralize everything inside Keycloak: Define roles there, assign them to users or groups, and propagate them via OIDC claims.
This works well – up to a point.
However, in a platform composed of many heterogeneous components, this approach starts to show its limits. Authorization is no longer just a matter of assigning static roles; it becomes a problem of composition, mapping, and evolution.
And that’s not what Keycloak is primarily designed for: Keycloak excels at identity management and token issuance. It can also handle roles, but when those roles become:
Numerous
Application-specific
Dependent on external groups
Subject to frequent changes
the model quickly becomes difficult to maintain.
In particular:
Roles tend to drift toward application-specific definitions
Mapping AD groups to platform roles becomes complex
Cross-application consistency is hard to enforce
Evolving the model requires changes inside the identity provider
In short, Keycloak risks becoming a bottleneck, not technically, but conceptually.
An Interesting Idea: An External Role Manager
A more scalable approach is to decouple authorization from identity. Instead of embedding all role logic inside Keycloak, we introduce a dedicated component: an external role manager responsible for defining and resolving permissions across the platform.
This component becomes the single source of truth for authorization.
Its responsibilities include:
Managing roles and permissions
Mapping users and groups (from AD) to platform roles
Handling role hierarchies and composition
Translating platform roles into application-specific access models
Keycloak, in this model, doesn’t disappear: it becomes simpler and more focused.
And here we have the same example of communication with Grafana as before, but following the new model:
The New Responsibility Split
The architecture becomes clearer when responsibilities are separated:
Upstream IdP (e.g., AD): Source of users and groups
Keycloak: Authentication broker and token issuer
External Role Manager: Authorization engine and policy source
Applications: Enforcement points
Each component does one thing and (hopefully) does it well.
What This Architecture Enables
Moving authorization out of Keycloak and into a dedicated service unlocks several advantages.
True Separation of Concerns: Identity, authentication, and authorization are no longer mixed in the same component
Consistent Authorization Across Services: All roles and permissions are defined in one place and applied uniformly
Flexibility in Role Design: The authorization model can evolve without being constrained by identity provider structures
Reduced Coupling: Applications no longer depend on a gateway or on shared role definitions embedded in multiple places
Future-Proofing: New services can be integrated by simply connecting them to Keycloak and mapping existing roles or creating new ones without redesigning the authorization model each time
Conclusion
Centralizing authentication with OIDC is an important first step, but in complex platforms it’s not enough.
Relying on a single OIDC client and embedding authorization logic across multiple components leads to tight coupling and inconsistent behavior, while moving toward:
Distributed OIDC clients
A clear separation between authentication and authorization
An external role manager as the source of truth for permissions
all while providing a more scalable and maintainable architecture.
And perhaps most importantly, it allows each part of the system to focus on its actual job, instead of quietly accumulating responsibilities it was never meant to handle.
These Solutions are Engineered by Humans
Did you find this article interesting? Does it match your skill set? Programming is at the heart of how we develop customized solutions. In fact, we’re currently hiring for roles just like this and others here at Würth IT Italy.
Welcome back for the second and last part of our journey into the jungle of Windows logs! In the first part we set out our goal – tracking admin authentications – and learned more about Windows, how authentication events are Read More
If you've ever worked with Windows authentication logs, you know they can be a chaotic mess. Even when you’re looking for something apparently simple and useful – like tracking admin logins – you quickly find yourself in a sea of Read More
After updating to NetEye version 4.38 and activating authentication via Keycloak, the Icinga Director Self Service API no longer works. For instance if you install the Icinga agents using a Powershell script that automatically creates the host objects in the Read More
It's really easy now to activate OTP on your personal account with NetEye with our new authentication method. In the latest 4.38 version of NetEye we've introduced a new product to manage authentication (documentation here). In the future thanks to Read More
We all know that NetEye can grant access to its Web Interface through local users, or through the use of LDAP queries that can filter and grant GUI access to users or groups of a given Active Directory domain. What Read More