API reference
Access rules
Who may reach which app, from which device, under which conditions.
Explain access for a device
GET/v0/tenants/{tenant_id}/explain-access
Answers "why can (or can't) this device reach this app?" without changing anything. It walks both gates in order — trust (is the device trusted, and is that required?) then access (does an enforced allow rule grant this device, its person or one of their groups?) — and explains each in plain English, including the device checks a rule needs that the device fails. Pass device plus either connection or private_network.
Token: read-only or full access · Created by: owner or security admin
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Query parameters
- devicestringrequired
Device id.
- connectionstring
App id to check. Use this or
private_network. - private_networkstring
Private network id to check instead of an app.
Responses
200 The verdict per gate.
application/json
- devicestringrequired
Device id.
- device_namestring | null
- personstring | null
Person name.
- groupsarray of string
Group ids of the device's person.
- connectionstring
App id (when an app was checked).
- private_networkstring
Private network id (when a private network was checked).
- resource_kindstring
- resource_namestring
- verdictstringrequired
- reachablebooleanrequired
- blocked_atstring | null
The gate that blocks (null when reachable).
- gatesarray of objectrequired
Trust gate first, then access gate.
gates fields
- gatestring
- labelstring
- passboolean
- detailstring
Plain-English explanation.
- trustTrustVerdict
trust fields
- statestringrequired
- reasonstringrequired
Plain-English reason.
- unmetarray of object
The conditions the device fails (from the first trust rule tried).
unmet fields
- kindstring
e.g.
posture,group,network,reauth. - fieldstring | null
- opstring
- valueany
- gotany
What the device reported (null = not reported).
- textstring
Plain-English explanation.
- evaluated_atstring (date-time)
- sourcestringrequired
rule= trust rules decided;manual= an admin marked the device;default= no trust rules exist;policy= re-authentication or suspension. - matched_rulestring
The trust rule that trusted the device (when
sourceisruleand the state istrusted).
- admission_enforcedboolean
Trust gate: untrusted devices are kept off the network entirely.
- matched_ruleobject | null
Access gate: the rule that grants access.
matched_rule fields
- idstring
- namestring
- consideredarray of object
Access gate: every allow rule targeting the resource.
considered fields
- rulestring
- namestring
- enforcedboolean
- enforcement_reasonstring | null
- grantsboolean
- missing_posturearray of string
Device checks the device fails for this rule;
!field= must be false.
400 valid-device-query-param-required valid-connection-query-param-required valid-private-network-query-param-required
valid-device-query-param-required: device is missing or is not a device in this workspace.
valid-connection-query-param-required: Neither a known connection nor private_network was given.
valid-private-network-query-param-required: private_network is not a private network in this workspace.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/explain-access?device=dvc_5mxq2b7r8k" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/explain-access?device=dvc_5mxq2b7r8k" -Headers $headersimport os, uuid, requests
r = requests.get(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/explain-access?device=dvc_5mxq2b7r8k",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/explain-access?device=dvc_5mxq2b7r8k", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"device": "dvc_5mxq2b7r8k",
"device_name": "FIN-LT-014",
"person": "Dana Levi",
"groups": [
"g3k9d0s7aa"
],
"connection": "cx9m2v7d1pa",
"resource_kind": "connection",
"resource_name": "erp-db",
"verdict": "BLOCKED",
"reachable": false,
"blocked_at": "access",
"gates": [
{
"gate": "trust",
"label": "Trust (admission)",
"pass": true,
"detail": "Device is trusted → admitted to the overlay.",
"trust": {
"state": "trusted",
"reason": "matched trust rule \"Company laptops\"",
"unmet": [],
"evaluated_at": "2026-10-13T09:24:11.000Z",
"source": "rule",
"matched_rule": "tr_4m8s2k0x9q"
},
"admission_enforced": true
},
{
"gate": "access",
"label": "Access (authorization)",
"pass": false,
"detail": "Rule \"Finance → ERP from encrypted laptops\" applies to this device, but it fails required device checks: Disk encryption (BitLocker) is off.",
"matched_rule": null,
"considered": [
{
"rule": "pr_7xk2m9c0d1",
"name": "Finance → ERP from encrypted laptops",
"enforced": true,
"enforcement_reason": null,
"grants": false,
"missing_posture": [
"disk_encrypted"
]
}
]
}
]
}Get the condition catalog
GET/v0/tenants/{tenant_id}/policy-rule-catalog
Lists every condition type, field and operator that access and trust rules accept, the allowed values (OS families, second-step methods, …) and notes on what is enforced. The catalog is the same for every workspace; it carries an ETag, so send If-None-Match to get 304 Not Modified when it has not changed.
Token: read-only or full access · Created by: owner or security admin
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Responses
200 The catalog.
application/json
- generated_atstring (date-time)
When this catalog version was published.
- typesarray of objectrequired
types fields
- typestring
Leaf
type. - value_typestring | null
- notestring
- operatorsarray of object
operators fields
- operatorstring
- aritystring
scalar,list,range,window,day_set. - value_typestring
- notestring
- fieldsarray of object
fields fields
- fieldstring
- operatorsarray of string
- value_typestring
- notestring
- valuesarray of object
Allowed ids with labels (e.g. OS families, second-step methods).
values fields
- idstring
- labelstring
- evaluatedany
Where the leaf is evaluated (
false= stored but not evaluated yet). - enforced_at_edgeboolean
False when the leaf cannot be enforced in an access rule.
304 If-None-Match matches the current catalog.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rule-catalog" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rule-catalog" -Headers $headersimport os, uuid, requests
r = requests.get(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rule-catalog",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rule-catalog", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"generated_at": "2026-10-06T00:00:00Z",
"types": [
{
"type": "group",
"value_type": "group_ref",
"operators": [
{
"operator": "in",
"arity": "list",
"value_type": "group_id_list",
"note": "value = [immutable group id, …] (directory, SCIM or local groups)"
}
]
},
{
"type": "posture",
"value_type": null,
"fields": [
{
"field": "disk_encrypted",
"operators": [
"eq"
],
"value_type": "bool",
"note": "OS volume encrypted (BitLocker on)"
}
],
"operators": [
{
"operator": "eq",
"arity": "scalar",
"value_type": "bool"
}
]
}
]
}List access rules
GET/v0/tenants/{tenant_id}/policy-rules
Returns the access rules in the workspace, oldest first, with whether each is live at the edge (enforced) and why not. Cloudraw is deny-by-default: an app is reachable only through an enforced allow rule. Pass limit to page: next_cursor is non-null while more rules follow; pass it back as cursor to get the next page. Without limit every rule comes back in one answer.
Token: read-only or full access · Created by: owner or security admin
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Query parameters
- effectstring
Only rules with this effect.
- limitinteger
Page size, 1-200 (above 200 = 200). Leave it out to get every rule in one answer.
- cursorstring
The
next_cursorof the previous page, unchanged.
Responses
200 Access rules (one page when limit is set).
application/json
- itemsarray of PolicyRulerequired
items fields
- idstringrequired
Access rule id.
- namestringrequired
1-128 characters.
- effectstringrequired
- enabledboolean
False when the rule is turned off: it then has no effect at all. Default true.
- targetRuleTargetrequired
What the rule grants. Exactly one of the three fields.
target fields
- service_idstring
An app (connection) id in this workspace.
- private_network_idstring
A private network id in this workspace. Private networks also require a trusted device unless the network is set otherwise.
- service_rolestring
Advanced: an app role of this workspace (it starts with your workspace id and a dash). Cannot name private networks.
- matchConditionNoderequired
One node of a condition tree: a group node (
op+children) or a leaf (type+operator+value). See the table in Create an access rule.match fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- enforcedbooleanrequired
True when the rule is live at the edge. An
allowrule that is not enforced grants nothing. Adenyrule is enforced when it removes access at the edge for everyone it matches. - enforcement_reasonstring | null
Why the rule is not enforced (null when it is).
- enforcement_statusstring
fail_closed(deny rules only): a condition can't be checked yet, so the deny is applied to everyone it could match.off: the rule is turned off. - traffic_effectstring
Plain-English summary of what the rule does to traffic right now.
- form_representableboolean
True when the console can show and edit the rule in its simple form.
- form_viewRuleFormView
The rule read as the console's simple form: Include / Require / Except. Present only when
form_representableis true.form_view fields
- includearray of ConditionNoderequired
Who the rule applies to (one OR list): group / person / device / simple attribute leaves, decorated with
resolved_groups,resolved_peopleorresolved_devices.include fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- requirearray of ConditionNoderequired
Conditions that must all hold (posture, time, mfa, attribute).
require fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- excludearray of ConditionNoderequired
Who is excluded (the negated OR list).
exclude fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- versionintegerrequired
Increases on every change. Send it as
If-Matchon PATCH and DELETE. - created_atstring (date-time)
- updated_atstring (date-time)
- next_cursorstring | null
Opaque cursor for the next page; null on the last page.
400 invalid-limit invalid-cursor
invalid-limit: limit is not a whole number of at least 1.
invalid-cursor: cursor is not a next_cursor from this list.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
curl -sS -X GET "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Get -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules" -Headers $headersimport os, uuid, requests
r = requests.get(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules", {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"items": [
{
"id": "pr_7xk2m9c0d1",
"name": "Finance → ERP from encrypted laptops",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
},
"enforced": true,
"enforcement_reason": null,
"enforcement_status": "active_at_edge",
"traffic_effect": "Allowed for the groups, people or devices it names — live at the edge now.",
"form_representable": true,
"form_view": {
"include": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
],
"resolved_groups": [
{
"id": "g3k9d0s7aa",
"display_name": "Finance",
"state": "active"
}
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
],
"resolved_people": [
{
"id": "p4hd8s0qk2l",
"display_name": "Omer Katz",
"email": "omer.katz@example.com",
"state": "active"
}
]
}
],
"require": [
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
],
"exclude": []
},
"version": 3,
"created_at": "2026-10-02T07:41:09.000Z",
"updated_at": "2026-10-13T09:24:11.000Z"
},
{
"id": "pr_2d8s0k9x1m",
"name": "Contractors → ERP office hours",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "time",
"operator": "within",
"value": {
"tz": "Asia/Jerusalem",
"start": "08:00",
"end": "18:00"
}
}
]
},
"enforced": false,
"enforcement_reason": "condition \"time/within\" is not yet enforceable at the overlay; left deny to avoid over-permitting",
"enforcement_status": "not_at_edge",
"traffic_effect": "DENIED right now — this rule cannot be applied at the edge yet, so it grants NO access. condition \"time/within\" is not yet enforceable at the overlay; left deny to avoid over-permitting",
"form_representable": true,
"form_view": {
"include": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
],
"resolved_groups": [
{
"id": "g3k9d0s7aa",
"display_name": "Contractors",
"state": "active"
}
]
}
],
"require": [
{
"type": "time",
"operator": "within",
"value": {
"tz": "Asia/Jerusalem",
"start": "08:00",
"end": "18:00"
}
}
],
"exclude": []
},
"version": 1,
"created_at": "2026-10-09T12:00:00.000Z",
"updated_at": "2026-10-09T12:00:00.000Z"
}
],
"next_cursor": null
}Create an access rule
POST/v0/tenants/{tenant_id}/policy-rules
Creates an access rule and applies it at the edge immediately; the answer tells you whether it is live (enforced). A rule Cloudraw cannot enforce exactly as written is saved but grants nothing, so it never allows more than you wrote. Deny wins: a deny rule removes access, at the edge, from the people and devices it matches, whatever allow rule, group or temporary access would let them in. Apart from that there is no rule priority: a device reaches an app when an enforced allow rule grants it and no deny rule matches it. Use Preview a change first to see who gains and who loses access. Audited. A change that gives access (an allow turned on, any condition / target edit of an enabled rule, a deny turned off or made an allow) is made in the Cloudraw console: API tokens get 403 widening-console-only.
Token: full access · Created by: owner
Idempotency: send Idempotency-Key to retry safely — the same key and body within 24 h returns the first answer.
### Conditions (match)
A condition tree. Every node is either a group node or a leaf.
Group node — { "op": "and" | "or", "children": [ …nodes ], "negate"?: true }. and = all children must hold, or = at least one. negate: true on an or node marks an *exclude* list (shown as "Except" in the console).
Leaf — { "type", "field"?, "operator", "value" }:
| type | field | operator | value | |---|---|---|---| | group | – | in, not_in | group ids (from the Groups API) | | person | – | in | 1-200 person ids | | device | – | in | 1-200 device ids | | email | – | in | 1-200 e-mail addresses (deny rules only: a person's, or a vendor's on a temporary-access grant) | | jit_grant | – | in | 1-200 temporary-access grant ids (deny rules only) | | posture | managed, domain_joined, workgroup, entra_joined, mdm_enrolled, disk_encrypted, antivirus_on, antivirus_present, edr_present, firewall_on, os_up_to_date, screen_lock | eq | true or false | | posture | computer_type | in | non-empty subset of ["domain","workgroup"] | | posture | os_in | in | 1-20 OS family ids: windows, macos, linux, android, ios | | network | country | in, not_in | ISO 3166 alpha-2 codes, e.g. ["IL","NL"] | | network | ip | in, not_in | IP addresses or CIDRs | | network | asn | in, not_in | integers | | network | risk | eq / in | vpn, tor, hosting, anonymizer, proxy (one / a list) | | time | – | within | { "tz": "<IANA zone>", "start": "HH:MM", "end": "HH:MM" } | | time | – | day_in | subset of mon…sun | | mfa | satisfied / method_in / max_age_seconds | same as field | boolean / method ids / 60-2592000 | | app | – | publisher_eq / hash_in / signed | string / non-empty list / boolean | | attribute | attribute name | eq, ne, contains, starts_with, ends_with, regex, in, not_in, gt, gte, lt, lte, between | scalar / list / number / {from,to}; regex ≤ 512 characters, linear-time only |
Get the full, machine-readable list (with labels) from Get the condition catalog.
What is actually enforced. Every leaf above is validated and stored, but not every leaf is evaluated yet: - *Allow rules* are enforced only when they are built from group in, person in, device in, posture eq true/false / computer_type and mfa (satisfied: true, method_in, max_age_seconds) leaves, combined with and / or (no negate), with a group, person or device in every combination, and at most 16 combinations. Anything else is saved but grants nothing (enforced: false, with the reason in enforcement_reason). mfa leaves are judged on the device's last verified second step (its own Cloudraw Connect sign-in), never on an admin flag. - *Deny rules* win over every allow rule, group, direct grant and temporary (just-in-time) access of the people and devices they match. They must name one app (service_id), one private network (private_network_id) or every app (service_role <tenant>-services). They evaluate group, person, device, posture, mfa and network (country, asn, risk) leaves; an input that is unknown (no fresh health report, no location, a browser with no device) counts as matching. A deny with a time, app, attribute or network ip leaf is applied to everyone it could match (enforcement_status: fail_closed). - *Trust rules* evaluate group, person, device, posture (including os_in), network and mfa leaves. time, app and attribute leaves are never met yet. - Turn a rule off with enabled: false (it then has no effect) and on again with enabled: true. Preview a change shows who gains and who loses access before you save it. - A device health report older than 60 minutes counts as *not reported*: it matches neither true nor false.
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Headers
- Idempotency-Keystring
A unique value (e.g. a UUID) per logical operation. Retrying with the same key and body within 24 hours returns the first answer instead of doing the work twice.
Request body application/json
- namestringrequired
1-128 characters.
- effectstringrequired
- enabledboolean
Default true. False saves the rule turned off.
- targetRuleTargetrequired
What the rule grants. Exactly one of the three fields.
target fields
- service_idstring
An app (connection) id in this workspace.
- private_network_idstring
A private network id in this workspace. Private networks also require a trusted device unless the network is set otherwise.
- service_rolestring
Advanced: an app role of this workspace (it starts with your workspace id and a dash). Cannot name private networks.
- matchConditionNoderequired
One node of a condition tree: a group node (
op+children) or a leaf (type+operator+value). See the table in Create an access rule.match fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
Responses
201 The rule as stored, with its enforcement status.
application/json
- idstringrequired
Access rule id.
- namestringrequired
1-128 characters.
- effectstringrequired
- enabledboolean
False when the rule is turned off: it then has no effect at all. Default true.
- targetRuleTargetrequired
What the rule grants. Exactly one of the three fields.
target fields
- service_idstring
An app (connection) id in this workspace.
- private_network_idstring
A private network id in this workspace. Private networks also require a trusted device unless the network is set otherwise.
- service_rolestring
Advanced: an app role of this workspace (it starts with your workspace id and a dash). Cannot name private networks.
- matchConditionNoderequired
One node of a condition tree: a group node (
op+children) or a leaf (type+operator+value). See the table in Create an access rule.match fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- enforcedbooleanrequired
True when the rule is live at the edge. An
allowrule that is not enforced grants nothing. Adenyrule is enforced when it removes access at the edge for everyone it matches. - enforcement_reasonstring | null
Why the rule is not enforced (null when it is).
- enforcement_statusstring
fail_closed(deny rules only): a condition can't be checked yet, so the deny is applied to everyone it could match.off: the rule is turned off. - traffic_effectstring
Plain-English summary of what the rule does to traffic right now.
- form_representableboolean
True when the console can show and edit the rule in its simple form.
- form_viewRuleFormView
The rule read as the console's simple form: Include / Require / Except. Present only when
form_representableis true.form_view fields
- includearray of ConditionNoderequired
Who the rule applies to (one OR list): group / person / device / simple attribute leaves, decorated with
resolved_groups,resolved_peopleorresolved_devices.include fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- requirearray of ConditionNoderequired
Conditions that must all hold (posture, time, mfa, attribute).
require fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- excludearray of ConditionNoderequired
Who is excluded (the negated OR list).
exclude fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- versionintegerrequired
Increases on every change. Send it as
If-Matchon PATCH and DELETE. - created_atstring (date-time)
- updated_atstring (date-time)
400 invalid-policy-rule
invalid-policy-rule: The body fails validation; detail lists every problem as path: message (e.g. match.children[1].value: posture disk_encrypted needs operator eq + boolean value, target: exactly one of service_id, service_role or private_network_id, target.service_id: unknown app).
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 widening-console-only insufficient-scope insufficient-role tenant-assertion-mismatch
widening-console-only: This rule gives access: create it in the Cloudraw console.
insufficient-scope: The token is read-only and this call changes something.
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
409 idempotency-key-reuse
idempotency-key-reuse: The same Idempotency-Key was used with a different body within 24 hours.
503 busy
busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.
curl -sS -X POST "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Finance → ERP from encrypted laptops",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
}
}'$body = @'
{
"name": "Finance → ERP from encrypted laptops",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
}
}
'@
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN"; "Idempotency-Key" = [guid]::NewGuid().ToString() }
Invoke-RestMethod -Method Post -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules" -Headers $headers -ContentType "application/json" -Body $bodyimport os, uuid, requests
r = requests.post(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"name": "Finance → ERP from encrypted laptops",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": True
}
]
}
},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"name": "Finance → ERP from encrypted laptops",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
}
}),
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"id": "pr_7xk2m9c0d1",
"name": "Finance → ERP from encrypted laptops",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
},
"enforced": true,
"enforcement_reason": null,
"enforcement_status": "active_at_edge",
"traffic_effect": "Allowed for the groups, people or devices it names — live at the edge now.",
"form_representable": true,
"form_view": {
"include": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
],
"resolved_groups": [
{
"id": "g3k9d0s7aa",
"display_name": "Finance",
"state": "active"
}
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
],
"resolved_people": [
{
"id": "p4hd8s0qk2l",
"display_name": "Omer Katz",
"email": "omer.katz@example.com",
"state": "active"
}
]
}
],
"require": [
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
],
"exclude": []
},
"version": 1,
"created_at": "2026-10-02T07:41:09.000Z",
"updated_at": "2026-10-02T07:41:09.000Z"
}Test a draft access rule
POST/v0/tenants/{tenant_id}/policy-rules:evaluate
Validates a draft condition tree without saving anything. With a target it also tells you whether the draft, saved as an allow rule, would be enforced and which devices it would grant right now. Validation problems come back in errors with compiles: false (status 200), so you can show them next to the field.
Token: read-only or full access · Created by: owner or security admin
Idempotency: send Idempotency-Key to retry safely — the same key and body within 24 h returns the first answer.
An empty match comes back as compiles: false with errors: [{path: "match", message: "match required"}].
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Headers
- Idempotency-Keystring
A unique value (e.g. a UUID) per logical operation. Retrying with the same key and body within 24 hours returns the first answer instead of doing the work twice.
Request body application/json
- matchConditionNoderequired
One node of a condition tree: a group node (
op+children) or a leaf (type+operator+value). See the table in Create an access rule.match fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- targetRuleTarget
What the rule grants. Exactly one of the three fields.
target fields
- service_idstring
An app (connection) id in this workspace.
- private_network_idstring
A private network id in this workspace. Private networks also require a trusted device unless the network is set otherwise.
- service_rolestring
Advanced: an app role of this workspace (it starts with your workspace id and a dash). Cannot name private networks.
Responses
200 The dry-run result.
application/json
- compilesbooleanrequired
True when the draft is valid.
- errorsarray of objectrequired
Validation errors (empty when it compiles).
errors fields
- pathstring
e.g.
match.children[1].value - messagestring
- enforcedbooleanrequired
Whether the draft, saved as an
allowrule, would be live at the edge. Needstarget. - enforcement_reasonstring | null
Why not, e.g.
no targetordoes not compile. - match_countintegerrequired
Devices the draft would grant right now (needs
target). - sample_matchesarray of object
Up to 5 of those devices.
sample_matches fields
- device_idstring
- device_namestring | null
- personstring | null
Person name or e-mail.
- warningsarray of string
- form_representableboolean
- form_viewRuleFormView
The rule read as the console's simple form: Include / Require / Except. Present only when
form_representableis true.form_view fields
- includearray of ConditionNoderequired
Who the rule applies to (one OR list): group / person / device / simple attribute leaves, decorated with
resolved_groups,resolved_peopleorresolved_devices.include fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- requirearray of ConditionNoderequired
Conditions that must all hold (posture, time, mfa, attribute).
require fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- excludearray of ConditionNoderequired
Who is excluded (the negated OR list).
exclude fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
409 idempotency-key-reuse
idempotency-key-reuse: The same Idempotency-Key was used with a different body within 24 hours.
curl -sS -X POST "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:evaluate" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
},
"target": {
"service_id": "cx9m2v7d1pa"
}
}'$body = @'
{
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
},
"target": {
"service_id": "cx9m2v7d1pa"
}
}
'@
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN"; "Idempotency-Key" = [guid]::NewGuid().ToString() }
Invoke-RestMethod -Method Post -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:evaluate" -Headers $headers -ContentType "application/json" -Body $bodyimport os, uuid, requests
r = requests.post(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:evaluate",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}", "Idempotency-Key": str(uuid.uuid4())},
json={
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": True
}
]
},
"target": {
"service_id": "cx9m2v7d1pa"
}
},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:evaluate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
"Idempotency-Key": crypto.randomUUID(),
"Content-Type": "application/json",
},
body: JSON.stringify({
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
},
"target": {
"service_id": "cx9m2v7d1pa"
}
}),
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"compiles": true,
"errors": [],
"enforced": true,
"enforcement_reason": null,
"match_count": 7,
"sample_matches": [
{
"device_id": "dvc_5mxq2b7r8k",
"device_name": "FIN-LT-014",
"person": "Dana Levi"
}
],
"warnings": [],
"form_representable": true,
"form_view": {
"include": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
],
"resolved_groups": [
{
"id": "g3k9d0s7aa",
"display_name": "Finance",
"state": "active"
}
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
],
"resolved_people": [
{
"id": "p4hd8s0qk2l",
"display_name": "Omer Katz",
"email": "omer.katz@example.com",
"state": "active"
}
]
}
],
"require": [
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
],
"exclude": []
}
}Preview a change
POST/v0/tenants/{tenant_id}/policy-rules:preview
Shows exactly who GAINS and who LOSES access (people, their devices and the browser portal, per app) if you create, change, delete, turn off or turn on access rules — before you save. It runs the same evaluation the edge uses, on a copy: nothing is stored, nothing is applied, nothing is audited. Send one change (op, rule_id, rule) or several (changes, up to 25, applied in order). Each row says why (why, the last line of trace). used_recently marks a loss someone used in the last 7 days. At most 30 previews a minute per workspace. It lists people, so console admins need the owner, security_admin or auditor role.
Token: read-only or full access · Created by: owner or security admin
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
Request body application/json
- opstring
- rule_idstring
The rule to change (update / delete / enable / disable).
- base_versioninteger
Optional: the rule version you are editing; a newer stored version is reported as an error.
- ruleobject
create: the whole rule; update: the fields that change.
rule fields
- namestring
1-128 characters.
- effectstring
- enabledboolean
On / off.
- targetRuleTarget
What the rule grants. Exactly one of the three fields.
target fields
- service_idstring
An app (connection) id in this workspace.
- private_network_idstring
A private network id in this workspace. Private networks also require a trusted device unless the network is set otherwise.
- service_rolestring
Advanced: an app role of this workspace (it starts with your workspace id and a dash). Cannot name private networks.
- matchConditionNode
One node of a condition tree: a group node (
op+children) or a leaf (type+operator+value). See the table in Create an access rule.match fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- changesarray of object
Several changes at once, instead of
op.changes fields
- opstringrequired
- rule_idstring
Rule id.
- base_versioninteger
Rule version.
- ruleobject
As above.
- limitinteger
Rows per list (gains / loses), 0-200. Default 20; the summary always counts everything.
Responses
200 Who gains and who loses access.
application/json
- read_onlyboolean
Always true.
- summaryobject
summary fields
- gainsinteger
Rows that gain.
- losesinteger
Rows that lose.
- people_gaininginteger
People.
- people_losinginteger
People.
- devices_gaininginteger
Devices.
- devices_losinginteger
Devices.
- apps_gaininginteger
Apps.
- apps_losinginteger
Apps.
- unchangedinteger
Rows that stay the same.
- sessions_cutinteger | null
Live sessions that would end (null when the overlay can't be read).
- used_recentlyinteger
Losses used in the last 7 days.
- apps_exposed_to_everyoneinteger
Apps every person could open afterwards.
- gainsarray of object
Up to
limitrows.gains fields
- personobject
person fields
- idstring | null
Person id.
- namestring
Name.
- deviceobject
device fields
- idstring
Device id, or "browser" for the portal.
- namestring
Name.
- appobject
app fields
- idstring
App or private network id.
- namestring
Name.
- kindstring
- beforeobject
before fields
- allowedboolean
Before.
- rulesarray of object
rules fields
- idstring
Rule id.
- namestring
Rule name.
- afterobject
after fields
- allowedboolean
After.
- rulesarray of object
rules fields
- idstring
Rule id.
- namestring
Rule name.
- used_recentlyboolean
Losses only.
- whystring | null
One line: why.
- tracearray of string
The decision, step by step.
- losesarray of object
Up to
limitrows. - truncatedboolean
More rows than
limit. - changesarray of object
Each change, with its edge status.
changes fields
- opstring
The change.
- rule_idstring | null
Rule id.
- sentencestring
The rule in one sentence.
- enforcementobject
enforcement fields
- enforcedboolean
Would be live at the edge.
- reasonstring | null
Why not.
- fail_closedboolean
Deny only: applied to everyone it could match.
- warningsarray of string
- evaluated_atstring (date-time)
400 invalid-preview
invalid-preview: The changes fail validation (errors lists path: message): unknown op, unknown rule (also another workspace's rule), bad rule body, limit outside 0-200.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-role tenant-assertion-mismatch
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 tenant-not-found
tenant-not-found: No workspace with this id.
429 too-many-previews
too-many-previews: More than 30 previews a minute in this workspace; Retry-After says when to try again.
curl -sS -X POST "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:preview" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"op": "create",
"rule": {
"name": "No ERP for contractors",
"effect": "deny",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
}
}
}'$body = @'
{
"op": "create",
"rule": {
"name": "No ERP for contractors",
"effect": "deny",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
}
}
}
'@
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Post -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:preview" -Headers $headers -ContentType "application/json" -Body $bodyimport os, uuid, requests
r = requests.post(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:preview",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
json={
"op": "create",
"rule": {
"name": "No ERP for contractors",
"effect": "deny",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
}
}
},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules:preview", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"op": "create",
"rule": {
"name": "No ERP for contractors",
"effect": "deny",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
}
}
}),
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"read_only": true,
"summary": {
"gains": 0,
"loses": 2,
"people_gaining": 0,
"people_losing": 2,
"devices_gaining": 0,
"devices_losing": 2,
"apps_gaining": 0,
"apps_losing": 1,
"unchanged": 14,
"sessions_cut": 0,
"used_recently": 1,
"apps_exposed_to_everyone": 0
},
"gains": [],
"loses": [
{
"person": {
"id": "p4hd8s0qk2l",
"name": "Omer Katz"
},
"device": {
"id": "dvc_5mxq2b7r8k",
"name": "FIN-LT-014"
},
"app": {
"id": "cx9m2v7d1pa",
"name": "erp-db",
"kind": "connection"
},
"before": {
"allowed": true,
"rules": [
{
"id": "pr_7xk2m9c0d1",
"name": "Finance → ERP from encrypted laptops"
}
]
},
"after": {
"allowed": false,
"rules": []
},
"used_recently": true,
"why": "Result: BLOCKED — the device passes the trust gate, but no rule grants it (see the rule lines above).",
"trace": [
"Rule \"No ERP for contractors\" is a deny rule and it matches this device: it blocks \"erp-db\" whatever allow rule, group or temporary access applies (deny wins)."
]
}
],
"truncated": false,
"changes": [
{
"op": "create",
"rule_id": null,
"sentence": "Contractors cannot open erp-db.",
"enforcement": {
"enforced": true,
"reason": null
}
}
],
"warnings": [],
"evaluated_at": "2026-10-13T09:24:11.000Z"
}Update an access rule
PATCH/v0/tenants/{tenant_id}/policy-rules/{rule_id}
Changes any of name, effect, enabled, target and match (a field you leave out keeps its value; match is replaced as a whole). enabled: false turns the rule off, true turns it on again. The rule is re-applied at the edge immediately and the answer shows the new enforcement status. Requires If-Match. Audited. A change that gives access (an allow turned on, any condition / target edit of an enabled rule, a deny turned off or made an allow) is made in the Cloudraw console: API tokens get 403 widening-console-only.
Token: full access · Created by: owner
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
- rule_idstringrequired
Access rule id (from List access rules).
Headers
- If-Matchstringrequired
The rule's current
version(from a GET or the last write). Required: without it the call answers428 if-match-required; with a stale value409 version-conflict.
Request body application/json
- namestring
1-128 characters.
- effectstring
- enabledboolean
Turn the rule off (false) or on (true).
- targetRuleTarget
What the rule grants. Exactly one of the three fields.
target fields
- service_idstring
An app (connection) id in this workspace.
- private_network_idstring
A private network id in this workspace. Private networks also require a trusted device unless the network is set otherwise.
- service_rolestring
Advanced: an app role of this workspace (it starts with your workspace id and a dash). Cannot name private networks.
- matchConditionNode
One node of a condition tree: a group node (
op+children) or a leaf (type+operator+value). See the table in Create an access rule.match fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
Responses
200 The updated rule.
application/json
- idstringrequired
Access rule id.
- namestringrequired
1-128 characters.
- effectstringrequired
- enabledboolean
False when the rule is turned off: it then has no effect at all. Default true.
- targetRuleTargetrequired
What the rule grants. Exactly one of the three fields.
target fields
- service_idstring
An app (connection) id in this workspace.
- private_network_idstring
A private network id in this workspace. Private networks also require a trusted device unless the network is set otherwise.
- service_rolestring
Advanced: an app role of this workspace (it starts with your workspace id and a dash). Cannot name private networks.
- matchConditionNoderequired
One node of a condition tree: a group node (
op+children) or a leaf (type+operator+value). See the table in Create an access rule.match fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- enforcedbooleanrequired
True when the rule is live at the edge. An
allowrule that is not enforced grants nothing. Adenyrule is enforced when it removes access at the edge for everyone it matches. - enforcement_reasonstring | null
Why the rule is not enforced (null when it is).
- enforcement_statusstring
fail_closed(deny rules only): a condition can't be checked yet, so the deny is applied to everyone it could match.off: the rule is turned off. - traffic_effectstring
Plain-English summary of what the rule does to traffic right now.
- form_representableboolean
True when the console can show and edit the rule in its simple form.
- form_viewRuleFormView
The rule read as the console's simple form: Include / Require / Except. Present only when
form_representableis true.form_view fields
- includearray of ConditionNoderequired
Who the rule applies to (one OR list): group / person / device / simple attribute leaves, decorated with
resolved_groups,resolved_peopleorresolved_devices.include fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- requirearray of ConditionNoderequired
Conditions that must all hold (posture, time, mfa, attribute).
require fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- excludearray of ConditionNoderequired
Who is excluded (the negated OR list).
exclude fields
- opstring
Group node: how the children combine.
- negateboolean
Group node:
trueon anornode marks an exclude list ("anyone except …"). Not enforceable in access rules. - childrenarray of ConditionNode
Group node: the child nodes.
- typestring
Leaf: what is tested.
- fieldstring
Leaf: the sub-field for
posture,network,mfa(and the attribute name forattribute). - operatorstring
Leaf: the operator (depends on
type/field). - valueany
Leaf: the operand — a list of ids, a boolean, a list of codes,
{tz,start,end},{from,to}, … - resolved_groupsarray of object
Read-only, in
form_view: the groups agroupleaf names.resolved_groups fields
- idstring
- display_namestring
- statestring
- resolved_peoplearray of object
Read-only, in
form_view: the people apersonleaf names.resolved_people fields
- idstring
- display_namestring
- emailstring
- statestring
- resolved_devicesarray of object
Read-only, in
form_view: the devices adeviceleaf names.resolved_devices fields
- idstring
- display_namestring
- statestring
- versionintegerrequired
Increases on every change. Send it as
If-Matchon PATCH and DELETE. - created_atstring (date-time)
- updated_atstring (date-time)
400 invalid-policy-rule
invalid-policy-rule: The body fails validation; detail lists every problem as path: message (e.g. match.children[1].value: posture disk_encrypted needs operator eq + boolean value, target: exactly one of service_id, service_role or private_network_id, target.service_id: unknown app).
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 widening-console-only insufficient-scope insufficient-role tenant-assertion-mismatch
widening-console-only: This change gives access: make it in the Cloudraw console.
insufficient-scope: The token is read-only and this call changes something.
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 policy-rule-not-found tenant-not-found
policy-rule-not-found: No access rule with this id.
tenant-not-found: No workspace with this id.
409 version-conflict
version-conflict: If-Match does not match the rule's current version (someone changed it meanwhile; re-read and retry).
428 if-match-required
if-match-required: No If-Match header was sent.
503 busy
busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.
curl -sS -X PATCH "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
},
{
"type": "posture",
"field": "edr_present",
"operator": "eq",
"value": true
}
]
}
}'$body = @'
{
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
},
{
"type": "posture",
"field": "edr_present",
"operator": "eq",
"value": true
}
]
}
}
'@
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Patch -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1" -Headers $headers -ContentType "application/json" -Body $bodyimport os, uuid, requests
r = requests.patch(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
json={
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": True
},
{
"type": "posture",
"field": "edr_present",
"operator": "eq",
"value": True
}
]
}
},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
},
{
"type": "posture",
"field": "edr_present",
"operator": "eq",
"value": true
}
]
}
}),
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"id": "pr_7xk2m9c0d1",
"name": "Finance → ERP from encrypted laptops",
"effect": "allow",
"target": {
"service_id": "cx9m2v7d1pa"
},
"match": {
"op": "and",
"children": [
{
"op": "or",
"children": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
]
}
]
},
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
]
},
"enforced": true,
"enforcement_reason": null,
"enforcement_status": "active_at_edge",
"traffic_effect": "Allowed for the groups, people or devices it names — live at the edge now.",
"form_representable": true,
"form_view": {
"include": [
{
"type": "group",
"operator": "in",
"value": [
"g3k9d0s7aa"
],
"resolved_groups": [
{
"id": "g3k9d0s7aa",
"display_name": "Finance",
"state": "active"
}
]
},
{
"type": "person",
"operator": "in",
"value": [
"p4hd8s0qk2l"
],
"resolved_people": [
{
"id": "p4hd8s0qk2l",
"display_name": "Omer Katz",
"email": "omer.katz@example.com",
"state": "active"
}
]
}
],
"require": [
{
"type": "posture",
"field": "disk_encrypted",
"operator": "eq",
"value": true
}
],
"exclude": []
},
"version": 4,
"created_at": "2026-10-02T07:41:09.000Z",
"updated_at": "2026-10-13T09:24:11.000Z"
}Delete an access rule
DELETE/v0/tenants/{tenant_id}/policy-rules/{rule_id}
Deletes the rule and removes what it granted at the edge right away; devices that reached the app only through this rule lose access. Requires If-Match. Audited. A removal that gives access (a deny) is not done here: the answer is 409 use-the-remove-route (see Remove an access rule with a reason).
Token: full access · Created by: owner
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
- rule_idstringrequired
Access rule id (from List access rules).
Headers
- If-Matchstringrequired
The rule's current
version(from a GET or the last write). Required: without it the call answers428 if-match-required; with a stale value409 version-conflict.
Responses
202 Deleted (state: done).
application/json
- idstringrequired
- tenant_idstring
- statestringrequired
- result_uristring | null
- errorobject | string | null
Why it failed, or a short status note (e.g.
revoke_pending).
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 insufficient-scope insufficient-role tenant-assertion-mismatch
insufficient-scope: The token is read-only and this call changes something.
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 policy-rule-not-found tenant-not-found
policy-rule-not-found: No access rule with this id.
tenant-not-found: No workspace with this id.
409 version-conflict use-the-remove-route
version-conflict: If-Match does not match the rule's current version (someone changed it meanwhile; re-read and retry).
use-the-remove-route: Removing this rule gives access: use POST .../policy-rules/{rule_id}/remove with a reason.
428 if-match-required
if-match-required: No If-Match header was sent.
503 busy
busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.
curl -sS -X DELETE "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN"$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Delete -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1" -Headers $headersimport os, uuid, requests
r = requests.delete(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
timeout=30,
)
r.raise_for_status()
print(r.status_code)const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1", {
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
},
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(res.status);{
"id": "task_8k2x0m9s1d",
"tenant_id": "tq7x2m9k4ab",
"state": "done",
"result_uri": null,
"error": null
}Remove an access rule with a reason
POST/v0/tenants/{tenant_id}/policy-rules/{rule_id}/remove
Removes a rule whose removal gives access (a deny). The reason goes ONLY in the JSON body (reason, 10-300 characters counted after decoding; any language, one line; control characters and invalid UTF-8 are refused, bidi / format characters removed). Not in a header: X-Cloudraw-Reason together with a body reason is refused. API tokens cannot give access (403 widening-console-only): make the change in the Cloudraw console. Requires If-Match. Audited with the reason.
Token: full access · Created by: owner
Path parameters
- tenant_idstringrequired
Your workspace id (Settings → Workspace in the console; it is also in every console URL).
- rule_idstringrequired
Access rule id (from List access rules).
Headers
- If-Matchstringrequired
The rule's current
version(from a GET or the last write). Required: without it the call answers428 if-match-required; with a stale value409 version-conflict.
Request body application/json
- reasonstringrequired
Why this removal gives access. 10-300 characters, one line.
Responses
202 Removed (state: done).
application/json
- idstringrequired
- tenant_idstring
- statestringrequired
- result_uristring | null
- errorobject | string | null
Why it failed, or a short status note (e.g.
revoke_pending).
400 reason-required reason-invalid reason-header-and-body
reason-required: No reason, or not 10-300 characters.
reason-invalid: The reason is not text, or has control characters or invalid UTF-8.
reason-header-and-body: The reason was sent in a header and in the body.
401 unauthorized invalid-token token-expired
unauthorized: No Authorization: Bearer crw_… header was sent.
invalid-token: The token is unknown or was revoked.
token-expired: The token is past its expiry date. Create a new one.
403 widening-console-only insufficient-scope insufficient-role tenant-assertion-mismatch
widening-console-only: This removal gives access: make it in the Cloudraw console.
insufficient-scope: The token is read-only and this call changes something.
insufficient-role: The token's role ceiling does not allow this call.
tenant-assertion-mismatch: The token belongs to another workspace than {tenant_id}.
404 policy-rule-not-found tenant-not-found
policy-rule-not-found: No access rule with this id.
tenant-not-found: No workspace with this id.
409 version-conflict
version-conflict: If-Match does not match the rule's current version (someone changed it meanwhile; re-read and retry).
428 if-match-required
if-match-required: No If-Match header was sent.
503 busy
busy: Cloudraw is switching servers or cannot save right now. Retry after Retry-After seconds.
curl -sS -X POST "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1/remove" \
-H "Authorization: Bearer $CLOUDRAW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "The contractor left; the block is no longer needed."
}'$body = @'
{
"reason": "The contractor left; the block is no longer needed."
}
'@
$headers = @{ Authorization = "Bearer $env:CLOUDRAW_TOKEN" }
Invoke-RestMethod -Method Post -Uri "https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1/remove" -Headers $headers -ContentType "application/json" -Body $bodyimport os, uuid, requests
r = requests.post(
"https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1/remove",
headers={"Authorization": f"Bearer {os.environ['CLOUDRAW_TOKEN']}"},
json={
"reason": "The contractor left; the block is no longer needed."
},
timeout=30,
)
r.raise_for_status()
print(r.json())const res = await fetch("https://cdapi.cloudraw.com/v0/tenants/tq7x2m9k4ab/policy-rules/pr_7xk2m9c0d1/remove", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.CLOUDRAW_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"reason": "The contractor left; the block is no longer needed."
}),
});
if (!res.ok) throw new Error((await res.json()).code);
console.log(await res.json());{
"id": "task_8k2x0m9s1d",
"tenant_id": "tq7x2m9k4ab",
"state": "done",
"result_uri": null,
"error": null
}