Skip to main content

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
Scopes are created independently of embed keys and then assigned to a key during key creation. One scope can be shared across many keys.
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.
FieldRequiredDescription
NameYesA short, human-readable label used to identify the scope when assigning it to embed keys (e.g. Customer read-only, Outlet dashboard)
DescriptionNoFree-text note that helps team members understand what data this scope exposes
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.
SettingDescription
Scope tableThe table that owns the tenant identifier (e.g. outlets)
Scope columnThe primary column in that table that identifies each tenant (e.g. id)
At query time, Cobi automatically filters every query so that only rows matching the caller’s scopeId value are returned.
If all callers should see the same data (e.g. a public read-only widget), leave row-level scoping unconfigured and rely on table access restrictions alone.

Table access

Select which tables this scope can query. Tables are grouped to help you make the right choices:
GroupDescription
Related tablesTables 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 tablesTables 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
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:
FieldValue
NameThe scope name you entered
TablesNumber of tables included
Row scopeThe table.column pair used for filtering, and a note that it is filtered by caller’s scope ID
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:
OptionBehaviour
Full access (no scope)The key can query all tables enabled on the data source. No scopeId parameter is required or used
A named scopeThe key can only query the tables and rows defined in that scope. A scopeId must be supplied in every iframe URL
Selecting a scope on an embed key is permanent for that key. To change the scope, create a new embed key with the desired scope and revoke the old one.

Using scopeId in the Iframe URL

When an embed key has a data scope assigned, every iframe src 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.
<iframe
  src="https://app.hellocobi.com/embed/chat?key=cobi_embed_your_key_here&scopeId=outlet_42"
  style="width: 100%; height: 600px; border: none; border-radius: 8px;"
  allow="clipboard-write"
  title="Cobi Chat"
></iframe>
Cobi uses 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 no scopeId 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.
ActionHow
ViewClick on a scope to see its full configuration
DeleteOpen the scope and click Delete. Any embed key currently using this scope will lose its data access restrictions — review key assignments before deleting
Deleting a scope does not automatically revoke the embed keys assigned to it. Those keys will revert to having no scope, potentially exposing more data than intended. Audit your embed keys after any scope deletion.

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 scopeId value is visible in the iframe src. It should only identify which tenant, not authenticate the request. Authentication is handled by the embed key itself. Always combine scopeId with 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.