Documentation Index
Fetch the complete documentation index at: https://formbricks.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
Context
XM analytics reads Hub feedback records through Cube. Hub stores all tenants in a sharedfeedback_records
table and uses tenant_id to separate rows. Workspace access is the application authorization boundary. In the
current Hub schema, tenant_id stores the authorized FeedbackDirectory ID, so every Cube query must be
scoped to a directory that the authenticated workspace can access before data leaves Cube.
Threat Model
The main risk is cross-tenant read access through an unscoped Cube query. The attacker could be a regression in server code, an AI-generated query that includes malicious filters, a copied static token, or a direct request to Cube from inside the deployment network. The controls assume query bodies are attacker-influenced. Tenant identity is never trusted from the query JSON.Enforcement Flow
Authorize workspace access
Server actions and server components authorize workspace access in the Next.js app.
Validate the Cube query
The app validates the Cube query and rejects any
FeedbackRecords.tenantId member supplied by users,
saved charts, or AI output, including filters, dimensions, time dimensions, and order clauses.Mint a short-lived JWT
The app mints a short-lived JWT per Cube request with
tenantId, feedbackDirectoryId,
workspaceId, organizationId, userId, scope, iss, aud, jti, and exp claims.Audit Evidence
The app records a sanitizedcubeQuery audit event for each Cube query attempt, keyed by the JWT jti. Cube also
emits a structured audit log line from queryRewrite with tenant, feedback directory, workspace,
organization, user, request ID, source, and queried member names. Raw filter values are intentionally omitted from
both logs.
Operational Notes
CUBEJS_API_SECRET is a signing secret, not an access token. Do not pass it to clients or reuse it as a bearer
token. Set CUBEJS_JWT_ISSUER and CUBEJS_JWT_AUDIENCE consistently for the web app and Cube so Cube rejects
tokens minted for any other audience or issuer. Set CUBEJS_DEFAULT_API_SCOPES=meta,data for Cube deployments so
GraphQL, SQL, and orchestration APIs are not exposed unless explicitly needed. Network isolation for Cube remains
recommended, but JWT-backed queryRewrite is the mandatory data boundary.