{"record":{"id":"42cfe918c4bcb32e","repo":"JuliusBrussee/caveman","slug":"cave-vercel-usage-missing","errorCode":"cave_vercel_usage_missing","errorMessage":"cave_vercel_usage_missing","messagePattern":"cave_vercel_usage_missing","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/agent/src/adapters.ts","lineNumber":384,"sourceCode":"    ...input.usage,\n    costUsd: priced.catalogCostUsd,\n    usageBasis: \"provider_reported\",\n    priceBasis: \"public_catalog\",\n    evaluatedTransformIDs: [...input.request.evaluatedTransformIDs],\n    appliedTransformIDs: [...input.request.appliedTransformIDs],\n    recoveryResolved: input.request.recoveryResolved,\n    latencyMs: input.latencyMs,\n  };\n}\n\nfunction usageFromAISDK(value: unknown, reasoningRequired: boolean): NormalizedUsage {\n  const usage = record(value, \"cave_vercel_usage_missing\");\n  const input = record(usage.inputTokenDetails, \"cave_vercel_usage_missing\");\n  const output = record(usage.outputTokenDetails, \"cave_vercel_usage_missing\");\n  const totalInput = strictInteger(usage.inputTokens, \"cave_vercel_usage_missing\");\n  const cacheRead = optionalInteger(input.cacheReadTokens, \"cave_vercel_usage_missing\");\n  const cacheWrite = optionalInteger(input.cacheWriteTokens, \"cave_vercel_usage_missing\");\n  if (cacheRead + cacheWrite > totalInput) throw new Error(\"cave_vercel_usage_missing\");\n  const noCache = input.noCacheTokens === undefined\n    ? totalInput - cacheRead - cacheWrite\n    : strictInteger(input.noCacheTokens, \"cave_vercel_usage_missing\");\n  if (noCache + cacheRead + cacheWrite !== totalInput) {\n    throw new Error(\"cave_vercel_usage_missing\");\n  }\n  const normalized = normalizeUsage({\n    inputTokens: noCache,\n    outputTokens: usage.outputTokens,\n    cacheReadTokens: cacheRead,\n    cacheWriteTokens: cacheWrite,\n    reasoningTokens: output.reasoningTokens,\n    totalTokens: usage.totalTokens,\n  }, reasoningRequired, \"cave_vercel_usage_missing\");\n  return normalized;\n}\n\nfunction usageFromMastra(value: unknown, reasoningRequired: boolean): NormalizedUsage {","sourceCodeStart":366,"sourceCodeEnd":402,"githubUrl":"https://github.com/JuliusBrussee/caveman/blob/27d5a3981a347890211bb1bf2439e5c821a63bc9/packages/agent/src/adapters.ts#L366-L402","documentation":"Returned by validateRuntimeIdentity when the connected role is superuser, has the BYPASSRLS attribute, or directly owns a tenant table (a table in public with an organization_id column). Any of the three would let the runtime connection circumvent row-level security, so the pool refuses to start. This is the hard security gate of the runtime-pool design: privileged identities are structurally excluded, not merely discouraged.","triggerScenarios":"DATABASE_URL pointing at the postgres superuser or the table owner; a role created with BYPASSRLS; migrating tables while logged in as the runtime role so it became the owner of new tenant tables; managed-database default users (e.g. cloudsqlsuperuser) that inherit superuser-like attributes.","commonSituations":"Copy-pasting the admin URL from a deploy guide into the app's secret; running migrations as the same role the app uses, transferring ownership of new tables to it; granting the runtime role ownership 'temporarily' and forgetting; RDS/Cloud SQL master accounts with bypassrls-like privileges.","solutions":["Create a least-privileged LOGIN role (NOLOGIN off, NOSUPERUSER, NOBYPASSRLS) that owns no tenant tables, grant it only DML + EXECUTE, and use it in DATABASE_URL","Run migrations as a separate privileged role so tenant tables are never owned by the runtime role","Check the flags: SELECT rolSuper, rolBypassRLS FROM pg_roles WHERE rolname = current_user; and ownership: SELECT relname FROM pg_class WHERE pg_get_userbyid(relowner) = current_user;","For managed Postgres, avoid the default admin account; provision a dedicated application login"],"exampleFix":"-- before: app connects as table owner\nCREATE ROLE app LOGIN PASSWORD '...' SUPERUSER;\n\n-- after\nCREATE ROLE app_migrator LOGIN PASSWORD '...';          -- owns schema/tables\nCREATE ROLE app_runtime LOGIN PASSWORD '...' NOSUPERUSER NOBYPASSRLS;\nGRANT USAGE ON SCHEMA public TO app_runtime;\nGRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_runtime;\n-- app_runtime connects; app_migrator runs migrations","handlingStrategy":"validation","validationCode":"// Assert the login is structurally unprivileged before pool construction:\nfunc preflightLeastPrivilege(ctx context.Context, dbURL string) error {\n    conn, err := pgx.Connect(ctx, dbURL)\n    if err != nil { return err }\n    defer conn.Close(ctx)\n    var super, bypass bool\n    var owns int\n    err = conn.QueryRow(ctx, `\n        SELECT pg_is_in_recovery() OR false,  -- placeholder replaced below\n        (SELECT rolsuper OR rolbypassrls FROM pg_roles WHERE rolname = current_user),\n        (SELECT count(*) FROM pg_class c\n           JOIN pg_namespace n ON n.oid = c.relnamespace\n          WHERE n.nspname = 'public' AND pg_get_userbyid(c.relowner) = current_user)`).Scan(new(bool), &super, &owns)\n    _ = bypass\n    if err != nil { return err }\n    if super || owns > 0 {\n        return fmt.Errorf(\"refusing privileged runtime role: super/bypass/owns=%d\", owns)\n    }\n    return nil\n}","typeGuard":"func isUnsafeIdentityErr(err error) bool {\n    return err != nil && strings.HasPrefix(err.Error(), \"postgres: unsafe runtime identity\")\n}","tryCatchPattern":"pool, err := postgresconfig.NewPool(ctx, dbURL)\nif err != nil {\n    if isUnsafeIdentityErr(err) {\n        // Never catch-and-continue: this is a security gate. Fix the role.\n        log.Fatal(\"runtime DB role is privileged (superuser/bypassrls/table owner); provision a least-privileged LOGIN role\")\n    }\n    return err\n}","preventionTips":["Create the app role with NOSUPERUSER NOBYPASSRLS and never let it own tenant tables","Run migrations as a separate migrator role so ownership stays off the runtime login","Include role-attribute assertions in deployment smoke tests: SELECT rolsuper, rolbypassrls FROM pg_roles WHERE rolname = '<app>'","Avoid managed-Postgres default admin accounts for the application connection"],"tags":["postgres","security","rls","roles","least-privilege"],"backgroundTag":null,"analyzedSha":"27d5a3981a347890211bb1bf2439e5c821a63bc9","analyzedAt":"2026-08-15T09:26:11.751Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}