{"record":{"id":"3c3629a3807f6589","repo":"kubernetes/kops","slug":"incorrect-audience-3c3629","errorCode":null,"errorMessage":"incorrect Audience","messagePattern":"incorrect Audience","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go","lineNumber":100,"sourceCode":"\n\ttokenBytes, err := base64.StdEncoding.DecodeString(authToken)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"decoding authorization token: %w\", err)\n\t}\n\n\ttoken := &gcetpm.AuthToken{}\n\tif err = json.Unmarshal(tokenBytes, token); err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshalling authorization token: %w\", err)\n\t}\n\n\ttokenData := gcetpm.AuthTokenData{}\n\tif err := json.Unmarshal(token.Data, &tokenData); err != nil {\n\t\treturn nil, fmt.Errorf(\"unmarshalling authorization token data: %w\", err)\n\t}\n\n\t// Guard against replay attacks\n\tif tokenData.Audience != gcetpm.AudienceNodeAuthentication {\n\t\treturn nil, fmt.Errorf(\"incorrect Audience\")\n\t}\n\ttimeSkew := math.Abs(time.Since(time.Unix(tokenData.Timestamp, 0)).Seconds())\n\tif timeSkew > float64(v.opt.MaxTimeSkew) {\n\t\treturn nil, fmt.Errorf(\"incorrect Timestamp %v\", tokenData.Timestamp)\n\t}\n\n\t// Verify the token has signed the body content.\n\trequestHash := sha256.Sum256(body)\n\tif !bytes.Equal(requestHash[:], tokenData.RequestHash) {\n\t\treturn nil, fmt.Errorf(\"incorrect RequestHash\")\n\t}\n\n\t// Some basic validation to avoid requesting invalid instances.\n\tif tokenData.GCPProjectID == \"\" {\n\t\treturn nil, fmt.Errorf(\"gcpProjectID is required\")\n\t}\n\tif tokenData.Zone == \"\" {\n\t\treturn nil, fmt.Errorf(\"zone is required\")","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go#L82-L118","documentation":"As a replay protection, VerifyToken requires the signed token's Audience field to equal gcetpm.AudienceNodeAuthentication. A token minted for a different audience (or with an empty audience) is rejected even if its signature is valid. This is a deliberate security check, not an infrastructure fault.","triggerScenarios":"VerifyToken receives a correctly signed and parsed token whose AuthTokenData.Audience differs from AudienceNodeAuthentication — e.g. a token generated for another purpose or by code setting a different audience constant.","commonSituations":"Token reuse across subsystems (e.g. using a verifier-audience token for node auth); custom client code hardcoding a wrong audience string; version skew where the audience constant value changed; replay of a captured token for a different endpoint.","solutions":["Ensure the node uses the standard gcetpm authenticator, which sets AudienceNodeAuthentication","Check that signer and verifier link the same gcetpm package version (same constant value)","Never mint tokens manually with a custom Audience for node authentication","Verify no proxy rewrites or substitutes tokens between node and server"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"tokenData := gcetpm.AuthTokenData{}\njson.Unmarshal(token.Data, &tokenData)\nif tokenData.Audience != gcetpm.AudienceNodeAuthentication {\n    return fmt.Errorf(\"token audience %q is not for node authentication\", tokenData.Audience)\n}","typeGuard":"func isNodeAuthToken(td gcetpm.AuthTokenData) bool {\n    return td.Audience == gcetpm.AudienceNodeAuthentication\n}","tryCatchPattern":"token, err := verifier.VerifyToken(ctx, rawToken, request)\nif err != nil {\n    if err.Error() == \"incorrect Audience\" {\n        return fmt.Errorf(\"token not intended for node authentication endpoint: %w\", err)\n    }\n    return err\n}","preventionTips":["Only use tokens minted by the standard gcetpm authenticator for node auth","Use distinct verifier instances per audience/purpose; never share tokens across endpoints","Keep the gcetpm audience constants identical on signer and verifier (same module version)","Reject and log tokens with unexpected audiences for security auditing"],"tags":["gce","tpm","security","audience","replay-protection"],"backgroundTag":"jwt-audience-mismatch","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}