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
Open the Scopes page
Navigate to Developer > Channels and click Create Scope (or open the Scopes tab if visible).
Enter scope details
Provide a Name (required) and an optional Description.
Click Next when done.
| Field | Required | Description |
|---|---|---|
| Name | Yes | A short, human-readable label used to identify the scope when assigning it to embed keys (e.g. Customer read-only, Outlet dashboard) |
| Description | No | Free-text note that helps team members understand what data this scope exposes |
Configure data access
This step has two parts: Row-level scope and Table access.
At query time, Cobi automatically filters every query so that only rows matching the caller’s
Use the Filter tables search box to find specific tables quickly.Click Next when done.
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.| Setting | Description |
|---|---|
| Scope table | The table that owns the tenant identifier (e.g. outlets) |
| Scope column | The primary column in that table that identifies each tenant (e.g. id) |
scopeId value are returned.Table access
Select which tables this scope can query. Tables are grouped to help you make the right choices:| Group | Description |
|---|---|
| Related tables | Tables that contain a foreign key referencing the scope column. These are typically the safest to include because row-level filtering applies to them automatically |
| Other tables | Tables without a direct relationship to the scope column. Queries against these tables will not be row-filtered, so include them only when full-table access is intentional |
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.
| Field | Value |
|---|---|
| Name | The scope name you entered |
| Tables | Number of tables included |
| Row scope | The table.column pair used for filtering, and a note that it is filtered by caller’s scope ID |
Assigning a Scope to an Embed Key
When creating or editing an embed key, the Security step includes a Data scope dropdown:| Option | Behaviour |
|---|---|
| Full access (no scope) | The key can query all tables enabled on the data source. No scopeId parameter is required or used |
| A named scope | The key can only query the tables and rows defined in that scope. A scopeId must be supplied in every iframe URL |
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.| Action | How |
|---|---|
| View | Click on a scope to see its full configuration |
| Delete | Open the scope and click Delete. Any embed key currently using this scope will lose its data access restrictions — review key assignments before deleting |
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.