Source write grants
Authorize a caller for a supported source endpoint with bounded operations
A source-write grant identifies which caller may mutate a particular supported endpoint, with explicit operation and target limits. It is separate from a write policy's semantics and from an API key's operation scopes.
You need a Semogram account with workspace management access, or an org:manage key, to manage endpoint grants. Configure a supported Iceberg endpoint, its approved workspace-wide policy and the workspace's source-write mode first. Current durable source mutations use the Iceberg plugin.
Review before granting
Identify the exact endpoint UUID, real subject (member/API key as supported by the grant contract), allowed mutations, writable fields and required equality predicates. Read the endpoint's current policy revision and source snapshot. Do not grant broad update/delete access just to make an append test work.
| Layer | Check |
|---|---|
| Workspace mode | read_write for the governed source path |
| Endpoint | Supported Iceberg target and installed capability |
| Policy | Approved workspace revision bound to this endpoint |
| Caller | Correct member/key identity, permissions and resource reach |
| Grant | Allowed operation, target and configured bounds |
| Request | Expected current source snapshot and unique operation identity |
Configure and inspect
Use the endpoint's supported source-write access controls to bind its policy and manage caller grants. API routes are available for GET/PUT /api/v1/data-endpoints/<ENDPOINT_UUID>/source-write-policy and GET/POST /api/v1/data-endpoints/<ENDPOINT_UUID>/source-write-grants; deleting a grant uses its grant-ID route.
The policy body is { "writePolicy": { "id": "<POLICY_UUID>", "version": 1 } }; null clears the binding. Endpoint policies must be workspace-wide and usable. Read the actual source-write grant schema before submitting a grant; a named read grant is not a source-write grant.
MCP exposes source_write_policy_get/bind and source_write_grant_list/save/delete with their documented schemas. Inspect grant save and its complete schema, then read back grant list. A connected assistant can prepare a bounded proposal using those actual fields; review the exact caller and target before authorizing it.
Example: restrict an equipment-status update
Assume a dedicated Iceberg equipment table has equipment_id, tenant_id and status. Its endpoint has an approved workspace-wide update policy keyed by equipment_id. The workspace source-write mode is read_write. The service key is active, has data:write and the necessary workspace-resource access. Give it only updates to status on tenant_id = factory-a.
Open the endpoint's source-write access panel. Select the approved policy revision. Under Add or update caller grant choose the exact API caller, enable update only, set Writable fields to status and Required record matches to tenant_id / factory-a. Select Save grant and inspect Caller write access. The form selects API keys; user principals are supported by the programmatic grant contract.
Ask the management assistant to prepare an update-only grant for this exact equipment endpoint and service key, allowing only status and requiring tenant_id equal to factory-a. Review the endpoint policy and caller scopes first; read back the saved grant. Do not broaden it to append/delete or unrestricted records.
With an org:manage key, POST the complete body below to /api/v1/data-endpoints/<ENDPOINT_UUID>/source-write-grants. Substitute the same real endpoint UUID in the path/body and the service key UUID in principal.id.
{
"endpointId": "<ENDPOINT_UUID>",
"principal": { "kind": "api_key", "id": "<SERVICE_KEY_UUID>" },
"operations": ["update"],
"writableFields": ["status"],
"equalityPredicates": { "tenant_id": "factory-a" }
}GET the same route to inspect the grant. Saving replaces the existing grant for that endpoint/principal. Delete the returned grant ID through the grant-ID route when access should end.
Call source_write_grant_save on the workspace connection with { "grant": <the complete object above>, "idempotencyKey": "<UNIQUE_GRANT_KEY>" }. This is the tool's arguments object; send it through the initialized MCP client. Read back source_write_grant_list for the exact endpoint.
For updates/deletes the request must include the granted equality condition in its where predicates. For append/upsert every written row must carry the granted value. Fields that a request sets must fit writableFields. Empty writableFields does not mean all fields, and the grant does not have an expiry or row-limit field. Key expiry and request limits remain separate controls.
Test and revoke
Execute a bounded test mutation against a dedicated target and inspect its receipt and resulting snapshot. Test that a disallowed mutation or caller is rejected. Use source_write_execute for the operation contract and source_write_recover to inspect an uncertain original operation without blindly writing again.
Delete an obsolete grant and verify new requests are denied. Removing the grant or policy binding does not undo records already written. A lost response is not proof that a write did not commit.