{"record":{"id":"4908b835aaea820b","repo":"hashicorp/nomad","slug":"w-certificate-derived-key-header-must-be-one-of","errorCode":null,"errorMessage":"%w; certificate-derived key header must be one of: %q, %q","messagePattern":"%w; certificate-derived key header must be one of: %q, %q","errorType":"validation","errorClass":"ErrInvalidKeyIDHeader","httpStatus":null,"severity":"error","filePath":"nomad/structs/acl.go","lineNumber":1897,"sourceCode":"\tif k.KeyID != \"\" && (k.PemCert != \"\" || k.PemCertFile != \"\") {\n\t\treturn ErrAmbiguousClientAssertionKeyID\n\t}\n\tif k.PemCertFile != \"\" {\n\t\tif !path.IsAbs(k.PemCertFile) {\n\t\t\treturn fmt.Errorf(\"%w: must be absolute; got: %s\", ErrInvalidClientAssertionCertPath, k.PemCertFile)\n\t\t}\n\t}\n\n\t// only allow certain key id headers\n\t// only \"kid\" for KeyID\n\tif k.KeyID != \"\" && k.KeyIDHeader != OIDCClientAssertionHeaderKid {\n\t\treturn fmt.Errorf(\"%w; key header for key ID must be %q\",\n\t\t\tErrInvalidKeyIDHeader, OIDCClientAssertionHeaderKid)\n\t}\n\t// only \"x5t*\" for certs\n\tif k.PemCert != \"\" || k.PemCertFile != \"\" {\n\t\tif k.KeyIDHeader != OIDCClientAssertionHeaderX5t && k.KeyIDHeader != OIDCClientAssertionHeaderX5tS256 {\n\t\t\treturn fmt.Errorf(\"%w; certificate-derived key header must be one of: %q, %q\",\n\t\t\t\tErrInvalidKeyIDHeader, OIDCClientAssertionHeaderX5tS256, OIDCClientAssertionHeaderX5t)\n\t\t}\n\t\tif fips140.Enabled() && k.KeyIDHeader == OIDCClientAssertionHeaderX5t {\n\t\t\treturn errors.New(\"x5t assertion headers use SHA-1, which is forbidden in FIPS-140 mode\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// ACLAuthClaims is the claim mapping of the OIDC auth method in a format that\n// can be used with go-bexpr. This structure is used during rule binding\n// evaluation.\ntype ACLAuthClaims struct {\n\tValue map[string]string   `bexpr:\"value\"`\n\tList  map[string][]string `bexpr:\"list\"`\n}\n","sourceCodeStart":1879,"sourceCodeEnd":1915,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/acl.go#L1879-L1915","documentation":"When the OIDC client assertion is certificate-derived (pem_cert or pem_cert_file set), the KeyIDHeader must be either x5t (SHA-1 cert thumbprint) or x5tS256 (SHA-256 thumbprint). Any other header fails with ErrInvalidKeyIDHeader. Additionally, x5t is rejected outright when FIPS-140 mode is enabled because SHA-1 is forbidden.","triggerScenarios":"Setting key_id_header to \"kid\" (or anything else) while pem_cert/pem_cert_file are configured; or using \"x5t\" on a Nomad server running with FIPS-140 mode enabled.","commonSituations":"Swapping a key_id config to cert-based without updating the header; Azure AD setups needing x5t while the Nomad server is in FIPS mode; typo like \"x5t256\" instead of \"x5tS256\".","solutions":["Set key_id_header to \"x5tS256\" (preferred) or \"x5t\" for certificate-derived assertions.","If in FIPS-140 mode, use x5tS256 and ensure your IdP accepts SHA-256 thumbprints.","Verify the exact header constant spelling (\"x5tS256\", not \"x5t256\")."],"exampleFix":"// before\npem_cert_file = \"/etc/ssl/client.crt\"\nkey_id_header = \"kid\"\n\n// after\npem_cert_file = \"/etc/ssl/client.crt\"\nkey_id_header = \"x5tS256\"","handlingStrategy":"validation","validationCode":"if (k.PemCert != \"\" || k.PemCertFile != \"\") {\n    switch k.KeyIDHeader {\n    case \"x5t\", \"x5tS256\":\n    default:\n        return fmt.Errorf(\"cert-based assertion needs x5t or x5tS256 header, got %q\", k.KeyIDHeader)\n    }\n    if fipsEnabled && k.KeyIDHeader == \"x5t\" {\n        return errors.New(\"x5t forbidden in FIPS mode; use x5tS256\")\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer x5tS256 everywhere to stay FIPS-compliant.","Confirm your IdP supports SHA-256 thumbprints (x5tS256).","Check the exact header constant spelling."],"tags":["nomad","acl","oidc","jwt","fips","validation"],"backgroundTag":"invalid-jwt-header","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"}