{"record":{"id":"8b538039dd469e3f","repo":"calcom/cal.diy","slug":"permissionsguard-no-authentication-provided-pro","errorCode":null,"errorMessage":"PermissionsGuard - no authentication provided. Provide either authorization bearer token containing managed user access token or oAuth client id in 'x-cal-client-id' header.","messagePattern":"PermissionsGuard - no authentication provided\\. Provide either authorization bearer token containing managed user access token or oAuth client id in 'x-cal-client-id' header\\.","errorType":"exception","errorClass":"ForbiddenException","httpStatus":403,"severity":"error","filePath":"apps/api/v2/src/modules/auth/guards/permissions/permissions.guard.ts","lineNumber":48,"sourceCode":"    if (!requiredPermissions?.length || !Object.keys(requiredPermissions)?.length) {\n      return true;\n    }\n\n    const request = context.switchToHttp().getRequest();\n    const bearerToken = request.get(\"Authorization\")?.replace(\"Bearer \", \"\");\n    const nextAuthSecret = this.config.get(\"next.authSecret\", { infer: true });\n    const nextAuthToken = await getToken({ req: request, secret: nextAuthSecret });\n    const oAuthClientId = request.params?.clientId || request.get(X_CAL_CLIENT_ID);\n    const apiKey = bearerToken && isApiKey(bearerToken, this.config.get(\"api.apiKeyPrefix\") ?? \"cal_\");\n    const isThirdPartyBearerToken = bearerToken && this.getDecodedThirdPartyAccessToken(bearerToken);\n\n    // only check permissions for accessTokens attached to platform oAuth Client or platform oAuth credentials, not for next token or api key or third party oauth client\n    if (nextAuthToken || apiKey || isThirdPartyBearerToken) {\n      return true;\n    }\n\n    if (!bearerToken && !oAuthClientId) {\n      throw new ForbiddenException(\n        \"PermissionsGuard - no authentication provided. Provide either authorization bearer token containing managed user access token or oAuth client id in 'x-cal-client-id' header.\"\n      );\n    }\n\n    const oAuthClient = bearerToken\n      ? await this.getOAuthClientByAccessToken(bearerToken)\n      : await this.getOAuthClientById(oAuthClientId);\n\n    const hasRequiredPermissions = hasPermissions(oAuthClient.permissions, [...requiredPermissions]);\n\n    if (!hasRequiredPermissions) {\n      throw new ForbiddenException(\n        `PermissionsGuard - oAuth client with id=${\n          oAuthClient.id\n        } does not have the required permissions=${requiredPermissions\n          .map((permission) => this.oAuthClientsOutputService.transformOAuthClientPermission(permission))\n          .join(\n            \", \"","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/auth/guards/permissions/permissions.guard.ts#L30-L66","documentation":"ForbiddenException from PermissionsGuard when the request carries neither a Bearer token nor an x-cal-client-id header (and is also not a NextAuth token, API key, or third-party OAuth token — those bypass the guard at line 44). The guard only enforces permissions for platform OAuth clients/credentials; the missing-auth case is a 403, not 401, by design.","triggerScenarios":"Calling any platform endpoint guarded by PermissionsGuard with no Authorization header AND no x-cal-client-id header (and no clientId route param). Earlier short-circuits return true for NextAuth tokens, cal_ API keys, and recognized third-party bearer tokens.","commonSituations":"Client forgot the Authorization header; using x-cal-client-id but misspelled the header; curl/Postman request built without auth; SDK not configured with the OAuth client id; dev environment missing the platform client entirely.","solutions":["Send a valid Bearer token (managed-user access token) in the Authorization header, OR an x-cal-client-id header for a platform OAuth client.","If using an API key (cal_…), confirm the prefix matches api.apiKeyPrefix (default 'cal_') so the apiKey short-circuit at line 41 fires.","If using a NextAuth session, confirm NEXTAUTH_SECRET matches so getToken decodes a valid nextAuthToken.","If using a third-party OAuth token, ensure getDecodedThirdPartyAccessToken recognizes it."],"exampleFix":"// before\ncurl https://api.example.com/v2/atoms -H 'cal-api-version: 2024-06-14'\n\n// after\ncurl https://api.example.com/v2/atoms \\\n  -H 'cal-api-version: 2024-06-14' \\\n  -H 'Authorization: Bearer <managed-user-access-token>'","handlingStrategy":"validation","validationCode":"const bearer = request.headers['authorization'];\nconst clientId = request.headers['x-cal-client-id'];\nif (!bearer && !clientId) {\n  // client-side: tell user to provide credentials; do not send the request.\n  throw new Error('Missing Authorization header and x-cal-client-id');\n}","typeGuard":"function hasPlatformAuth(headers: Record<string,string|undefined>): boolean {\n  return Boolean(headers['authorization'] || headers['x-cal-client-id']);\n}","tryCatchPattern":null,"preventionTips":["Always set either Authorization: Bearer <token> or x-cal-client-id on platform requests.","Use the SDK's auth helpers so headers are attached consistently.","Remember API keys (cal_…) and NextAuth tokens bypass PermissionsGuard — use those if permissions aren't required."],"tags":["auth","permissions","oauth","guard","forbidden"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}