{"record":{"id":"4a13380f0c765739","repo":"hcengineering/platform","slug":"unauthorized-4a1338","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"ApiError","httpStatus":401,"severity":"error","filePath":"services/datalake/pod-datalake/src/middleware.ts","lineNumber":53,"sourceCode":"    res.setHeader('Connection', 'keep-alive')\n    res.setHeader('Keep-Alive', `timeout=${timeout}, max=${max}`)\n    next()\n  }\n}\n\nexport const withOptionalAuth = (secure: boolean): RequestHandler => {\n  return secure\n    ? withAuthorization\n    : (req: Request, res: Response, next: NextFunction) => {\n        next()\n      }\n}\n\nexport const withAdminAuthorization = (req: RequestWithAuth, res: Response, next: NextFunction): void => {\n  try {\n    const token = extractToken(req.headers)\n    if (token == null || !(token.account === systemAccountUuid || token.extra?.admin === 'true')) {\n      throw new ApiError(401, 'Unauthorized')\n    }\n    req.token = token\n\n    next()\n  } catch (err: any) {\n    next(err)\n  }\n}\n\nexport const withAuthorization = (req: RequestWithAuth, res: Response, next: NextFunction): void => {\n  try {\n    const token = extractToken(req.headers)\n    if (token == null || token.extra?.guest === 'true' || token.extra?.readonly === 'true') {\n      throw new ApiError(401, 'Unauthorized')\n    }\n    req.token = token\n\n    next()","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/hcengineering/platform/blob/63e28dc96483967b2fc21c881b3f1023c1de7718/services/datalake/pod-datalake/src/middleware.ts#L35-L71","documentation":"withAdminAuthorization extracts the request token and throws ApiError(401, 'Unauthorized') unless the caller is the system account or has extra.admin === 'true'. It is the admin-only gate for datalake routes.","triggerScenarios":"Request to an admin-gated datalake route with no token, a non-admin user token, or a token whose extra claims lack admin='true'.","commonSituations":"Regular service/user tokens used against admin endpoints; token issued before the account was promoted to admin; missing or stale token claims after a permission change; header omitted entirely.","solutions":["Obtain and send a token whose extra.admin is 'true' (or use the system account) for admin routes","Re-issue/refresh the token after granting admin so the claim is present","Verify the Authorization header format matches extractToken's expectations","Confirm you are hitting the right endpoint — use non-admin endpoints where possible"],"exampleFix":"// before (regular user token)\nAuthorization: Bearer eyJ...\"extra\":{\"guest\":\"false\"}\n// after (admin token)\nAuthorization: Bearer eyJ...\"extra\":{\"admin\":\"true\"}","handlingStrategy":"try-catch","validationCode":"// inspect token claims before calling admin endpoints\nconst payload = decodeJwt(token)\nif (payload.extra?.admin !== 'true' && payload.account !== SYSTEM_ACCOUNT) {\n  throw new Error('Admin token required for this datalake operation')\n}","typeGuard":"function isAdminToken(t: { account?: string, extra?: Record<string, string> } | null): boolean {\n  return t != null && (t.account === systemAccountUuid || t.extra?.admin === 'true')\n}","tryCatchPattern":"try {\n  await datalake.adminOperation(...)\n} catch (err) {\n  if (err.response?.status === 401) {\n    // request an admin-scoped token or surface 'admin privileges required'\n  } else throw err\n}","preventionTips":["Keep admin tokens separate from normal app tokens","Re-issue tokens after permission changes","Check token claims (extra.admin) before invoking admin routes"],"tags":["authorization","http-401","admin","middleware"],"backgroundTag":"insufficient-permissions","analyzedSha":"63e28dc96483967b2fc21c881b3f1023c1de7718","analyzedAt":"2026-08-29T15:21:27.377Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}