{"record":{"id":"4fb22afb0374ac27","repo":"mastra-ai/mastra","slug":"you-do-not-have-permission-to-view-usage-for-this","errorCode":null,"errorMessage":"You do not have permission to view usage for this connection","messagePattern":"You do not have permission to view usage for this connection","errorType":"http","errorClass":"HTTPException","httpStatus":403,"severity":"warning","filePath":"packages/server/src/server/handlers/tool-providers.ts","lineNumber":765,"sourceCode":"      const store = await storage?.getStore('toolProviderConnections');\n      let ownerAuthorId: string | undefined;\n      let ownerScope: 'shared' | 'per-author' | 'caller-supplied' | undefined;\n      let matched = false;\n      if (store) {\n        const rows = await store.listConnectionsByAuthor({ providerId: provider.info.id });\n        const match = rows.find(r => r.connectionId === connectionId);\n        if (match) {\n          matched = true;\n          ownerAuthorId = match.authorId;\n          ownerScope = match.scope;\n        }\n      }\n\n      // Fail closed: if storage is configured and no row matches the\n      // requested connectionId, refuse the call for non-admins so callers\n      // cannot probe for other tenants' connections.\n      if (store && !matched && !isAdmin) {\n        throw new HTTPException(403, {\n          message: 'You do not have permission to view usage for this connection',\n        });\n      }\n\n      const effectiveOwner = ownerAuthorId ?? callerAuthorId;\n      const isShared = ownerScope === 'shared';\n      if (!isShared && effectiveOwner !== callerAuthorId && !isAdmin) {\n        throw new HTTPException(403, {\n          message: 'You do not have permission to view usage for this connection',\n        });\n      }\n\n      const agents = await scanConnectionUsage(mastra, { providerId: provider.info.id, connectionId, toolkit });\n      return { agents };\n    } catch (error) {\n      return handleError(error, 'Error listing tool provider connection usage');\n    }\n  },","sourceCodeStart":747,"sourceCodeEnd":783,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/server/src/server/handlers/tool-providers.ts#L747-L783","documentation":"A 403 fail-closed guard on the connection usage endpoint: when storage is configured but no row matches the requested connectionId, non-admin callers are refused so they cannot probe for other tenants' connection IDs. Distinguishes 'no permission' from 'not found' to avoid leaking existence.","triggerScenarios":"Calling the connection usage endpoint with a connectionId that has no matching row for the caller (e.g. another tenant's connection or a nonexistent ID) while not an admin — even though a 404 would seem more apt, the handler intentionally returns 403.","commonSituations":"Enumerating/guessing connection IDs across tenants; querying usage for a deleted connection as a non-admin; querying a connection scoped to another author.","solutions":["Verify the connectionId exists and belongs to you (list your connections first).","Re-authenticate as the connection's author, or use an admin context.","If the connection was deleted, recreate it before checking usage."],"exampleFix":"// before\nawait api.get(`/api/tool-providers/github/connections/${someoneElsesId}/usage`); // 403\n// after: discover your own connection IDs first\nconst list = await api.get(`/api/tool-providers/github/connections`);\nconst mine = list.connections.find(c => c.label === 'mine');\nawait api.get(`/api/tool-providers/github/connections/${mine.connectionId}/usage`);","handlingStrategy":"validation","validationCode":"const list = await api.get(`/api/tool-providers/${providerId}/connections`);\nif (!list.connections.some(c => c.connectionId === id)) {\n  throw new Error('Connection does not exist or is not visible to you');\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await api.get(`/api/tool-providers/${p}/connections/${id}/usage`);\n} catch (e) {\n  if (e.status === 403) return { agents: [], restricted: true };\n  throw e;\n}","preventionTips":["Only query usage for connections you own or that are shared.","Don't guess/enumerate connection IDs.","Cache the IDs returned by your own listing calls."],"tags":["http-403","authorization","multi-tenancy","tool-providers"],"backgroundTag":"insufficient-permissions","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}