{"record":{"id":"bf086c90b4b208f0","repo":"nats-io/nats-server","slug":"operators-do-not-allow-authorization-callouts-to-b","errorCode":null,"errorMessage":"operators do not allow authorization callouts to be configured directly","messagePattern":"operators do not allow authorization callouts to be configured directly","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/jwt.go","lineNumber":176,"sourceCode":"\t\tif !nkeys.IsValidPublicOperatorKey(key) {\n\t\t\treturn fmt.Errorf(\"trusted Keys %q are required to be a valid public operator nkey\", key)\n\t\t}\n\t}\n\tif len(o.resolverPinnedAccounts) > 0 {\n\t\tfor key := range o.resolverPinnedAccounts {\n\t\t\tif !nkeys.IsValidPublicAccountKey(key) {\n\t\t\t\treturn fmt.Errorf(\"pinned account key %q is not a valid public account nkey\", key)\n\t\t\t}\n\t\t}\n\t\t// ensure the system account (belonging to the operator can always connect)\n\t\tif o.SystemAccount != _EMPTY_ {\n\t\t\to.resolverPinnedAccounts[o.SystemAccount] = struct{}{}\n\t\t}\n\t}\n\n\t// If we have an auth callout defined make sure we are not in operator mode.\n\tif o.AuthCallout != nil {\n\t\treturn errors.New(\"operators do not allow authorization callouts to be configured directly\")\n\t}\n\n\treturn nil\n}\n\nfunc validateSrc(claims *jwt.UserClaims, host string) bool {\n\tif claims == nil {\n\t\treturn false\n\t} else if len(claims.Src) == 0 {\n\t\treturn true\n\t} else if host == \"\" {\n\t\treturn false\n\t}\n\tip := net.ParseIP(host)\n\tif ip == nil {\n\t\treturn false\n\t}\n\tfor _, cidr := range claims.Src {","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/jwt.go#L158-L194","documentation":"When operator mode is in effect (trusted operators / JWT-based auth), all authorization must be managed via account-scoped authorization callouts declared in operator/account JWTs, not via the server's own configuration. If `authorization {}` (AuthCallout) is set directly in server config while operator mode is enabled, `validateTrustedOperators` in server/jwt.go:176 rejects the configuration at startup.","triggerScenarios":"Starting a server with both a resolver/operator JWT setup (trusted operators) and a direct `authorization { ... }` block in the config file; enabling operator mode via `--trusted` while auth callout options remain present.","commonSituations":"Migrating a self-managed server to operator mode and forgetting to remove the legacy auth callout block; copying a config from a non-operator deployment into an operator-mode deployment; enabling trusted operators in a test config that still has auth callout settings.","solutions":["Remove the `authorization { ... }` callout block from the server config and define the auth callout in an account JWT instead (pushed via resolver or embedded)","If direct auth callout is intended, remove the trusted operator/operator mode configuration","Move any user-level auth into account/user JWTs managed by the operator's signing key"],"exampleFix":"// before: operator mode + direct callout in nats-server.conf\nresolver: URL(...)\nauthorization {\n  users = [ ... ]\n}\n// after: authorization via account JWT only\nresolver: URL(...)\n// (authorization block removed; callout configured in the account JWT)","handlingStrategy":"validation","validationCode":"// Reject the config combination before startup\nif hasTrustedOperators(cfg) && cfg.Authorization != nil {\n  return errors.New(\"auth callout cannot be configured directly in operator mode\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a dedicated operator-mode config without authorization blocks","Define auth callouts in account JWTs, never in server config","Audit configs with nats-server --config check or a linter before deploy"],"tags":["configuration","operator-mode","jwt","auth-callout"],"backgroundTag":"operator-mode-config-conflict","analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}