Bringing Microsoft Entra ID SSO to IBM FileNet, ACCE and Content Services GraphQL
When we talk about Single Sign-On, the discussion often starts with a simple requirement:
“We want users to log in with Microsoft Entra ID.”
On paper, that sounds straightforward. In practice, when IBM FileNet is involved, the topic quickly becomes more interesting.
FileNet is not just a web application. It is a platform made of several components: Content Platform Engine, ACCE, IBM Content Navigator, Content Services GraphQL, WebSphere security, LTPA tokens, directory configurations, user short names, groups, service accounts and backend calls.
So the real question is not only:
“How do I redirect users to Entra ID?”
The real question is:
“How do I make Entra ID, WebSphere, FileNet authorization and GraphQL work together without breaking the identity chain?”
This article walks through the architecture and the key configuration points we used to implement SSO between Microsoft Entra ID, IBM FileNet Content Platform Engine, ACCE, IBM Content Navigator and IBM Content Services GraphQL on traditional WebSphere Application Server.
The target architecture
The implementation pattern is based on a fairly common enterprise setup:
-
Microsoft Entra ID is the identity provider.
-
WebSphere Application Server acts as the OpenID Connect relying party.
-
ACCE and Content Platform Engine run on one WebSphere environment.
-
IBM Content Navigator and Content Services GraphQL run on another WebSphere environment.
-
LTPA is used to propagate the authenticated identity between WebSphere environments.
-
Keycloak, provisioned from Entra ID, exposes users and groups through SCIM.
-
FileNet CPE uses the SCIM directory to resolve users and groups for authorization.
-
GraphQL calls CPE through the internal WSI endpoint, not through the public VIP.
The important part is this: authentication and authorization are not handled by the same layer.
Entra ID authenticates the user. WebSphere establishes the authenticated web session. FileNet still needs to resolve that user and their groups before it can authorize access to object stores, classes, documents, folders or administration functions.
A simplified view looks like this:
User Browser
|
| HTTPS
v
VIP / Reverse Proxy / IHS
|
+--------------------------+
| |
v v
WebSphere CPE / ACCE WebSphere ICN / GraphQL
OIDC RP TAI OIDC RP TAI
| |
+----------- LTPA ---------+
|
v
FileNet Content Platform Engine
|
| SCIM user and group lookup
v
Keycloak SCIM
|
v
Microsoft Entra ID
This is the design goal: every component sees the same user identity, and FileNet can still apply its own security model correctly.
The following sequence diagram summarizes the end-to-end authentication and authorization flow. The most important point is the separation between the browser-facing SSO flow and the backend FileNet communication. OIDC callbacks go through the VIP because they are browser redirects, while GraphQL uses the internal CPE WSI endpoint for server-to-server communication. FileNet authorization remains delegated to the SCIM directory, where CPE resolves the authenticated user and their group memberships.

First lesson: SSO is not authorization
A successful Entra ID login does not automatically mean that FileNet knows what the user is allowed to do.
That distinction is critical.
In this architecture:
Entra ID proves who the user is.
WebSphere accepts the OIDC token and creates the authenticated Java EE subject.
LTPA allows the authenticated identity to be reused between WebSphere applications.
FileNet CPE performs authorization based on its directory configuration.
SCIM through Keycloak provides the user and group information required by FileNet.
That means the username returned by Entra ID must match what FileNet can retrieve through SCIM. If the values do not align, the login may succeed, but the user will not be correctly authorized in FileNet.
This is one of the most important design points of the whole setup.
Choose one canonical username
Before touching WebSphere, Entra ID or FileNet, decide which username will be used everywhere.
In many Microsoft Entra ID environments, the most natural value is the user’s UPN:
firstname.lastname@company.com
The same value should be visible in all layers:
Entra ID claim firstname.lastname@company.com
WebSphere authenticated ID firstname.lastname@company.com
Keycloak SCIM userName firstname.lastname@company.com
FileNet short name firstname.lastname@company.com
For FileNet SCIM, this also means enabling support for email-style short names when required.
In practice, the goal is simple:
The user authenticated by WebSphere must be the same user that FileNet can find through SCIM.
This also applies to technical users. If you need a CPE system user or service account authenticated locally by WebSphere, its username must also exist in Keycloak or in the directory used by FileNet for authorization.
The password does not necessarily have to be the same everywhere, but the username must match.
Register the Entra ID application
On the Entra ID side, you need one or more App Registrations.
There are two possible patterns.
Option 1: one shared App Registration
This is the easiest to operate. You use one client ID and one secret, then register multiple redirect URIs for ACCE, ICN and GraphQL.
Example:
https://filenet.company.com/oidcclientCPE/EntraID
https://filenet.company.com/oidcclientICN/EntraID
https://filenet.company.com/oidcclientGQL/EntraID
Option 2: one App Registration per component
This is cleaner from a governance perspective. You create one application for CPE/ACCE, one for ICN, and one for GraphQL.
That gives you better separation, easier secret rotation and clearer ownership.
Both options are valid. What matters is that the redirect URIs are exact.
No approximation. No private hostname if the browser cannot reach it. No wrong port. No missing context root.
Callback URL: use the VIP, not the private WebSphere URL
This is a common source of confusion.
The OIDC callback is not a server-to-server call from Microsoft Entra ID to WebSphere. It is a browser redirect.
After authentication, Entra ID sends the user’s browser back to the redirect URI.
So the callback URL must be reachable by the user’s browser.
In most enterprise architectures, that means the callback must go through the VIP, reverse proxy or IHS layer.
Correct pattern:
https://filenet.company.com/oidcclientICN/EntraID
Usually wrong:
https://was-private-host.internal:9443/oidcclientICN/EntraID
The private WebSphere URL still has a role. It is useful for backend communication, for example when Content Services GraphQL calls CPE through the internal WSI endpoint.
But for browser-based OIDC callbacks, use the same front door as the users.
That keeps the flow consistent:
User browser -> VIP -> WebSphere -> Entra ID -> VIP callback -> WebSphere
Configure WebSphere as an OIDC relying party
On WebSphere traditional, the usual approach is to configure the OpenID Connect Relying Party Trust Association Interceptor.
The TAI class is:
com.ibm.ws.security.oidc.client.RelyingParty
You also need the WebSphere OIDC RP application, usually installed with a callback context such as:
/oidcclient
In a multi-component architecture, I prefer using distinct callback contexts. It makes the setup easier to read and easier to troubleshoot.
For example:
/oidcclientCPE
/oidcclientICN
/oidcclientGQL
That gives you clean redirect URIs and avoids ambiguity when several WebSphere clusters or servers are exposed through the same VIP.
Example OIDC properties for ACCE and CPE
For the CPE / ACCE WebSphere environment, the configuration can look like this:
provider_1.identifier=EntraID
provider_1.clientId=<entra-client-id>
provider_1.clientSecret=<entra-client-secret>
provider_1.discoveryEndpointUrl=https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration
provider_1.callbackServletContext=/oidcclientCPE
provider_1.redirectToRPHostAndPort=https://filenet.company.com
provider_1.userIdentifier=preferred_username
provider_1.useRealm=WAS_DEFAULT
provider_1.createSession=true
provider_1.interceptedPathFilter=/acce.*|/FileNet.*|/P8CE.*
A few comments from the field:
-
identifier is part of the callback URL.
-
callbackServletContext must match the deployed OIDC RP application context.
-
redirectToRPHostAndPort is important behind a reverse proxy or VIP.
-
userIdentifier must be aligned with the username expected by FileNet and SCIM.
-
interceptedPathFilter should be adapted to your deployed context roots.
Do we need OIDC on ICN as well?
Technically, LTPA can be enough if the user always authenticates first on the CPE/ACCE WebSphere environment and then accesses ICN.
But in real life, users usually enter through IBM Content Navigator.
So yes, in most cases, ICN should also be configured as an OIDC relying party.
Otherwise, a user who opens ICN directly may not be redirected to Entra ID. They may get a WebSphere login page, or the flow may simply not behave as expected.
For ICN, the configuration is similar:
provider_1.identifier=EntraID
provider_1.clientId=<entra-client-id>
provider_1.clientSecret=<entra-client-secret>
provider_1.discoveryEndpointUrl=https://login.microsoftonline.com/<tenant-id>/v2.0/.well-known/openid-configuration
provider_1.callbackServletContext=/oidcclientICN
provider_1.redirectToRPHostAndPort=https://filenet.company.com
provider_1.userIdentifier=preferred_username
provider_1.useRealm=WAS_DEFAULT
provider_1.createSession=true
provider_1.interceptedPathFilter=/navigator.*
This allows ICN to be a first entry point into the platform.
The same logic applies to GraphQL if users, tools or applications access it directly.
Where LTPA fits in
OIDC handles authentication against Entra ID.
LTPA handles SSO between WebSphere applications.
That means LTPA is still essential.
In our scenario, CPE/ACCE and ICN/GraphQL run on different WebSphere environments. To make SSO work correctly between them, the LTPA configuration must be aligned.
At a minimum, check:
-
LTPA keys are shared or imported where needed.
-
The LTPA cookie domain matches the application DNS strategy.
-
The applications are accessed using compatible hostnames.
-
Session affinity is enabled at the load balancer or reverse proxy.
-
The token timeout is aligned with the expected user session duration.
A very common mistake is to configure OIDC correctly, but forget that ICN or GraphQL still needs to talk to CPE with a valid authenticated identity.
OIDC gets the user in.
LTPA keeps the identity flowing.
GraphQL deserves special attention
Content Services GraphQL is not the repository itself. It is an API layer in front of Content Platform Engine.
That means there are two authentication paths to think about.
1. User or application to GraphQL
If GraphQL is accessed directly, it must be able to authenticate the caller.
For browser-based usage, that can be handled by WebSphere OIDC RP.
For API usage, you may also have bearer token scenarios, where you validate Entra ID tokens directly. In that case, pay special attention to:
issuer
audience
signing keys
token lifetime
user identity claim
scope or delegated permission
The audience check is especially important. A token issued for another application should not be accepted just because it comes from the same Entra ID tenant.
2. GraphQL to CPE
After GraphQL authenticates the caller, it still needs to call CPE.
In the architecture described here, GraphQL calls CPE through the internal WSI endpoint:
https://cpe-internal.company.local:9443/wsi/FNCEWS40MTOM/
This is intentionally not the VIP.
The VIP is for browser-facing traffic.
The internal WSI URL is for backend component-to-component communication.
This separation keeps the architecture cleaner and avoids sending internal FileNet traffic through unnecessary external layers.
For this part, LTPA propagation and the FileNet WSI authentication settings are key. Depending on the design, you may need to ensure that the GraphQL runtime can detect and forward the correct authentication token when calling CPE.
What about the CPE system user?
There is one special case that is worth calling out: the CPE system user.
When creating the P8 domain, FileNet needs a system user. In some environments, especially when the primary human authentication flow is OIDC, you may still need a username and password that WebSphere can authenticate directly.
A practical approach is to create a local WebSphere user, or an LDAP user if WebSphere is connected to LDAP, with the same username as the one exposed through SCIM.
For example:
WebSphere local user cpe_system_user@company.com
Keycloak SCIM userName cpe_system_user@company.com
FileNet short name cpe_system_user@company.com
WebSphere authenticates the credentials.
FileNet authorizes the user through SCIM.
The password used in WebSphere does not have to be the same as the Entra ID password. But be careful: the same username may authenticate differently depending on the entry point.
Browser login goes through Entra ID.
Username/password API login goes through WebSphere.
That difference must be understood and documented.
SCIM: the missing piece for FileNet authorization
Once the user is authenticated, FileNet must be able to resolve that user and their group memberships.
This is where the SCIM directory configuration comes in.
The SCIM endpoint, exposed here by Keycloak, must return:
-
the user, using the same username as WebSphere;
-
the user’s groups;
-
nested group membership if your security model depends on it.
This is where many SSO projects fail quietly.
The login works. The session exists. The user reaches the application. But FileNet cannot find the user or the expected groups, so permissions do not behave as expected.
The first troubleshooting step should always be simple:
Can FileNet resolve this exact username through SCIM?
Then:
Does SCIM return the groups expected by FileNet security?
Only after those two questions are answered does it make sense to troubleshoot ACLs, object store permissions or application configuration.
Practical troubleshooting checklist
When something does not work, I usually start with these checks.
Redirect problem
Symptoms:
AADSTS50011
redirect_uri mismatch
browser returns to the wrong host
Check:
Entra ID redirect URI
provider identifier
callbackServletContext
redirectToRPHostAndPort
VIP hostname
HTTP to HTTPS rewriting
User logs in but has no FileNet access
Symptoms:
login succeeds
ACCE or ICN opens
FileNet access denied
groups missing
Check:
OIDC userIdentifier claim
WebSphere authenticated username
SCIM userName
AllowEmailOrUPNShortNames
SCIM group lookup
nested groups
FileNet directory configuration
ICN works only after opening ACCE first
Symptoms:
ACCE login works
ICN direct access does not redirect to Entra ID
ICN shows WebSphere login
Check:
OIDC RP configured on ICN WebSphere
interceptedPathFilter for /navigator.*
callback URI registered for ICN
LTPA cookie domain
GraphQL cannot access CPE
Symptoms:
GraphQL authentication works
CPE calls fail
401 or authentication exceptions from WSI
Check:
GraphQL to CPE internal WSI URL
LTPA keys
token propagation
CPE WSI authentication settings
SSL trust between GraphQL and CPE
Final thoughts
The main lesson from this kind of implementation is that SSO is not a single checkbox.
With FileNet, SSO is an identity chain.
The browser authenticates with Entra ID. WebSphere accepts the OIDC token. LTPA propagates the WebSphere identity. FileNet resolves the user and groups through SCIM. GraphQL must preserve the identity when calling CPE.
If one link in that chain uses a different username, a different hostname, a different token audience or a different directory source, the whole experience becomes fragile.
The architecture becomes much easier to operate when a few principles are respected:
-
Use one canonical username across Entra ID, WebSphere, Keycloak SCIM and FileNet.
-
Register browser-facing callback URLs using the VIP, not private WebSphere hosts.
-
Configure OIDC on every component that can be a first user entry point.
-
Keep LTPA in place for cross-application SSO and backend propagation.
-
Use the internal CPE WSI URL for GraphQL to CPE communication.
-
Validate FileNet authorization through SCIM before troubleshooting ACLs.
-
Document the difference between browser SSO users and technical username/password users.
Once these rules are clear, the integration becomes predictable.
And that is exactly what we want from an enterprise content platform: secure authentication, consistent authorization and a user experience that feels simple, even when the architecture behind it is not.