Skip to content

Commit

Permalink
feat: support custom jwt assertion claim (#1401)
Browse files Browse the repository at this point in the history
  • Loading branch information
csmig authored Oct 14, 2024
1 parent f9cc74a commit 99f54b2
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 9 deletions.
2 changes: 2 additions & 0 deletions api/source/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion api/source/utils/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const verifyRequest = async function (req, requiredScopes, securityDefinition) {
if (!response?.statistics?.lastAccess || now - response?.statistics?.lastAccess >= config.settings.lastAccessResolution) {
refreshFields.lastAccess = now
}
if (!response?.statistics?.lastClaims || decoded.jti !== response?.statistics?.lastClaims?.jti) {
if (!response?.statistics?.lastClaims || decoded[config.oauth.claims.assertion] !== response?.statistics?.lastClaims?.[config.oauth.claims.assertion]) {
refreshFields.lastClaims = decoded
}
if (req.userObject.username && (refreshFields.lastAccess || refreshFields.lastClaims)) {
Expand Down
3 changes: 2 additions & 1 deletion api/source/utils/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ const config = {
name: process.env.STIGMAN_JWT_NAME_CLAIM || process.env.STIGMAN_JWT_USERNAME_CLAIM || "name",
privileges: formatChain(process.env.STIGMAN_JWT_PRIVILEGES_CLAIM || "realm_access.roles"),
privilegesPath: process.env.STIGMAN_JWT_PRIVILEGES_CLAIM || "realm_access.roles",
email: process.env.STIGMAN_JWT_EMAIL_CLAIM || "email"
email: process.env.STIGMAN_JWT_EMAIL_CLAIM || "email",
assertion: process.env.STIGMAN_JWT_ASSERTION_CLAIM || "jti"
}
},
log: {
Expand Down
12 changes: 6 additions & 6 deletions docs/installation-and-setup/authentication.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ The JWT produced by the Identity Provider should provide the claims specified be
* User Full Name - ``STIGMAN_JWT_NAME_CLAIM`` - (optional) **default:** ``name``
* User Email - ``STIGMAN_JWT_EMAIL_CLAIM`` - (optional) **default:** ``email``
* User Privileges - ``STIGMAN_JWT_PRIVILEGES_CLAIM`` - **default:** ``realm_access.roles``
* scope - OIDC standard. Use ``STIGMAN_CLIENT_EXTRA_SCOPES`` to specify additional scopes the client should request.
* Scope - ``STIGMAN_JWT_SCOPE_CLAIM`` **default:** ``scope``. Some OIDC Providers (Okta, Azure Entra ID) use the claim ``scp`` to enumerate scopes.
* Assertion ID - ``STIGMAN_JWT_ASSERTION_CLAIM`` **default** ``jti``. Some OIDC Providers (ADFS, Azure Entra ID?) use the claim ``uti`` instead of ``jti`` to protect against replay attacks.

.. note::
STIG Manager will use the value specified in the ``STIGMAN_JWT_USERNAME_CLAIM`` environment variable as the Claim that should hold a users unique username. This value defaults to the Keycloak default, which is ``preferred_username``
Expand Down Expand Up @@ -109,17 +110,16 @@ The **Roles** specified in the JWT map to Privileges in STIG Manager that allow

The **Scopes** specified in the JWT control access to API endpoints as specified in the OpenAPI spec. See the :ref:`STIG Manager Client Scopes and Roles <oidc-scopes-table>` table below for a suggestion on how to allocate these scopes using OIDC roles, and more information.



.. note::
The information provided below is just one way to configure Keycloak to provide a JWT that will work with STIG Manager. Please make sure you configure Keycloak in accordance with your organization's Security Policy.

If your OIDC Provider requires the STIG Manager Web App to request additional scopes when redirecting to the OIDC Provider, you can provide those as values to the envvar ``STIGMAN_CLIENT_EXTRA_SCOPES``. An example would be Okta, which requires the scope ``offline_access`` be requested in order to generate a refresh token.

.. _keycloak:

Authentication Example - RedHat Keycloak 19+
-------------------------------------------------------

.. note::
The information provided below is just one way to configure Keycloak to provide a JWT that will work with STIG Manager. Please make sure you configure Keycloak in accordance with your organization's Security Policy.

The web client is an OpenID Connect (OIDC) OAuth2 Relying Party and the API is an OAuth2 Resource Server. User authentication is provided by an external Identity Provider (IdP). All API access is controlled by OAUth2 JSON Web Tokens (JWTs) issued by the IdP. User roles are extracted from token claims, endpoint access is controlled by token scope.
Keycloak is readily available, actively maintained by a major OSS vendor, supports Identity Brokering and User Federation, and is used by major DoD projects such as Air Force Iron Bank.
Keycloak supports many External Identity Providers, but has only been tested using its own authentication.
Expand Down
4 changes: 3 additions & 1 deletion docs/installation-and-setup/envvars.csv
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"STIGMAN_CLIENT_DISABLED","| **Default** ``false``
| Whether to *not* serve the reference web client","Client"
"STIGMAN_CLIENT_EXTRA_SCOPES","| **No default**
| OAuth2 scopes to request in addition to ``stig-manager:stig`` ``stig-manager:stig:read`` ``stig-manager:collection`` ``stig-manager:user`` ``stig-manager:user:read`` ``stig-manager:op``. Some OIDC providers (Okta) generate a refresh token only if the scope ``offline_access`` is requested","Client"
| A space separated list of OAuth2 scopes to request in addition to ``stig-manager:stig`` ``stig-manager:stig:read`` ``stig-manager:collection`` ``stig-manager:user`` ``stig-manager:user:read`` ``stig-manager:op``. Some OIDC providers (Okta) generate a refresh token only if the scope ``offline_access`` is requested","Client"
"STIGMAN_CLIENT_ID","| **Default** ``stig-manager``
| The OIDC clientId of the web client","Client"
"STIGMAN_CLIENT_OIDC_PROVIDER","| **Default** Value of ``STIGMAN_OIDC_PROVIDER``
Expand Down Expand Up @@ -61,6 +61,8 @@
| Controls the granularity of the generated log output, from 1 to 4. Each level is inclusive of the ones before it. Level 1 will log only errors, level 2 includes warnings, level 3 includes status and transaction logs, and level 4 includes debug-level logs","API"
"STIGMAN_LOG_MODE","| **Default** ``combined``
| Controls whether the logs will create one “combined” log entry for http requests that includes both the request and response information; or two separate log entries, one for the request and one for the response, that can be correlated via a generated Request GUID in each entry","API"
"STIGMAN_JWT_ASSERTION_CLAIM","| **Default** ``jti``
| The access token claim whose value is the OIDC provider's Assertion ID. Updates to this value trigger the API to update a User's ``lastClaims`` property. The claim MUST be a top-level claim and cannot be nested.","API"
"STIGMAN_JWT_EMAIL_CLAIM","| **Default** ``email``
| The access token claim whose value is the user's email address","API, Client"
"STIGMAN_JWT_NAME_CLAIM","| **Default** ``name``
Expand Down

0 comments on commit 99f54b2

Please sign in to comment.