hashicorp/nomad · error

no auth method config or client assertion

Error message

no auth method config or client assertion

What it means

BuildClientAssertionJWT returns this error when the ACLAuthMethodConfig is nil or has no OIDCClientAssertion configured. A client-assertion JWT cannot be built without the private-key/JWKS/derived-key assertion settings, and the function refuses to proceed.

Source

Thrown at lib/auth/oidc/client_assertion.go:57

//   - "client_secret": uses the config's ClientSecret as an HMAC key to sign
//     the JWT. This is marginally more secure than a bare ClientSecret, as the
//     JWT is time-bound, and signed by the secret rather than sending the
//     secret itself over the network.
//   - "nomad": uses the RS256 nomadKey (Nomad's private key) to sign the JWT,
//     and the nomadKID as the JWT's "kid" header, which the OIDC provider uses
//     to find the public key at Nomad's JWKS endpoint (/.well-known/jwks.json)
//     to verify the JWT signature. This is arguably the most secure option,
//     because only Nomad has the private key.
//   - "private_key": uses an RSA private key provided by the user. They may
//     provide a KeyID to use as the JWT's "kid" header, or an x509 public
//     certificate to derive an x5t#S256 (or x5t) header, which the OIDC
//     provider uses to find the cert on their end to verify the JWT signature.
//     This is the most flexible option, allowing users to manage their own
//     keys however they like.
func BuildClientAssertionJWT(config *structs.ACLAuthMethodConfig, nomadKey *rsa.PrivateKey, nomadKID string) (*cass.JWT, error) {
	// should already be validated by caller, but just in case.
	if config == nil || config.OIDCClientAssertion == nil {
		return nil, errors.New("no auth method config or client assertion")
	}

	// this is all we use config for
	clientID := config.OIDCClientID
	// client assertion-specific info is in here
	as := config.OIDCClientAssertion

	// this should have also happened long before, but again, just in case.
	if err := as.Validate(); err != nil {
		return nil, err
	}

	opts := []cass.Option{
		cass.WithHeaders(as.ExtraHeaders),
	}

	switch as.KeySource {

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Configure OIDCClientAssertion (with key source: private key, JWKS, or derived key) on the ACL auth method before enabling private_key_jwt
  2. Verify the auth method's config is loaded and non-nil before building the assertion
  3. If the provider uses client_secret auth instead, do not use the client assertion path
  4. Re-check the ACL auth method after any config update that may have cleared the assertion settings

Example fix

// before: missing assertion config
authMethodConfig := &structs.ACLAuthMethodConfig{
  OIDCClientID: "nomad",
}
jwt, err := auth.BuildClientAssertionJWT(authMethodConfig, key, kid) // errors
// after: configure the assertion
authMethodConfig := &structs.ACLAuthMethodConfig{
  OIDCClientID:        "nomad",
  OIDCClientAssertion: &structs.OIDCClientAssertion{KeySource: "nomad", ...},
}
jwt, err := auth.BuildClientAssertionJWT(authMethodConfig, key, kid)
Defensive patterns

Strategy: validation

Validate before calling

if config == nil || config.OIDCClientAssertion == nil {
  // fall back to client_secret auth or configure assertion first
  return errors.New("auth method lacks OIDC client assertion; cannot use private_key_jwt")
}

Type guard

func hasClientAssertion(c *structs.ACLAuthMethodConfig) bool {
  return c != nil && c.OIDCClientAssertion != nil
}

Try / catch

jwt, err := auth.BuildClientAssertionJWT(config, key, kid)
if err != nil && strings.Contains(err.Error(), "no auth method config or client assertion") {
  return configureAssertionThenRetry()
}

Prevention

When it happens

Trigger: Calling BuildClientAssertionJWT with config == nil, or config.OIDCClientAssertion == nil — i.e. the auth method is not configured for OIDC client assertion (private_key_jwt).

Common situations: OIDC auth method configured without BoundAudiences/ClientAssertion while the OIDC provider requires private_key_jwt; calling the assertion builder for auth methods using a different client authentication style (client_secret); config dropped or overwritten in the ACL auth method update.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/9d1cb30425e5a756. Report an issue: GitHub.