Access Rules
Control which artifacts and jobs can access which tables, secrets, connectors, and external endpoints — principle of least privilege for your SDK code.
Every artifact runs with a set of permissions determined by its access rules. By default a new artifact has no permissions — you explicitly grant what it needs. Rules are configured at SDK → Access Rules and enforced at runtime.
PermissionDeniedError and fail the execution. The error is visible in the execution log with the specific resource that was denied.Rule Types
Table Access
Grant read and/or write access to specific tables:
{
"type": "table",
"table": "incidents",
"operations": ["read", "create", "update"],
"condition": null // optional row-level filter
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| table | string | required | — | Table slug, or "*" for all tables. |
| operations | string[] | required | — | Allowed operations: read | create | update | delete | sql |
| condition | object | optional | — | Row-level filter — artifact can only access records matching this filter. |
| columns | string[] | optional | — | Column-level restriction. null = all columns. |
Row-Level Conditions
// Only allow reading incidents owned by the artifact's workspace
{
"type": "table",
"table": "incidents",
"operations": ["read"],
"condition": { "severity": ["P1", "P2"] } // only P1/P2 incidents
}
// Only allow updating unresolved tickets
{
"type": "table",
"table": "incidents",
"operations": ["update"],
"condition": { "status": { "nin": ["resolved", "closed"] } }
}Secret Access
{
"type": "secret",
"secret": "GITHUB_WEBHOOK_SECRET" // specific secret key, or "*" for all
}Connector Access
{
"type": "connector",
"connector": "github-prod", // connector ID or "*"
"operations": ["read", "write"] // read | write | admin
}HTTP Access
By default artifacts cannot make outbound HTTP requests. Grant access to specific hosts:
{
"type": "http",
"hosts": [
"api.github.com",
"api.pagerduty.com",
"*.datadoghq.com" // wildcard subdomains
],
"methods": ["GET", "POST"]
}Event Bus Access
{
"type": "event",
"topics": ["incident.*", "github.push"],
"operations": ["publish", "subscribe"]
}Notification Access
{
"type": "notification",
"channels": ["email", "slack"],
"templates": ["incident-assigned", "incident-resolved"] // null = any template
}Policy Sets
Rather than configuring rules per artifact, create a named policy set and apply it to multiple artifacts. Updates to the policy set apply immediately to all attached artifacts.
{
"name": "ITSM Read-Write",
"description": "Standard permissions for artifacts that process ITSM records",
"rules": [
{ "type": "table", "table": "incidents", "operations": ["read", "update"] },
{ "type": "table", "table": "problems", "operations": ["read", "update"] },
{ "type": "table", "table": "changes", "operations": ["read"] },
{ "type": "table", "table": "cmdb_items", "operations": ["read"] },
{ "type": "event", "topics": ["incident.*"],"operations": ["publish"] },
{ "type": "notification", "channels": ["email", "in_app"], "templates": null }
]
}Applying Rules to Artifacts
In the artifact editor, go to Security tab → Access Rules. You can apply individual rules or attach a policy set. Multiple policy sets and individual rules are merged — the resulting effective permissions are shown in the Effective Permissions summary.
Access Audit
A failed runtime permission check throws immediately and returns an HTTP 403 with the message You do not have Flow SDK access to <action> — it does not currently write a dedicated access-denied audit entry. To review who did what, use the workspace Audit Log instead:
GET /api/audit
?action=execute