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

SCSG verb reference

SCSG is the sub-protocol server-side services (ScaiWave, ScaiTerm, ScaiDrive-server, ScaiEdit-server) use to obtain bounded, user-consented clipboard access. It runs on its own WebSocket endpoint separate from the user-facing scaiclip/1.

For the conceptual model, see Server-side integrations.

Endpoint#

text
1
wss://scaigrid.scailabs.ai/v1/modules/scaiclip/scsg/ws

Sub-protocol string: scsg/1.

Auth: OAuth2 client_credentials JWT via ?token=<jwt> query param or Authorization: Bearer <jwt> header. The token's sub claim (== client_id) must correspond to a registered service_id in the SCSG registry.

Naming convention (M1): client_id starts with cli_<service_id>_… (e.g. cli_scaiwave_prod_a1b2c3). Future ScaiKey versions will carry service_id as an explicit claim.

Verbs#

Client (service) → grid#

Type Verb Body Response
0x60 session.open `{1: session_id, 2: user_id, 3: ephemeral_kem_pub, 4: ephemeral_sig_pub, 5: {1: channel_ids 'user_default', 2: capabilities}, 6: duration_max_s, 7: reason}`
0x61 session.close {1: grant_id, 2: reason} {1: 'closed', 2: closed_at_ms}
0x63 session.list {} {1: [{1: grant_id, 2: service_id, 3: user_id, 4: status, 5: capabilities, 6: expires_at_ms}]}

Grid → service push#

Type Event Body
0xA1 session.ready {1: grant_id, 2: [channel_id_bytes], 3: expires_at_ms, 4: consenting_device_id}
0xA2 session.denied {1: grant_id, 2: reason}
0xA3 session.expired {1: grant_id}
0xA4 session.revoked {1: grant_id, 2: reason}

User-side (scaiclip/1 endpoint)#

Type Verb Body Response
0x62 session.deny {1: grant_id, 2: reason} {1: 'denied'}
0xA0 session.grant_request (grid → user) {1: grant_id, 2: service_id, 3: reason, 4: {1: channel_ids, 2: capabilities}, 5: duration_max_s, 6: ephemeral_sig_pub, 7: consent_deadline_ms, 8: display_name}

User consents by installing wraps for the ephemeral device via the standard key.wraps.put verb targeting dev_scsg_<service_id>_<session_id>. The grid's implicit-consent hook detects this pattern and transitions the grant to active.

Capabilities bitfield#

scope.capabilities is a u32 with these flags:

Bit Name Description
0x01 READ Subscribe + fetch (clip.fetch, channel.sync)
0x02 WRITE Publish (clip.publish)
0x04 CLAIM Consume one-shot clips (subject to tenant policy)
0x08 SCRATCH_READ Read scratch objects
0x10 SCRATCH_WRITE Upload scratch objects
0x20 PUBLIC_SHARE Mint public share links

Services SHOULD request the minimum bit set for their function. Consent UIs enumerate capabilities in human terms.

Service registry#

Only pre-registered service_id values may open sessions.

service_id Display Default capabilities
scaiwave ScaiWave (voice) READ · WRITE
scaiterm ScaiTerm (terminal) READ · WRITE · CLAIM
scaidrive ScaiDrive (files) READ · SCRATCH_READ · SCRATCH_WRITE
scaiedit ScaiEdit (editor) READ · WRITE · SCRATCH_READ

Unlisted service_idE_UNKNOWN_SERVICE.

Third-party service integration requires a manual registration step (email platform@scailabs.ai) plus a ScaiKey OAuth app.

Tenant policy#

Each service must be opted in by the tenant admin:

Column in mod_scaiclip_tenant_policy Default
allow_scsg_scaiwave false
allow_scsg_scaiterm false
allow_scsg_scaidrive false
allow_scsg_scaiedit false
allow_agent_claim false — gates the CLAIM capability regardless of service
max_session_duration_s 14400 (4 hours) — clamps duration_max_s

Missing tenant policy row → all flags default false. Attempting session.open for a service the tenant hasn't opted into → E_FORBIDDEN.

Rate limits#

Limit Setting Default
session.open per (tenant, service_id) scaiclip_scsg_session_open_per_s / _burst 5/s, burst 20
Concurrent sessions per (tenant, service_id) scaiclip_scsg_max_concurrent_per_service 100
Consent window scaiclip_scsg_consent_window_s 60 s
Absolute max session duration scaiclip_scsg_absolute_max_duration_s 4 h
Expiry sweep cadence scaiclip_scsg_expiry_sweep_s 30 s

Audit stream#

Every SCSG lifecycle event lands in audit_log:

scdoc
1
2
3
4
5
6
7
8
scaiclip.scsg.session_opened
scaiclip.scsg.session_granted
scaiclip.scsg.session_denied
scaiclip.scsg.session_closed
scaiclip.scsg.session_expired
scaiclip.scsg.session_revoked
scaiclip.scsg.out_of_scope_denied
scaiclip.scsg.unknown_service

Every row's details field carries service_id, grant_id, user_id, capabilities, duration_max_s, and where applicable consenting_device_id.

Reference client#

The Python reference client at modules/scaiclip/services/scsg_client.py (in the ScaiGrid repo) wraps the WS protocol so consumer services call open_session / wait_ready / close_session async methods without touching CBOR.

Updated 2026-07-12 00:26:08 View source (.md) rev 5