Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

Scopes as realms

A scope groups related queues. You can also hand it to a team or a service as its own realm: they manage their queues and messages there, without tenant-wide ScaiQueue rights and without seeing other teams' scopes.

Two things make this work:

  • Scope roles. Give a user or a group a role in one scope. The role applies to that scope only.
  • Restricted scopes. Mark a scope restricted and only its members and tenant admins can reach it. To everyone else it doesn't exist (404).

Roles#

Role Can
owner Everything in the scope, including who has access (grants, queue ACL entries, trusted scopes)
operator Create, delete, pause and resume queues; routing rules, schemas, HITL patterns, subscriptions; cancel messages; pause, resume and drain the scope; publish and consume
producer View the scope and publish messages
consumer View the scope; claim, complete, fail, release and extend messages; create subscriptions
viewer Read the scope, its queues, messages, rules, schemas and audit log

Tenant-level actions stay with tenant admins and holders of the tenant-wide scaiqueue:manage permission: creating scopes, archiving, unarchiving and deleting them, and making a scope restricted or unrestricted. An owner can't delete its own scope or open it up.

Letting a service create its own realms#

Give a user (typically a service user) the scaiqueue:create_scopes permission, and it can create scopes itself, for example one per customer:

  • it becomes owner of every scope it creates, and can make it restricted at creation;
  • it can archive, unarchive and delete the scopes it owns;
  • it can't see or touch any other scope, and can't open a restricted scope up later.

Deleting a scope removes everything in it: queues, messages (including archived ones and their attachments), grants, queue ACL entries, trusts, routing rules, subscriptions, streams, schemas and HITL patterns. The scope's audit log is kept.

Who can do what in a scope#

A caller's rights in a scope come from three places, added together:

  1. Tenant level. Tenant admins, partner admins and holders of tenant-wide scaiqueue:manage can do everything in every scope of the tenant, restricted or not.
  2. Tenant-wide permissions, unrestricted scopes only. scaiqueue:view, :publish and :consume work as before on unrestricted scopes. They don't reach restricted scopes.
  3. Scope roles on that scope.

On top of that, per-queue ACL entries can still deny a specific action on one queue, for example to stop a service from approving its own review requests.

A caller with no rights in a scope gets 404, so it can't tell whether the scope exists. A caller who can see the scope but lacks the right for an action gets 403.

Members#

  • Users, by ScaiGrid user id. For an API key, that's the key's owner.
  • Groups, by ScaiKey group id (the local group id is accepted and converted). Members of the group get the role.
  • Members must belong to the scope's tenant. A member has one role per scope: granting again replaces it.
  • A grant can expire: pass expires_at (ISO 8601). Expired grants stop working at once.

Reviewing through another application#

Reviewers often work in another application's console, for example a code-review tool that shows human-in-the-loop requests from a ScaiQueue realm. The reviewers can claim and complete messages under their own identity, so the application never needs a key that can approve:

  1. The reviewer signs in to the application with ScaiKey.
  2. The application exchanges the reviewer's token for a ScaiGrid token, with the RFC 8693 token-exchange grant and audience=scaigrid. The application must be a confidential ScaiKey client that is allowed to exchange tokens.
  3. The application calls ScaiQueue with the exchanged token.

ScaiQueue then decides access on the reviewer, who needs a role in the realm (consumer is enough to claim and complete), and records the reviewer as the one who claimed and completed the message, with the application as via. The same goes for the audit log. A token issued for the application itself is refused (401): ScaiGrid accepts only tokens addressed to ScaiGrid.

Example: a realm for a service#

A service runs as its own user with an API key. Give it a restricted scope and no tenant-wide ScaiQueue permissions:

bash
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# Tenant admin: create the realm
curl -X POST "$SCAIGRID_HOST/v1/modules/scaiqueue/scopes" \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
  -d '{"slug": "ci-pipeline", "display_name": "CI pipeline", "restricted": true}'

# Tenant admin: make the service its operator
curl -X POST "$SCAIGRID_HOST/v1/modules/scaiqueue/scopes/$SCOPE_ID/acl/grants" \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
  -d '{"actor_type": "user", "actor_id": "'$SERVICE_USER_ID'", "role": "operator"}'

# Give the reviewers' group the consumer role
curl -X POST "$SCAIGRID_HOST/v1/modules/scaiqueue/scopes/$SCOPE_ID/acl/grants" \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
  -d '{"actor_type": "group", "actor_id": "grp_reviewers", "role": "consumer"}'

The service can now create its own queues and publish and consume in ci-pipeline, and nothing else. GET /scopes shows it only that scope, with my_role and capabilities.

In the admin UI: ScaiQueue → Create scope → Restricted, then the scope's Access section → Add Grant.

Compared with Scuttle realms#

If you know Scuttle: a ScaiQueue scope is the counterpart of a Scuttle realm. owner, operator and viewer match Scuttle's realm admin, operator and viewer; producer and consumer are extra, because queues have a data side that databases don't.

Updated 2026-10-19 16:21:00 View source (.md) rev 6