{"record":{"id":"df6f2b9fa9822359","repo":"dgraph-io/dgraph","slug":"authorize-guardian-of-the-galaxy-extracting-jwt-t","errorCode":null,"errorMessage":"Authorize guardian of the galaxy, extracting jwt token, error:","messagePattern":"Authorize guardian of the galaxy, extracting jwt token, error:","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"edgraph/access.go","lineNumber":1128,"sourceCode":"\t\t\t}\n\t\t\ttypeNode.Fields = respFields\n\t\t}\n\t}\n\n\treturn nil\n}\n\n// AuthSuperAdmin authorizes the operations for the users who belong to the guardians\n// group in the galaxy namespace. This authorization is used for admin usages like creation and\n// deletion of a namespace, resetting passwords across namespaces etc.\n// NOTE: The caller should not wrap the error returned. If needed, propagate the GRPC error code.\nfunc AuthSuperAdmin(ctx context.Context) error {\n\tif !x.WorkerConfig.AclEnabled {\n\t\treturn nil\n\t}\n\tns, err := x.ExtractNamespaceFrom(ctx)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"Authorize guardian of the galaxy, extracting jwt token, error:\")\n\t}\n\tif ns != 0 {\n\t\treturn status.Error(\n\t\t\tcodes.PermissionDenied, \"Only superadmin is allowed to do this operation\")\n\t}\n\t// AuthorizeGuardians will extract (user, []groups) from the JWT claims and will check if\n\t// any of the group to which the user belongs is \"guardians\" or not.\n\tif err := AuthorizeGuardians(ctx); err != nil {\n\t\ts := status.Convert(err)\n\t\treturn status.Error(\n\t\t\ts.Code(), \"AuthSuperAdmin: failed to authorize guardians. \"+s.Message())\n\t}\n\tglog.V(3).Info(\"Successfully authorised guardian of the galaxy\")\n\treturn nil\n}\n\n// AuthorizeGuardians authorizes the operation for users which belong to Guardians group.\n// NOTE: The caller should not wrap the error returned. If needed, propagate the GRPC error code.","sourceCodeStart":1110,"sourceCodeEnd":1146,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/edgraph/access.go#L1110-L1146","documentation":"AuthSuperAdmin authorizes super-admin (namespace 0, guardians) operations when ACLs are enabled. If the namespace cannot be extracted from the JWT/context, the underlying extraction error is wrapped with 'Authorize guardian of the galaxy, extracting jwt token, error:'. It means the request lacked a valid JWT carrying namespace claims.","triggerScenarios":"Calling CreateNamespace, DropNamespace, ListNamespaces, an alter operation, or a query while x.WorkerConfig.AclEnabled is true and the context has no valid/parseable JWT with namespace information (ExtractNamespaceFrom fails).","commonSituations":"Sending admin requests without logging in via /login; JWT actually expired or stripped by a proxy; ACLs enabled on the server but client not configured with auth; mixing anonymous and ACL-mode clients.","solutions":["Login first (POST /login or dgraph acl login) to obtain a JWT and attach it as Authorization: Bearer <token> metadata on subsequent calls","Check the wrapped inner error: if 'jwt token expired' or invalid signature, refresh the token","Ensure --dir with the galaxy key (super administrators) is configured consistently on all Alphas when ACLs are enabled","Confirm your client SDK attaches JWT metadata on every RPC (the Go client's GetJwt/refresh token loop)","Temporarily disable ACL to confirm this is auth-related, then re-enable and fix credentials"],"exampleFix":"// before: no JWT attached\ndg.DropNamespace(ctx, 2)\n// after\ntok, err := c.LoginIntoNamespace(ctx, api.UserCredentials{Userid: \"gagali\", Password: \"pass\", Namespace: 0}, 0)\nctx = metadata.AppendToOutgoingContext(ctx, \"accessJwt\", tok.AccessJwt)\ndg.DropNamespace(ctx, 2)","handlingStrategy":"try-catch","validationCode":"// Ensure a JWT exists and ACLs require it before admin calls\nif (!token) throw new Error('ACL enabled: login required before admin operations')\n// attach on every RPC:\nconst md = new Metadata(); md.add('accessJwt', token)","typeGuard":null,"tryCatchPattern":"try {\n  await dg.createNamespace(ctx, ns)\n} catch (e) {\n  if (/extracting jwt token/.test(e.message) || /jwt token expired/i.test(e.message)) {\n    const tok = await login(user, pass, 0) // re-login into namespace 0\n    ctx = withJwt(ctx, tok.accessJwt)\n    return dg.createNamespace(ctx, ns)\n  }\n  throw e\n}","preventionTips":["Configure the client's auto-refresh JWT (Go client dg.GetLoginState) so tokens stay valid","Never mix anonymous client instances into ACL-enabled deployments","Verify proxies forward the Authorization/accessJwt metadata"],"tags":["auth","jwt","acl","namespace"],"backgroundTag":"missing-or-invalid-jwt","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}