Skip to content

Commit

Permalink
backport of commit ae21ae5 (#25149)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Smithhisler <[email protected]>
  • Loading branch information
hc-github-team-nomad-core and mismithhisler authored Feb 18, 2025
1 parent de345fe commit ec8320c
Show file tree
Hide file tree
Showing 8 changed files with 286 additions and 10 deletions.
10 changes: 8 additions & 2 deletions nomad/acl_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -2792,9 +2792,15 @@ func (a *ACL) OIDCCompleteAuth(

internalClaimBytes, err := json.MarshalIndent(oidcInternalClaims.List, "", " ")
if err != nil {
vlog.Debug("failed to marshal OIDC internal claims list")
vlog.Debug("failed to marshal OIDC internal list claims")
}
vlog.Debug("claims after mapping to nomad identity attributes", "internal_claims", string(internalClaimBytes))
vlog.Debug("list claims after mapping to nomad identity attributes", "internal_claims", string(internalClaimBytes))

internalClaimBytes, err = json.MarshalIndent(oidcInternalClaims.Value, "", " ")
if err != nil {
vlog.Debug("failed to marshal OIDC internal value claims")
}
vlog.Debug("value claims after mapping to nomad identity attributes", "internal_claims", string(internalClaimBytes))
}

// Create a new binder object based on the current state snapshot to
Expand Down
4 changes: 2 additions & 2 deletions website/content/api-docs/task-api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ $ nomad node status -filter 'Meta.example == "Hello World!"'
- Using the Task API Unix Domain Socket on Windows [requires][windows] Windows
build 17063 or later.

[acl]: /nomad/docs/concepts/acl
[acl-tokens]: /nomad/docs/concepts/acl#token
[acl]: /nomad/docs/concepts/acl/
[acl-tokens]: /nomad/docs/concepts/acl/#token
[alloc-exec]: /nomad/docs/commands/alloc/exec
[anon]: /nomad/tutorials/access-control/access-control#acl-policies
[bind_addr]: /nomad/docs/configuration
Expand Down
36 changes: 36 additions & 0 deletions website/content/docs/concepts/acl/auth-methods/jwt.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
layout: docs
page_title: JSON Web Token (JWT) Auth Method
description: >-
Use the JWT auth method to authenticate to Nomad with a JSON web token and receive an ACL token with privileges based on JWT identity attributes. Learn how to configure the auth method parameters using this reference page and example configuration.
---

# JSON Web Token (JWT) Auth Method

Use the `jwt` auth method to authenticate with Nomad by providing a
[JWT](https://en.wikipedia.org/wiki/JSON_Web_Token) directly. The JWT is
cryptographically verified using locally-provided keys, or, if configured, you may use an
OIDC Discovery service to fetch the appropriate keys.

Refer to [auth-method create] for the parameters required to create a JWT auth-method with a given verification method.

## JWT Verification

Nomad verifies JWT signatures against public keys from the issuer. This
process uses one of these methods:

- **Static Keys** - A set of public keys is stored directly in the
configuration.

- **JWKS** - Configure a JSON Web Key Set ([JWKS](https://tools.ietf.org/html/rfc7517))
URL and optional certificate chain. Nomad fetches keys from
this endpoint during authentication.

- **OIDC Discovery** - Configure an OIDC Discovery URL and optional certificate chain. Nomad fetches keys from this URL during authentication. When you use OIDC Discovery, Nomad applies OIDC validation criteria such as `iss` and `aud`.

If you need multiple methods, create another auth method of this type
with a different name.

@include 'jwt_claim_mapping_details.mdx'

[auth-method create]: /nomad/docs/commands/acl/auth-method/create
117 changes: 117 additions & 0 deletions website/content/docs/concepts/acl/auth-methods/oidc.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
---
layout: docs
page_title: OpenID Connect (OIDC) Auth Method
description: >-
Use the OIDC auth method type to authenticate to Nomad through a web browser with an OpenID Connect provider. Learn how to configure the auth method parameters using this reference page and example configuration.
---

# OpenID Connect (OIDC) Auth Method

Use the `oidc` auth method to authenticate to Nomad with
[OIDC](https://en.wikipedia.org/wiki/OpenID_Connect). This method allows
authentication via a configured OIDC provider using the user's web browser.
Initiate this method from the Nomad UI or the command line.

## Prerequisites

- General knowledge of [OIDC concepts](https://developer.okta.com/blog/2017/07/25/oidc-primer-part-1)
- [Nomad Access Control List fundamentals][ACL Overview].

Refer to [auth-method create] for the parameters required to create an OIDC auth-method.

## JWT Verification

Nomad uses OIDC discovery to verify JWT signatures against public
keys from the issuer. Nomad first fetches keys from the OIDC
Discovery URL during authentication and then applies OIDC
validation criteria such as `iss` and `aud`.

## OIDC Authentication

Nomad includes two built-in OIDC login flows: the Nomad UI, and the CLI using
[`nomad login`](/nomad/docs/commands/login).

### Redirect URIs

Properly setting redirect URIs is an important part of OIDC auth method
configuration. You must configure these in both Nomad and the OIDC
provider, and these configurations must align.

Specify the redirect URIs for an auth method with the
`AllowedRedirectURIs` parameter in the auth method config. The Nomad UI
and CLI use different redirect URIs, so you need to configure one or both,
depending on your installation.

**Note:** Redirect URI is used interchangeably with callback address.

Logging in via the UI requires the redirect URI
`http://{host:port}/ui/settings/tokens`.

Logging in via the CLI requires the redirect
URI `http://{host:port}/oidc/callback`.

### OIDC Login

#### Nomad UI

1. Select one of the provider links in the Nomad homepage or navigate directly to `/ui/settings/tokens`.
1. Click one of the buttons for your OIDC auth method of choice.
1. Complete the authentication with the configured provider.

#### CLI

Execute the `nomad login -method=oidc` command to log in.
If the `-oidc-callback-addr` flag is not specified, it will default to `localhost:4649`.

```shell-session
$ nomad login -method=oidc -oidc-callback-addr=<host:port>
Complete the login via your OIDC provider. Launching browser to:
https://myco.auth0.com/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A4649%2Foidc%2Fcallback&client_id=r3qXc2bix9eF...
```

Your browser opens to the generated URL to complete the provider's login.
Enter the URL manually if the browser does not automatically open.

## OIDC Configuration Troubleshooting

The amount of configuration required for OIDC is relatively small, but it can
be tricky to debug why things aren't working. The following are tips for setting up OIDC:

- Monitor the log output for the Nomad servers for important
information about OIDC validation failures.

- Ensure correct redirect URIs in Nomad and on the provider. URIs
need to match exactly. Check http/https, 127.0.0.1/localhost,
port numbers, and whether trailing slashes are present.

- The `BoundAudiences` option is typically
not required. OIDC providers use the `client_id` as the audience and
OIDC validation expects this.

- Check your provider for scopes that are required to receive all of
the information you need. You often need to request the scopes
`profile` and `groups`, which you may set with
`OIDCScopes=["profile", "groups"]` in the auth method configuration.

- If you're seeing claim-related errors in logs, review the provider's docs
very carefully to see how they're naming and structuring their claims.
Depending on the provider, you may be able to construct a simple `curl`
[implicit grant](https://developer.okta.com/blog/2018/05/24/what-is-the-oauth2-implicit-grant-type)
request to obtain a JWT that you can inspect. This example decodes the
JWT located in the `access_token` field of a JSON response.

jq --raw-output '.access_token / "." | .[1] | @base64d' jwt.json

- With debug level logging, use the [VerboseLogging] option in the auth
method configuration to log the received OIDC token. This can be helpful
when debugging provider setup and verifying that the received claims are
what you expect. Since claims data is logged verbatim and may contain
sensitive information, do not use this option in production.

@include 'jwt_claim_mapping_details.mdx'

[ACL Overview]: /nomad/docs/concepts/acl
[auth-method create]: /nomad/docs/commands/acl/auth-method/create
[VerboseLogging]: /nomad/api-docs/acl/auth-methods#verboselogging
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,25 @@ Connect (OIDC)][oidc] SSO workflow which allows users to log in to Nomad via
applications such as [Auth0][auth0], [Okta][okta], and [Vault][vault], and
non-interactive login via externally-issued [JSON Web Tokens (JWT)][jwt].

Since both the `oidc` and `jwt` auth methods ultimately operate on JWTs as
bearer tokens, use the following to determine which method fits your use case:

- **JWT**

- Ideal for machine-oriented, headless login where an operator may have already
arranged for a valid JWT to be dropped on a VM or provided to a container.
- User or application performing the Nomad login must have a valid JWT
to begin login.
- Does not require browser interaction.

- **OIDC**

- Ideal for human-oriented, interactive login where an operator or administrator
may have deployed SSO widely and doesn't want to distribute Nomad ACL tokens
to every authorized user.
- User performing the Nomad login does not need a JWT.
- Requires browser interaction.

## Binding Rule

Binding rules provide a mapping between a Nomad user's SSO authorisation claims
Expand Down
10 changes: 5 additions & 5 deletions website/content/docs/concepts/architecture/federation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ the job on all the specified regions, removing the need for multiple job
specification copies and registration on each region. Multiregion jobs do not
provide regional failover in the event of failure.

[acl_policy]: /nomad/docs/concepts/acl#policy
[acl_role]: /nomad/docs/concepts/acl#role
[acl_auth_method]: /nomad/docs/concepts/acl#auth-method
[acl_binding_rule]: /nomad/docs/concepts/acl#binding-rule
[acl_token]: /nomad/docs/concepts/acl#token
[acl_policy]: /nomad/docs/concepts/acl/#policy
[acl_role]: /nomad/docs/concepts/acl/#role
[acl_auth_method]: /nomad/docs/concepts/acl/#auth-method
[acl_binding_rule]: /nomad/docs/concepts/acl/#binding-rule
[acl_token]: /nomad/docs/concepts/acl/#token
[node_pool]: /nomad/docs/concepts/node-pools
[namespace]: /nomad/docs/other-specifications/namespace
[quota]: /nomad/docs/other-specifications/quota
Expand Down
80 changes: 80 additions & 0 deletions website/content/partials/jwt_claim_mapping_details.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
## Trusted Identity Attributes via Claim Mappings

The authentication step can return data from JWT claims as trusted
identity attributes for use in binding rule selectors and bind name
interpolation.

The `ClaimMappings` and `ListClaimMappings` attributes control how Nomad maps claims
to identity attributes. Both are maps of items to copy,
with elements of the form `"<JWT claim>":"<attribute suffix>"`.

Use `ClaimMappings` to map singular values and `ListClaimMappings` to map lists of values.

This examples contains `ClaimMappings` and `ListClaimMappings`. The configuration
instructs Nomad to copy the values in the JWT claims `"givenName"` and `"surname"`
to attributes named `"value.first_name"` and `"value.last_name"` respectively.
Additionally, Nomad should copy the list of values in the JWT
claim `"groups"` to an attribute named `"list.roles"`.

```json
{
"Name": "example-auth-method",
"Type": "<jwt|oidc>",
"Description": "Example auth method",
"Config": {
"ClaimMappings": {
"givenName": "first_name",
"surname": "last_name"
},
"ListClaimMappings": {
"groups": "roles"
}
}
}
```

The following table shows the resulting attributes and
the ways they may be used in rule bindings:

| Attributes | Supported selector operations | Can be interpolated |
| ------------------ | -------------------------------------------------- | ------------------- |
| `value.first_name` | Equal, Not Equal, In, Not In, Matches, Not Matches | yes |
| `value.last_name` | Equal, Not Equal, In, Not In, Matches, Not Matches | yes |
| `list.groups` | In, Not In, Is Empty, Is Not Empty | no |

Refer to the [binding-rule] documentation for more examples on using selectors.

### Claim Specifications and JSON Pointer

Use the `ClaimMappings` and `ListClaimMappings` fields to point to data
within the JWT. If the desired key is at the top of level of the JWT, you may
provide the name directly. If it is nested at a lower level, you may use a JSON
Pointer.

This example shows decoded JWT claims.

```json
{
"division": "North America",
"groups": {
"primary": "Engineering",
"secondary": "Software"
},
"iss": "https://my-corp-app-name.auth0.com/",
"sub": "auth0|eiw7OWoh5ieSh7ieyahC3ief0uyuraphaengae9d",
"aud": "V1RPi2MYptMV1RPi2MYptMV1RPi2MYpt",
"iat": 1589224148,
"exp": 1589260148,
"nonce": "eKiihooH3Fah8Ieshah4leeti6ien3"
}
```

Use the following syntax to reference data:

- Top-level key: Use direct reference. For example, `"division"` refers to `"North America"`.
- Nested key: Use JSON Pointer syntax. For example, `"/groups/primary"` refers to `"Engineering"`.

You may use any valid JSON Pointer as a selector. Refer to the [JSON Pointer
RFC](https://tools.ietf.org/html/rfc6901) for a full description of the syntax.

[binding-rule]: /nomad/docs/commands/acl/binding-rule/create#examples
20 changes: 19 additions & 1 deletion website/data/docs-nav-data.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,25 @@
},
{
"title": "ACL",
"path": "concepts/acl"
"routes": [
{
"title": "Overview",
"path": "concepts/acl"
},
{
"title": "Auth Methods",
"routes": [
{
"title": "JWT",
"path": "concepts/acl/auth-methods/jwt"
},
{
"title": "OIDC",
"path": "concepts/acl/auth-methods/oidc"
}
]
}
]
},
{
"title": "Architecture",
Expand Down

0 comments on commit ec8320c

Please sign in to comment.