{"record":{"id":"af743cdc15560b0b","repo":"hashicorp/nomad","slug":"x5t-assertion-headers-use-sha-1-which-is-forbidde","errorCode":null,"errorMessage":"x5t assertion headers use SHA-1, which is forbidden in FIPS-140 mode","messagePattern":"x5t assertion headers use SHA-1, which is forbidden in FIPS-140 mode","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/auth/oidc/client_assertion.go","lineNumber":197,"sourceCode":"\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to parse %s bytes: %w\", source, err)\n\t}\n\tnow := time.Now()\n\tif now.Before(cert.NotBefore) || now.After(cert.NotAfter) {\n\t\treturn nil, errors.New(\"certificate has expired or is not yet valid\")\n\t}\n\treturn cert, nil\n}\n\n// hashKeyID derives a \"certificate thumbprint\" that the OIDC provider uses\n// to find the certificate to verify the private key JWT signature.\n// https://datatracker.ietf.org/doc/html/rfc7515#section-4.1.7\nfunc hashKeyID(cert *x509.Certificate, header structs.OIDCClientAssertionKeyIDHeader) (string, error) {\n\tvar hasher hash.Hash\n\tswitch header {\n\tcase structs.OIDCClientAssertionHeaderX5t:\n\t\tif fips140.Enabled() {\n\t\t\treturn \"\", errors.New(\"x5t assertion headers use SHA-1, which is forbidden in FIPS-140 mode\")\n\t\t}\n\n\t\thasher = sha1.New()\n\tcase structs.OIDCClientAssertionHeaderX5tS256:\n\t\thasher = sha256.New()\n\tdefault:\n\t\t// this should be validated long before here, at upsert\n\t\treturn \"\", fmt.Errorf(`%w; must be one of: \"x5t\", \"x5t#S256\"`, structs.ErrInvalidKeyIDHeader)\n\t}\n\thasher.Write(cert.Raw)\n\thashed := hasher.Sum(nil)\n\treturn base64.RawURLEncoding.EncodeToString(hashed), nil\n}\n\n// newlineHeaders allows flexible copy-paste of a one-line key/cert PEM\n// by adding newlines around \"----BEGIN.*-----\" and\n// \"-----END.*(KEY|CERTIFICATE)-----\"\n// it's okay to have extra whitespace, but it's imperative that there be","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/lib/auth/oidc/client_assertion.go#L179-L215","documentation":"hashKeyID computes the x5t (SHA-1 thumbprint, per RFC 7515 §4.1.7) or x5t#S256 header used by the OIDC provider to locate the certificate that verifies the private-key JWT. In FIPS-140 mode SHA-1 is disallowed, so selecting the x5t header kind fails immediately.","triggerScenarios":"BuildClientAssertionJWT is called with key ID header structs.OIDCClientAssertionHeaderX5t while fips140.Enabled() is true (Nomad built/running with FIPS-140 mode enabled).","commonSituations":"Deployments in FIPS-compliant environments (government, regulated industries) whose OIDC auth method still specifies the legacy x5t header, which the OIDC provider only supports in SHA-1 form.","solutions":["Switch the auth method's client-assertion key ID header to structs.OIDCClientAssertionHeaderX5tS256 (SHA-256), which is FIPS-allowed — verify your OIDC provider supports x5t#S256.","If the provider only supports x5t/SHA-1, disable FIPS-140 mode or use a different provider/key-id mechanism.","Confirm with the provider documentation which x5c thumbprint header it validates before changing config."],"exampleFix":"// before\nheader = structs.OIDCClientAssertionHeaderX5t\n// after\nheader = structs.OIDCClientAssertionHeaderX5tS256","handlingStrategy":"validation","validationCode":"if fips140.Enabled() && header == structs.OIDCClientAssertionHeaderX5t {\n    return errors.New(\"FIPS mode requires x5t#S256 (SHA-256) key ID header\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to x5t#S256 in all OIDC client-assertion configs","Confirm provider support for x5t#S256 before enabling FIPS mode","Document FIPS incompatibility of SHA-1 x5t in deployment runbooks"],"tags":["oidc","fips","sha1","jwt"],"backgroundTag":"fips-forbidden-algorithm","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}