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.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.
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: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:
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.
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.
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.