Skip to content

docs: Add OAUTH authentication module documentation#136

Open
Copilot wants to merge 13 commits intomasterfrom
copilot/add-oauth-documentation
Open

docs: Add OAUTH authentication module documentation#136
Copilot wants to merge 13 commits intomasterfrom
copilot/add-oauth-documentation

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 26, 2026

  • Examine existing documentation structure and actual Admin UI
  • Replace the two OAUTH tables (module-level + resolver-level) with Basic Properties and Advanced Properties tables that exactly match the Admin UI sections and the OPENAM_SESSION 4-column format
  • Update copyright notice in modified file to Portions Copyright 2024-2026 3A Systems LLC.
Original prompt

Task

Add documentation for the OAUTH authentication module to the integrators guide. This module is fully implemented in the codebase but is completely absent from the current documentation (chap-auth.adoc and appendix-auth-modules.adoc).

Background

The OAUTH module is implemented in:

  • openidm-authnfilter/src/main/java/org/forgerock/openidm/auth/modules/oauth/OAuthModule.java — core module implementation
  • openidm-authnfilter/src/main/java/org/forgerock/openidm/auth/AuthenticationService.java — generated dynamically from SOCIAL_PROVIDERS template or configured explicitly
  • openidm-ui/openidm-ui-admin/src/main/js/org/forgerock/openidm/ui/admin/authentication/modules/OAUTH.js — Admin UI view
  • openidm-ui/openidm-ui-admin/src/main/resources/templates/admin/authentication/modules/OAUTH.html — Admin UI template
  • Test configs: openidm-authnfilter/src/test/resources/config/amendedAuthentication.json
  • UI translation strings (translation.json) describe it as: "Generic OAuth 2.0 access_token validation"

How it works (from code analysis)

The OAUTH module authenticates users via a generic OAuth 2.0 provider. Unlike OPENID_CONNECT, it does NOT use JWT identity tokens — it validates an OAuth 2.0 access_token by calling the provider's userinfo_endpoint. It uses two HTTP headers: one for the token itself, and one to identify which configured resolver (provider) should validate the token. This allows a single module instance to support multiple OAuth providers simultaneously.

Key implementation details from OAuthModule.java:

  • authTokenHeader — HTTP header carrying the OAuth access token (required, throws AuthenticationException if missing)
  • authResolverHeader — HTTP header identifying the provider name to use for validation (required)
  • resolvers — list of OAuth provider configurations; service validates token against the named resolver

Key properties extracted from code and templates:

  • authTokenHeader — HTTP header name for the OAuth token (e.g., authToken)
  • authResolverHeader — HTTP header name for the provider selector (e.g., provider)
  • queryOnResource — managed object resource to query after token validation (e.g., managed/google)
  • resolvers — array of provider configurations, each with:
    • name — unique resolver name (must match value sent in authResolverHeader)
    • type — always OAUTH
    • client_id / client_secret
    • authorization_endpoint
    • token_endpoint
    • userinfo_endpoint
    • scope — list of OAuth scopes
    • authenticationId — attribute from userinfo response used as user ID (e.g., _id, sub)
    • propertyMap — array of {source, target} mappings from provider attributes to managed object attributes
    • icon — HTML for the social login button
    • enabled — whether this resolver is active
  • propertyMapping.authenticationId — maps the provider identity attribute to OpenIDM identity
  • propertyMapping.userRoles — maps to OpenIDM roles (usually authzRoles)
  • defaultUserRoles — roles assigned on successful authentication
  • augmentSecurityContext — optional script to run post-authentication

Example configuration (from amendedAuthentication.json):

{
    "name" : "OAUTH",
    "enabled" : true,
    "properties" : {
        "augmentSecurityContext": {
            "type" : "text/javascript",
            "file" : "auth/populateAsManagedUserFromRelationship.js"
        },
        "propertyMapping" : {
            "userRoles" : "authzRoles",
            "authenticationId" : "_id"
        },
        "defaultUserRoles" : [
            "openidm-authorized"
        ],
        "resolvers" : [
            {
                "name" : "oauth",
                "type" : "OAUTH",
                "icon" : "<button class=\"btn btn-lg btn-default btn-block btn-social-provider\"><img src=\"images/provider.png\">Sign in with Provider</button>",
                "scope" : ["foo", "bar"],
                "authenticationId" : "_id",
                "propertyMap" : [
                    {
                        "source" : "source",
                        "target" : "target"
                    }
                ],
                "enabled" : true,
                "client_id" : "your-client-id",
                "client_secret" : "your-client-secret",
                "authorization_endpoint" : "https://provider.example.com/oauth2/authorize",
                "token_endpoint" : "https://provider.example.com/oauth2/access_token",
                "userinfo_endpoint" : "https://provider.example.com/oauth2/userinfo"
            }
        ],
        "queryOnResource" : "managed/oauth",
        "authTokenHeader" : "authToken",
        "authResolverHeader" : "provider"
    }
}

Key Difference from OPENID_CONNECT

The OAUTH module validates a plain OAuth 2.0 access_token (not a JWT/ID token). It requires two request headers: one with the token, and one naming the provider resolver. This allows mul...

This pull request was created from Copilot chat.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add documentation for OAUTH authentication module docs: Add OAUTH authentication module documentation Mar 26, 2026
Copilot AI requested a review from vharseko March 26, 2026 16:51
@vharseko vharseko requested review from Copilot and maximthomas March 26, 2026 16:53
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds missing integrator documentation for the existing OAUTH authentication module, including an overview in the authentication chapter and a configuration-options appendix section.

Changes:

  • Adds a new OAUTH:: entry to the “Supported Authentication Modules” list, including behavior notes and a sample configuration.
  • Adds a new appendix section documenting OAUTH module-level and resolver-level configuration properties.
  • Cross-links the chapter entry and the appendix section for discoverability.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
openidm-doc/src/main/asciidoc/integrators-guide/chap-auth.adoc Introduces the OAUTH module in the supported-modules list and provides a sample configuration + appendix xref.
openidm-doc/src/main/asciidoc/integrators-guide/appendix-auth-modules.adoc Adds an OAUTH configuration reference section with module/resolver property tables and cross-reference back to the chapter.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

In this section, the bullets read as if the literal HTTP header names are authTokenHeader and authResolverHeader, but those are configuration property keys. The actual request header names are whatever values you configure for those properties (for example, authToken and provider in the sample). Please reword to avoid readers sending the wrong header names.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +514 to +525
{
"name" : "myProvider",
"type" : "OAUTH",
"icon" : "<button class=\"btn btn-lg btn-default btn-block btn-social-provider\"><img src=\"images/provider.png\">Sign in with Provider</button>",
"scope" : ["profile", "email"],
"authenticationId" : "sub",
"propertyMap" : [
{
"source" : "sub",
"target" : "userName"
}
],
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The sample mixes two different “identity” fields without explaining how they relate: resolver authenticationId/propertyMap.source uses sub, but propertyMapping.authenticationId is set to _id while the mapped managed attribute target is userName. This makes it unclear which managed attribute is intended to be the effective authentication identifier. Consider aligning the example (e.g., set propertyMapping.authenticationId to userName if that’s the mapped identifier) and/or adding a short note explaining the distinction between resolver authenticationId (userinfo response field) and propertyMapping.authenticationId (managed object field).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 80818d2propertyMapping.authenticationId is already "userName" (consistent with the propertyMap target userName), and added a note after the sample explaining that authenticationId means different things at the two levels: inside resolvers[] it refers to the provider's userinfo response field (e.g., sub), while at propertyMapping level it refers to the managed object attribute used as the authentication identifier (e.g., userName).

Comment on lines +325 to +327
a|`propertyMapping.authenticationId`
a|Authentication ID
a|Attribute in the managed object used as the user identifier.
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The appendix defines two different fields named “authenticationId” at different levels, but doesn’t explicitly state that they refer to different sources (managed object attribute vs. userinfo response attribute). Adding a brief clarification (or renaming the description wording to explicitly call out “managed object attribute” vs “provider userinfo attribute”) would prevent misconfiguration—especially since both are labeled “user identifier.”

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot apply changes based on this feedback

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 67d1349 — updated the propertyMapping.authenticationId description in the module-level table to explicitly state it is the managed object attribute (e.g., userName) used when querying queryOnResource, and that it is distinct from the resolver-level authenticationId which names the field in the provider's userinfo endpoint response.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…modules.adoc

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@vharseko vharseko requested a review from Copilot March 26, 2026 18:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

a|Provider's userinfo endpoint URL. The access token is validated by calling this endpoint.

a|`scope`
a|List of OAuth 2.0 scopes to request (for example, `["openid", "profile", "email"]`).
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example scope includes openid, which is typically associated with OpenID Connect. Since this section explicitly distinguishes OAUTH from OPENID_CONNECT, consider using a non-OIDC example (for example, ["profile", "email"]) to avoid confusing readers.

Suggested change
a|List of OAuth 2.0 scopes to request (for example, `["openid", "profile", "email"]`).
a|List of OAuth 2.0 scopes to request (for example, `["profile", "email"]`).

Copilot uses AI. Check for mistakes.
}
----
+
Note that `authenticationId` appears at two different levels with different meanings: inside each `resolvers[]` entry it names the field in the provider's userinfo response that identifies the user (for example, `sub`); at the `propertyMapping` level it names the attribute in the managed object (for example, `userName`) that OpenIDM uses as the authentication identifier after the userinfo fields have been mapped via `propertyMap`.
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This note explains the distinction well, but it doesn’t explicitly state the required relationship between these fields. Consider adding a short, explicit constraint (for example: the resolver-level authenticationId userinfo field should be included in propertyMap and mapped into the managed-object attribute referenced by propertyMapping.authenticationId) so readers don’t end up with a configuration that can’t correlate the user to queryOnResource.

Suggested change
Note that `authenticationId` appears at two different levels with different meanings: inside each `resolvers[]` entry it names the field in the provider's userinfo response that identifies the user (for example, `sub`); at the `propertyMapping` level it names the attribute in the managed object (for example, `userName`) that OpenIDM uses as the authentication identifier after the userinfo fields have been mapped via `propertyMap`.
Note that `authenticationId` appears at two different levels with different meanings: inside each `resolvers[]` entry it names the field in the provider's userinfo response that identifies the user (for example, `sub`); at the `propertyMapping` level it names the attribute in the managed object (for example, `userName`) that OpenIDM uses as the authentication identifier after the userinfo fields have been mapped via `propertyMap`. The resolver-level `authenticationId` userinfo field must therefore be included in `propertyMap` and mapped into the managed-object attribute referenced by `propertyMapping.authenticationId`, so that OpenIDM can correlate the resolved user to the `queryOnResource` entry.

Copilot uses AI. Check for mistakes.
@vharseko
Copy link
Copy Markdown
Member

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 26, 2026

@copilot apply changes based on the comments in this thread

Done in bab62db:

  • Changed the scope example in the appendix resolver table from ["openid", "profile", "email"] to ["profile", "email"] to avoid implying OpenID Connect semantics in the generic OAUTH module docs.
  • Expanded the authenticationId note in chap-auth.adoc to explicitly state that the resolver-level authenticationId userinfo field must be included in propertyMap and mapped into the managed-object attribute referenced by propertyMapping.authenticationId, so that OpenIDM can correlate the resolved user to the queryOnResource entry.

@vharseko vharseko marked this pull request as ready for review March 27, 2026 05:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants