{"record":{"id":"14215d755ef333b1","repo":"hashicorp/nomad","slug":"auth-method-specifies-boundissuers-but-the-provide","errorCode":null,"errorMessage":"auth method specifies BoundIssuers but the provided token does not contain issuer information","messagePattern":"auth method specifies BoundIssuers but the provided token does not contain issuer information","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/auth/jwt/validator.go","lineNumber":75,"sourceCode":"\t\tNotBeforeLeeway:   methodConf.NotBeforeLeeway,\n\t\tExpirationLeeway:  methodConf.ExpirationLeeway,\n\t\tClockSkewLeeway:   methodConf.ClockSkewLeeway,\n\t}\n\n\tvalidator, err := jwt.NewValidator(keySet)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tclaims, err := validator.Validate(ctx, token, expected)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to verify signature of JWT token: %v\", err)\n\t}\n\n\t// validate issuer manually, because we allow users to specify an array\n\tif len(methodConf.BoundIssuer) > 0 {\n\t\tif _, ok := claims[\"iss\"]; !ok {\n\t\t\treturn nil, fmt.Errorf(\n\t\t\t\t\"auth method specifies BoundIssuers but the provided token does not contain issuer information\",\n\t\t\t)\n\t\t}\n\t\tif iss, ok := claims[\"iss\"].(string); !ok {\n\t\t\treturn nil, fmt.Errorf(\"unable to read iss property of provided token\")\n\t\t} else if !slices.Contains(methodConf.BoundIssuer, iss) {\n\t\t\treturn nil, fmt.Errorf(\"invalid JWT issuer: %v\", claims[\"iss\"])\n\t\t}\n\t}\n\n\treturn claims, nil\n}\n\nfunc usingStaticKeys(keys []string) (jwt.KeySet, error) {\n\tvar parsedKeys []crypto.PublicKey\n\tfor _, v := range keys {\n\t\tkey, err := jwt.ParsePublicKeyPEM([]byte(v))\n\t\tparsedKeys = append(parsedKeys, key)","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/lib/auth/jwt/validator.go#L57-L93","documentation":"The auth method has BoundIssuer configured, but the validated JWT contains no iss claim at all. Issuer checking is done manually (to support arrays of acceptable issuers), so a token without iss cannot be matched and is rejected.","triggerScenarios":"Login where methodConf.BoundIssuer is non-empty but claims lacks the \"iss\" key — typically an opaque/access token or a token type that omits iss.","commonSituations":"Sending an access token instead of an ID token; IdP configured without issuer in token; using a token from a different provider that doesn't set iss.","solutions":["Use the ID token (which carries iss) rather than the access token","Configure the IdP to include the iss claim in issued tokens","If issuer enforcement isn't required, clear BoundIssuer on the auth method"],"exampleFix":"// before: access token without iss\nresp, err := client.Login(idp.AccessToken)\n// after: ID token\nresp, err := client.Login(idp.IDToken)","handlingStrategy":"validation","validationCode":"payload := decodeJWTPayload(rawToken) // base64 decode middle segment\nif _, ok := payload[\"iss\"]; !ok && authMethodUsesBoundIssuer {\n    return errors.New(\"token has no iss claim but auth method requires BoundIssuer match\")\n}","typeGuard":"func hasStringIss(claims map[string]interface{}) bool {\n    iss, ok := claims[\"iss\"]\n    if !ok { return false }\n    _, isStr := iss.(string)\n    return isStr\n}","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"does not contain issuer information\") {\n    return fmt.Errorf(\"use the ID token (contains iss), not the access token: %w\", err)\n}","preventionTips":["Always send the ID token for OIDC login flows — access tokens often lack iss","If your IdP omits iss, either fix the IdP config or drop BoundIssuer from the method","Add a client-side pre-check that the token payload contains iss when BoundIssuer is set"],"tags":["auth","jwt","issuer-validation"],"backgroundTag":"jwt-missing-issuer-claim","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"}