Overview
A data scope defines the exact slice of your database that an embed key is allowed to access. Instead of granting an embed key unrestricted access to every table in your data source, you create a named scope that specifies:- Which tables the key may query
- Which row-level filter should be applied so that each caller only sees their own rows
A
scopeId URL parameter is required whenever an embed key has a data scope
assigned to it. Requests without a valid scopeId will be rejected with a
403 error.Creating a Scope
1
Open the Scopes page
Navigate to Developer > Channels and click Create Scope (or open the Scopes tab if visible).
2
Enter scope details
Provide a Name (required) and an optional Description.
Click Next when done.
3
Configure data access
This step has two parts: Row-level scope and Table access.
Row-level scope
Row-level scoping restricts each caller to only the rows that belong to them. It is required for multi-tenant deployments where different end-users must not see each other’s data.At query time, Cobi automatically filters every query so that only rows matching the caller’s
scopeId value are returned.Table access
Select which tables this scope can query. Tables are grouped to help you make the right choices:Use the Filter tables search box to find specific tables quickly.Click Next when done.
4
Review and create
The Review scope screen summarises your configuration:
Click Create scope to save. The scope is immediately available for assignment to embed keys.
Assigning a Scope to an Embed Key
When creating or editing an embed key, the Security step includes a Data scope dropdown:Using scopeId in the Iframe URL
When an embed key has a data scope assigned, every iframesrc must include the scopeId parameter. The value should be the identifier of the tenant or entity whose data the current user is allowed to see — typically the primary key value from the scope table.
scopeId to filter all queries at the row level. In the example above, queries against the outlets scope table would automatically include WHERE outlets.id = 'outlet_42', and all related table queries would be filtered accordingly.
Render the
scopeId server-side from your own authentication system. Never
derive it from user-supplied input or client-side storage, as this would allow
a user to spoof another tenant’s ID.What happens without scopeId
If a request is made to an embed key that has a scope assigned but noscopeId is provided, Cobi returns a 403 error and the widget displays an access-denied message. This is intentional — a missing scopeId is treated as an unauthorised request.
Managing Scopes
From Developer > Channels (Scopes tab) you can view all scopes along with the number of tables and their row-scope configuration.Security Considerations
- Scope isolation — each embed key can only be assigned one scope. There is no way for a key to escalate beyond its assigned scope at runtime.
- Row-level enforcement — Cobi enforces row-level filtering server-side. It cannot be bypassed by modifying the iframe URL or the chat query.
- scopeId is not a secret — the
scopeIdvalue is visible in the iframesrc. It should only identify which tenant, not authenticate the request. Authentication is handled by the embed key itself. Always combinescopeIdwith domain restrictions (allowed origins) in production. - Minimal table access — follow the principle of least privilege: only include the tables your widget actually needs. Excluding sensitive tables from the scope is the safest way to prevent unintended data exposure.