API reference Resources
Policies
Policies: authoring, lifecycle, hits and simulation.
35 operations
List decisions
Decisions newest first, each with the engine runs that fed it. Page with after, passing the previous page's next.
Query parameters
1h, 24h, 7d or 30d. Defaults to 24h.
A policy id, the workspace's own or a provided one.
blocked | alerted | justified | undetermined | passed.
The filter expression, e.g. all;outcome~in~blocked;action~in~redact.
Joined by all, each segment field~in~values with values separated by commas. Fields: outcome, policy, action (block, redact, ask, connector_action), engine, machine, inspection (not_inspected: content not inspected because of its size). A field or value this list does not have is a 400 naming it.
Free text over a reference, a user, a hostname and, on a connector action, its record and connection.
One decision by its reference, a filter of its own. A malformed reference is a 400. With no window named, the window is unbounded.
Keep rows whose machine or connection was removed. Default false; a read scoped by interaction or reference ignores it.
An interaction id: every decision about that one interaction, whatever its outcome. With no window named, the window is unbounded.
The next of the previous page.
Clamped to 1–200; default 50.
Response200
A page of decisions with their runs
The verbs the deciding policy version lists, wire names, in its order. ["connector_action"] on an action row. Empty for a caller holding only alerts:read.
inline | policy | engine | connector (kind=action rows): who decided.
decision for a decision about an interaction; action for something a rule or a person did through a connection.
Every decision the window and filters match, whatever page this is.
Errors
- 400
A window, policy, outcome, facet, reference or cursor this endpoint does not accept
- 401
No valid session
- 403
Caller lacks both policies:read and alerts:read in this workspace
One decision by reference
One decision by the reference a person was shown when their request was stopped. A malformed reference is a 400 naming the format.
Path parameters
Response200
The decision the reference names
The verbs the deciding policy version lists, wire names, in its order. ["connector_action"] on an action row. Empty for a caller holding only alerts:read.
inline | policy | engine | connector (kind=action rows): who decided.
decision for a decision about an interaction; action for something a rule or a person did through a connection.
open | acknowledged | resolved | suppressed.
Errors
- 400
Not a well-formed reference; the message names the format
- 401
No valid session
- 403
Caller lacks both policies:read and alerts:read in this workspace
- 404
No decision with that reference in this workspace
Decision counts
The window's decision counts, and the 95th-percentile engine time in milliseconds.
Query parameters
1h, 24h, 7d or 30d. Defaults to 24h.
Count rows whose machine or connection was removed. Default false.
Response200
Counts over the window
Decisions and connector actions in the window.
Redactions that happened: enforcing matches on a policy version that lists Redact and no Block (which would have won).
Weighted p95 of the engine runs that served a policy; workspace-wide.
Errors
- 400
The window is not one of 1h, 24h, 7d, 30d
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
Decisions per policy
Per policy: decisions by outcome over the window, and why undetermined.
Query parameters
1h, 24h, 7d or 30d. Defaults to 24h.
Response200
Decisions per policy over the window
Twelve RFC 3339 bucket starts, oldest first.
Every policy with a decision in the window. Passed decisions are not kept except where the late pass settled one.
draft | monitor | enforce — the policy's mode for this workspace now.
true for a policy provided by Oxelone rather than written by the workspace.
Errors
- 400
The window is not one of 1h, 24h, 7d, 30d
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
One decision
One decision or connector action by its id, of any age, removed or not. An unknown id, a malformed one and another workspace's are all 404.
Path parameters
Response200
The decision, its runs and the issue it joined
The verbs the deciding policy version lists, wire names, in its order. ["connector_action"] on an action row. Empty for a caller holding only alerts:read.
inline | policy | engine | connector (kind=action rows): who decided.
decision for a decision about an interaction; action for something a rule or a person did through a connection.
open | acknowledged | resolved | suppressed.
Errors
- 401
No valid session
- 403
Caller lacks both policies:read and alerts:read in this workspace
- 404
No decision with that id in this workspace
What each hook tool can do with each action
policies:read: it describes the authoring surface and reveals nothing a policy reader may not already see — the same gate as the capabilities document.
Response200
Each hook tool's block, native ask and companion ask per action
What an Ask at a hook does when no companion is running, as one sentence.
The eight action kinds with their words, in picker order.
The display name, e.g. Shell command, Tool call.
One per tool whose vendor documents blocking hooks, in the registry's order.
Per action kind; a kind absent here has no hook on this tool.
The registry's display name (Claude Code, Devin Desktop).
What the tool does when its hook times out: open or closed.
The registry slug (claude_code).
The hook timeout we write into the tool's config, or null where it has no field (Windsurf: its own limit is unmeasured).
The capability document's version (hook_capabilities.json's version).
Errors
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such workspace, or the caller is not a member
List policies
Every policy in this workspace, at its current version, or with ?connection= only the rules bound to that connection.
Query parameters
A connection id: only that connection's rules, in precedence order.
An id that is not a connection in this workspace, cannot be parsed, or was removed is a 404, never an empty list.
Response200
Policies in this workspace
Every policy group this workspace sees, those provided by Oxelone and its own, of every type, in reading order. A policy row's group_id names the group it is in, null when it is in none.
On (true) or Off. Off pauses every member.
The members, in member order.
A provided group this workspace removed (listed with the removed policies).
How many decisions each policy has ever produced — a filter match, whatever the outcome or the state — with its trailing seven days, day by day. One entry per policy that has any; a policy with none is absent.
Hits per UTC day, oldest first, today last, zero-filled: always seven entries, all zeros for a policy last hit before the window.
Hits in the trailing seven UTC days: the sum of daily. Not the same figure as last_30d on GET /policies/{id}/hits, which is a rolling 30 days.
Every hit this policy has ever had.
Errors
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such workspace, no such connection, or the caller is not a member
Create a policy
The policy starts Disabled (draft) unless mode says otherwise. enforce needs policies:publish, as /mode does; monitor and enforce are checked as enabling a Disabled policy is, and monitor needs a policy that can hold something back. A policy that starts in Monitor or Enabled ships at once, and the reply carries what that publish did under publish — null for a Disabled policy — beside the policy's own fields, mode among them.
Request bodyCreatePolicyInput
One of draft, monitor, enforce. Absent is draft, as every create was before this field existed.
Response201
Policy created: the policy as stored, plus holds_back and publish (the auto-publish's {hash, warnings, halted}, null for a draft)
Errors
- 400
Policy body is malformed or fails validation, an unknown mode, or Monitor on a policy that holds nothing back
- 401
No valid session
- 403
Caller lacks policies:write in this workspace, or policies:publish for enforce
- 404
No such workspace, or the caller is not a member
Compile and publish policies
Compiles every policy that is not Disabled, together with the PII & Secrets rules and the workspace's catalogued services, and publishes the result as what every machine in the workspace runs next. While enforcement is halted, every policy is published as Monitor; the stored states are untouched.
Response201
Compiled and published as the workspace's current bundle
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
The same thing in a sentence, for an operator who is not going to look the reason code up.
The policy's own name, so an operator recognises it in the list. The id is the handle they act on.
Stable and machine-readable: label_not_emittable, no_backend, engine_has_no_runner, or engine_unknown. no_backend is the one you can fix, by choosing a backend for the engine; engine_has_no_runner cannot be fixed by any setting.
The canonical label the condition binds, when the warning is about one.
Errors
- 401
No valid session
- 403
Caller lacks policies:publish in this workspace
- 404
No such workspace, or the caller is not a member
Enforcement state
What is enforcing in this workspace, and on how many machines: whether enforcement is halted, and how far the current publish has reached.
Response200
Halt state and bundle rollout
How long a machine may take to notice a change, in seconds: the interval at which this workspace's machines check in. A halt or a publish is not instant; alerts can keep arriving until then.
The hash of what this workspace has published, or null if nothing has been. While it is null a machine has no site catalog, captures nothing, and reports "outcome": "no catalog".
The reason given when enforcement was halted; always present.
Errors
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such workspace, or the caller is not a member
Halt enforcement
Stops enforcing everything in this workspace without changing a single policy: every policy runs as Monitor, and alerts are still raised. Takes effect at once — the policies are republished in the same request, and if that fails the whole request fails, so a success means the machines are being told. Needs policies:publish and a reason, which is recorded.
Request bodyHaltRequest
Why enforcement is being stopped. Must not be blank.
Response200
Enforcement halted and a bundle republished
How long a machine may take to notice a change, in seconds: the interval at which this workspace's machines check in. A halt or a publish is not instant; alerts can keep arriving until then.
The hash of what this workspace has published, or null if nothing has been. While it is null a machine has no site catalog, captures nothing, and reports "outcome": "no catalog".
The reason given when enforcement was halted; always present.
Errors
- 400
No reason was given
- 401
No valid session
- 403
Caller lacks policies:publish in this workspace
- 404
No such workspace, or the caller is not a member
Resume enforcement
Lets enforcement resume after a halt. Every policy returns to whatever its state already said, because the halt never changed it.
Response200
Enforcement resumed and a bundle republished
How long a machine may take to notice a change, in seconds: the interval at which this workspace's machines check in. A halt or a publish is not instant; alerts can keep arriving until then.
The hash of what this workspace has published, or null if nothing has been. While it is null a machine has no site catalog, captures nothing, and reports "outcome": "no catalog".
The reason given when enforcement was halted; always present.
Errors
- 401
No valid session
- 403
Caller lacks policies:publish in this workspace
- 404
No such workspace, or the caller is not a member
A tab's top level, in order
Query parameters
The tab: a policy type's wire value — prompt, file_artifact, hook, connector_event, …
Response200
The tab's groups and policies in no group, in order
The tab's top level, first first: every group on it, and every policy in no group.
The group's id, or the policy's (own or provided).
group or policy.
Errors
- 400
Unknown policy type
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such workspace, or the caller is not a member
Replace a tab's top-level order
Refuses an item that is not on the tab — another workspace's, another type's, or a policy that is in a group (it moves within its group) — and a list that is not the tab's whole top level (409: it changed since it was read, the rule PUT /policies/order has for a partial list). Reading order only, like that route; it republishes because the bundle's policy order follows precedence.
Request bodySetLayoutRequest
Every item GET answers for this tab, in the new order. A replacement: an item left out is a stale list (409), not a removal.
The group's id, or the policy's (own or provided).
group or policy.
The tab, as GET's subject.
Response200
The layout as stored
The tab's top level, first first: every group on it, and every policy in no group.
The group's id, or the policy's (own or provided).
group or policy.
Errors
- 400
Unknown type or kind, a malformed or repeated id, an id that is not this workspace's, an item of another type, or a policy that is in a group
- 401
No valid session
- 403
Caller lacks policies:write in this workspace
- 404
No such workspace, or the caller is not a member
- 409
The list is not the tab's whole top level: it changed since it was read
Set the state of many policies
One transaction and one publish. Each id is checked as POST /policies/{id}/mode checks it — leaving Disabled re-validates against this workspace's engines and connections, and a connector's rule is refused because it is switched per connection — and a refused id is reported and left as it was while the rest are written together. A policy whose group is Off has its stored state written like any other; it stays paused until its group is On.
Needs policies:write, and policies:publish as well when the mode is enforce.
Request bodySetModesRequest
Policy ids, the workspace's own and provided ones alike.
One of draft, monitor, enforce.
Response200
Each id's outcome, and the one publish
Monitor where it applies: how many of the ids asked for Monitor are Enabled instead (changed to it, or already in it), because nothing in them changes anything. 0 for any other mode.
One entry per id sent, in the order sent.
changed, unchanged (it already had that mode), refused (see refusal; nothing was written for it), or not_found.
The mode it is in after this change — enforce where monitor was asked for and the policy holds nothing back — or null when it was refused or not found.
Why it was refused, as a sentence, or null.
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 400
Unknown mode, a malformed or repeated id, or more than 500 ids
- 401
No valid session
- 403
Caller lacks policies:write, or policies:publish for enforce
- 404
No such workspace, or the caller is not a member
Reorder policies
Sets the order one policy type's list is read in, and nothing else. It does not make the first matching policy win: every policy is evaluated and every match raises its own alert.
The list must name every policy of that type in this workspace; a partial list is refused with a 400 that gives the expected count. Needs policies:write. Reordering publishes nothing and reaches no machine.
Request bodySetOrderRequest
Every policy of that type in this workspace, in the order they should appear.
The policy type this order is within — one of prompt, file_artifact, asset, connector_event, egress.
Required rather than inferred from the ids, and that is the point of the field: precedence is only meaningful within a type, because ordering a prompt policy against a file-artifact one answers no question anybody asks. Naming it lets the route refuse a list that mixes two, which is a caller bug that would otherwise be stored and rendered as an order.
Response200
Order stored
How many policies moved: the number of ids sent, on success. A partial list is refused, never applied in part.
Errors
- 400
Unknown policy type, an id that is not this workspace's, an id of another type, or an incomplete list
- 401
No valid session
- 403
Caller lacks policies:write in this workspace
- 404
No such workspace, or the caller is not a member
List removed policies
The policies provided by Oxelone that this workspace removed. Each can be brought back with POST /policies/{id}/restore.
Response200
The policies provided by Oxelone that this workspace removed, restorable
Errors
- 403
Caller lacks policies:read in this workspace
Simulate one call against this workspace's policies
Request bodySimulateRequest
The tool's registry slug (claude_code). Required for hook; for prompt it names the tool whose vendor host the request goes to.
hook — a tool's hook call (action says which) — or prompt, a Network prompt as the network path sees it. A prompt a hook saw is trigger: "hook", action: "prompt".
The action kind (shell, file_read, …). Required for hook.
A companion is running in the person's session. Default true.
The machine observes content. false simulates a metadata-only machine: every content fact reads unknown. Default true.
The fields of a policy a caller writes: name, subject_kind, condition, actions, fail_mode, latency_budget_ms. id and version are assigned by the server, and a policy's state is changed only through its mode route, which needs policies:publish.
The facts of the call that fit its kind.
The working directory, as the agent normalises it (~/src/app).
The enrollment profile to simulate as; null is a machine with no profile.
The tool is set to skip permissions: the simulated call carries the tool's bypass value, where it has one.
Response200
The winner, the route, and every policy of the trigger with its result
The non-enforcing actions of every matched policy: what is raised besides the decision.
alert or webhook.
An Alert that also tells the person in the moment (Notify).
For a prompt at a hook: the Network policies checked there, in the same shape.
The policy's own decision: allow, ask, block (or redact for a Network policy).
Its place in the list, from 1.
matched, no_match, other_action, out_of_scope, disabled, monitor or undetermined.
Why, in one line.
Every policy of the trigger — Hook policies of this kind, and for a prompt every Network policy — matched or not, Disabled, Monitor and out of scope included, each with why.
The policy's own decision: allow, ask, block (or redact for a Network policy).
Its place in the list, from 1.
matched, no_match, other_action, out_of_scope, disabled, monitor or undetermined.
Why, in one line.
allow, ask or block, the strictest of the matched policies winning, or undetermined when the outcome waits on an engine result, which a simulation does not run. For an Ask with no companion running this is still ask; what happens then is if_no_companion's sentence.
The policies that decided it: every merged Ask, or the blocking ones.
The merged question, as the person would read it; null for Oxelone's default wording.
What happens when no companion is running, as a sentence; null unless the Ask would go to the companion.
What happens when nobody answers, as a sentence; null when nobody would be asked.
native or companion.
Errors
- 400
Unknown trigger, tool or action, or a draft that would not save
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such workspace, or the caller is not a member
Preview an AI tool policy
How many of this workspace's machines an unsaved AI tool policy would match now.
Request bodyToolConfigPreviewRequest
The unsaved policy body, in the shape POST /policies takes: a Host policy about an AI tool, triggered while present.
Response200
Matched machines where the agent can fix the setting itself, in a tool the policy matched.
More than 5,000 reads: the counts are over the newest 5,000.
The first item the filter matched (a rule, an MCP server, a plugin), when it matched one.
Errors
- 400
Not a Host policy about an AI tool, triggered while present
- 403
Caller lacks policies:write or machines:read in this workspace
Validate a policy body
Checks a policy body as saving it would, and says whether it could be enabled and, if not, why — without storing anything. Needs policies:write; it does not need policies:publish, so an author learns why a rule cannot be enabled before asking someone who can enable it.
Request bodyPolicyInput
Response200
The verdict, whichever way it went
Whether this body could be armed — moved out of draft — as things stand in this workspace right now.
Whether the refusal is about enforcing — an engine not accurate enough to block or redact on — rather than something an unfinished policy has not got round to yet. can_arm: false alone does not say which. False whenever there is no refusal.
Whether this body can be saved as a draft. False only for something storage itself cannot hold — a body that does not match the model, or a pattern that does not compile.
What publishing will warn about in this body, never a refusal: scope_names_missing_profile for a profile deleted since it was named, targets_hook_actions for a Network policy written against hook:// or HOOK. Empty when the body did not parse.
scope_names_missing_profile or targets_hook_actions.
A sentence for the policy's author, meant to be shown as it is.
Why this body could not be enabled, or null if it could. Show it as it is: where an engine's accuracy is the reason, it names the measured false-positive rate and the backend to choose instead.
What this workspace's fleet will not do for this body, even though nothing refuses it — for example, a category no live machine scans for.
Never a refusal: it does not change ok or can_arm. Absent when empty.
Why not, in the server's own words, or null.
Errors
- 400
The body is not a JSON object at all
- 401
No valid session
- 403
Caller lacks policies:write in this workspace
- 404
No such workspace, or the caller is not a member
Publish a new version of an existing policy
The live mode is preserved from the existing policy, never taken from the request body — see the PolicyInput doc comment. Changing mode is exclusively POST .../mode's job.
Path parameters
Request bodyPolicyInput
Response200
New version published, and auto-published unless the policy is Disabled
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 400
Policy body is malformed or fails validation, or an ENABLED policy's edit would leave it unarmable
- 401
No valid session
- 403
Caller lacks policies:write in this workspace
- 404
No such policy in this workspace
Delete a policy
The policy leaves the list and stops running on every machine; the policies are republished in the same request. Its version history is kept, so alerts it raised still name the exact rule that fired.
policies:write deletes a Disabled or Monitor policy; deleting an Enabled one also needs policies:publish, because it stops live enforcement. An unknown id, or one in another workspace, is a 404.
Path parameters
Response200
Policy soft-deleted and the bundle republished in the same request
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
The same thing in a sentence, for an operator who is not going to look the reason code up.
The policy's own name, so an operator recognises it in the list. The id is the handle they act on.
Stable and machine-readable: label_not_emittable, no_backend, engine_has_no_runner, or engine_unknown. no_backend is the one you can fix, by choosing a backend for the engine; engine_has_no_runner cannot be fixed by any setting.
The canonical label the condition binds, when the warning is about one.
Errors
- 401
No valid session
- 403
Caller lacks the grant this delete requires — policies:write, or policies:publish for an enforcing policy
- 404
No such policy in this workspace
One policy's activity
One policy's decisions over a window, with the engines and tools behind them. Works for the workspace's own policies and provided ones.
Path parameters
Query parameters
24h, 7d or 30d. Defaults to 30d.
Response200
The policy's decisions, engines and tools over the window
Thirty RFC 3339 bucket starts, oldest first.
One per outcome present.
Aligned with bucket_starts.
The top three tools.
0–1, of decisions.
Errors
- 400
The window is not one of 24h, 7d, 30d
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such policy in this workspace, and no such provided policy
Duplicate a provided policy
Copies a policy provided by Oxelone into one this workspace owns and can edit. The copy starts Disabled. Needs policies:write.
Path parameters
Request bodyDuplicateRequest
The copy's name; "Copy of <vendor name>" when absent.
Response201
A policy this workspace owns, Disabled, with the provided policy's content
Errors
- 403
Caller lacks policies:write in this workspace
- 404
No such policy provided by Oxelone
A policy's hit counts
How often this policy's filter has matched: every decision it produced, in every state and with every outcome, in total and over the trailing 30 days. Broader than the preview on purpose: the preview counts only Monitor, while this answers whether the rule is doing anything at all.
Path parameters
Response200
Total decisions, and the trailing 30 days
Errors
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such policy in this workspace
Set a policy's state
Moves a policy between Disabled (draft), Monitor (monitor) and Enabled (enforce), and republishes in the same request. Needs policies:write; reaching enforce also needs policies:publish. Every change is recorded in the audit log, so you can later tell whether a policy was enforcing when an alert was raised.
Path parameters
Request bodySetModeRequest
One of draft, monitor, enforce.
Response200
Mode changed, and the bundle republished in the same request
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 400
Unknown mode
- 401
No valid session
- 403
Caller lacks the grant this transition requires
- 404
No such policy in this workspace
Preview a policy
What this policy would have done had it been Enabled, from what it matched while in Monitor. Every count is scoped to Monitor: a decision made while the policy was already Enabled is not evidence about enabling it. Needs policies:read.
An empty answer is not a safe answer: a policy put in Monitor minutes ago and one that genuinely matches nothing produce identical counts, which is what first_at tells apart.
Path parameters
Query parameters
Whole days, 1–90. Defaults to 7. 90 days is also the longest a workspace can keep engine runs.
Response200
What arming this policy would have changed
The window actually used, in whole days, after clamping.
Distinct machines among the matches.
Interactions this policy matched while watching.
Whether this policy's group is Off: it reads as Disabled and runs nowhere, so enabling it changes nothing until its group is On. The counts are still what it did while it ran.
Interactions the policy could not decide, because an engine returned no verdict. Under a policy that fails closed, each of these becomes a block once the policy is Enabled.
How many of those undetermined interactions would become blocks: equal to undetermined when this policy fails closed, and zero when it fails open.
The version the counts are being read for.
How many of those it would have stopped.
Equal to matched when the policy binds an inline enforcing action, and zero when it does not — which is the fact a promote button most needs to be able to say out loud. An alert-only policy in enforce alerts, exactly as it did in monitor; promoting it changes nothing about what anybody can do, and a preview that reported its match count as a blast radius would be arguing for a change that has none.
How long the version being previewed has existed, in whole hours, or null if that is not knowable.
The counts are not filtered by version, so when this is shorter than the preview window, some of the matches belong to an earlier version of the policy.
The earliest decision in the window, or null if there were none.
Errors
- 400
The window is out of range, or the id is reserved
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such policy in this workspace, or a provided policy it cannot preview
Restore a removed policy
Brings back a policy provided by Oxelone that this workspace removed, in the state it had, and republishes. Needs policies:write; restoring one that was Enabled also needs policies:publish, because it starts enforcing again.
Path parameters
Response200
Back in this workspace's list, in the state it had
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 403
Caller lacks policies:write in this workspace
- 404
Not a policy provided by Oxelone that this workspace removed
What a policy type can do
For one policy type, every filter field, comparison, engine, input and response a policy may use in this workspace, with how many machines can act on a filter field or a response today.
Query parameters
The policy type: prompt, file_artifact, asset, connector_event, or egress. Required; missing or unknown is a 400.
Which connection the catalogue is for. Meaningful only with subject=connector_event; ignored for every other type.
Which connector the catalogue is for.
The platform document's narrowing, and the one it needs: a vendor policy is written for one connector (vendor_policies.connector), and without this the document lists every live connector's record kinds in one list. On a workspace document the connection already names its connector, so this is only a cross-check: sending both and disagreeing is a 400, and sending it alone is ignored.
The Hook trigger's action kind (shell, file_read, …): narrows predicates and actions to what a policy on that action offers. Meaningful only with subject=hook; ignored elsewhere, like connection. An unknown word is a 400 that names the eight.
Response200
What this workspace can do with this policy type
Whether Oxelone can run this verb in this workspace: a connector exists for it, the subject carries a live request to act on, or a destination is stored. It does not depend on how many machines are enrolled.
Where the verb runs, derived from the verb: inline for an enforcing verb, connector for a connector verb, otherwise server_async.
The configuration keys this verb takes, in display order — for ask, message and require_reason.
How many of this workspace's machines this verb would act on today.
Zero is a normal answer. It is the coverage strip's sentence — fires on 0 of your machines today — and not a reason to hide a verb; an author can write a real policy before enrolling anything, and that is the case this field exists for.
Per verb rather than one number for the document, because the verbs genuinely differ and the differences are the interesting part: block counts machines whose capture sits in the request path, redact counts the narrower set whose capture reads a body at all, and alert counts every live machine because a server-side alarm needs nothing from the endpoint. A single count would be wrong for redact on a metadata fleet, which is the one sentence the whole coverage strip exists to say.
Why this verb is unavailable, as a full sentence. Present exactly when available is false.
What each engine can actually be asked about, as the engine declares it.
Whether this engine will answer in this workspace, the same answer GET /engines gives. An unavailable engine is still listed: a row may be written over it, and the editor warns beside the row.
The engine's display name, as the engine list shows it.
The engine's id, as a policy's engine filter names it.
The fields of the engine's own output a filter may read. Empty until the engine publishes them.
Only for llm-judge, and empty for every other engine.
The label vocabulary, narrowed to the backend this workspace selected. An unemittable label is listed and flagged rather than dropped: a policy written against a build that could emit it must still render, and the editor must still not offer it as a new condition.
The categories a Host policy may pick, for file_artifact; empty for every other subject. A policy picks at most one; none means every category.
The artifact events a Host policy over this category may be triggered by, in the File Events page's own order.
Not the same list for every category — HostCategory:: offered_events withholds content_changed from a category nothing hashes, and an AI Tool is an installation rather than a file. A picker that offered it anyway would let an author arm a trigger that can never fire, which is the placebo this whole document exists to prevent.
Why a filter over this category's content is refused, or absent when it is not refused — the domain own sentence, shown verbatim.
This is what keeps the narrowing from being unexplained. Switching a policy to Model weights takes the content filters out of the picker, and a picker that quietly gets shorter reads as a bug. The editor prints this beside the count it dropped.
Verbs this category alone offers, and on which triggers — today, Fix on AI tool, while present. Absent on every other category.
What may be given to an engine under this trigger — the text a policy can look at, as opposed to the facts in predicates. In picker order; empty for a subject with no editor.
The engines that will answer a filter written under this input. An engine that reads its subject by reference (rather than its text) is listed only under file_name on Host and request on Network.
The Host categories that allow it, as category ids. Empty means every one — a file's name and location are known whatever the file is. file_contents names the five categories that carry text; the three opaque ones and AI Dependency (read as entries rather than text) are absent. A Host policy that has picked no category may read contents. Empty on a Network document; always present.
The value a row's input carries: prompt | attachment | request | file_contents | file_name.
The sub-category choices under which this input is offered, where all means a policy that has not picked one. Empty means every choice, which is what the prompt and the whole request answer; only the attachment narrows, to ["all", "attachment"]. Empty on a Host document; always present.
The display name: The prompt, The file's contents.
The field a plain text filter over this input uses: contains and matches pattern are filters over prompt_text, attachment_text, body, artifact_text or artifact_path, not engine filters.
The sub-categories a Network policy may pick: today just Attachment, for prompt; empty for every other subject. A policy picks at most one; none means any interaction.
Why a Redact response is refused under this kind, or absent when it is not. No kind carries one today: a text attachment is rewritten, and a binary one carrying a named type is withheld.
Every filter field for this type, each with what it is worth in this workspace. Fields this workspace cannot answer yet are listed too.
The group this field is listed under: destination | application | identity | content | finding | context.
Machines in this workspace on which this predicate can be evaluated.
The filter's kind, exactly as a policy body writes it: service_is, body_contains, engine_label, and so on.
The field's display name, and only the name.
agent | server — where a filter over this field is answered: on the machine, or by Oxelone. One server-side filter moves the whole policy to the server.
The comparisons that can be evaluated over this field, in the order to offer them. Any other comparison is refused.
Whether machines on this tactic capture content. False for metadata and none, where content filters cannot match.
A capture tactic: extension, redirect, mitm_ca, metadata or none.
One machine is on exactly one tactic, so these counts sum to the workspace's live machine count.
The policy type this document answers for, echoed back from the request.
The service categories a filter with takes_categories may name, written $slug. Absent on a type with no such filter.
One line on what it covers.
A name, never a sentence: Criminal AI.
vendor (Oxelone's: additions only) or workspace (this workspace's own: renamed, described and deleted here).
What a policy stores: $criminal-ai.
How many of this workspace's Network policies name it. Only the Coverage Matrix's list carries it.
Everything the Connector trigger needs, and null on every other trigger.
The live connections this workspace has. Always present on a Connector document, because the trigger step's first control is this Select.
Empty without connection=: a record kind is a fact about one connection's credential, and answering for "any of them" would offer a catalogue no connection has.
The kinds of Fix a policy may apply. Host (file_artifact) only; absent on every other trigger.
What the row needs from the author: filter (it acts on what the filter matched), list (rules or sources typed in), mode (a start mode picked) or none.
The Hook trigger: one action kind per policy. Ask with subject=hook&action=<kind> for the filters that kind offers.
The eight kinds, in picker order.
The action this document's predicates and actions are for — the query's action — or null when none was asked, in which case predicates is every Hook filter and each kind's fields narrows it.
The AI tools a Lock is held on, as tool ids in a fixed order. A Lock that matches a tool outside this list does not hold on it. Hook and Host only; absent elsewhere.
Errors
- 400
The policy type is missing or unknown
- 401
No valid session
- 403
Caller lacks policies:read in this workspace
- 404
No such workspace, or the caller is not a member
Create a group of this workspace's own policies
Request bodyCreateGroupRequest
prompt, file_artifact or hook.
Members, in order: this workspace's own policies of subject, in no other group.
Response201
The group as stored, On
On (true) or Off. Off pauses every member.
The members, in member order.
A provided group this workspace removed (listed with the removed policies).
prompt (Network), file_artifact (Host) or hook (Hook).
oxelone for a provided group; absent for the workspace's own.
A provided group's content version: it moves when Oxelone changes the name, the description or the members. Absent for an own group.
Errors
- 400
Unknown type, a blank name, or a policy that may not be a member: not this workspace's, provided, of another type, or already in a group
- 401
No valid session
- 403
Caller lacks policies:write in this workspace
- 404
No such workspace, or the caller is not a member
Reorder policy groups
Sets the order one policy type's groups are read in. It changes nothing a machine runs.
Request bodySetGroupOrderRequest
Every group of that type this workspace has (removed provided ones excepted), in the order they should appear.
prompt, file_artifact or hook.
Response200
Order stored
How many groups moved: the number of ids sent, on success.
Errors
- 400
Unknown type, an id that is not one of this workspace's groups, a group of another type, a duplicate, or an incomplete list
- 401
No valid session
- 403
Caller lacks policies:write in this workspace
- 404
No such workspace, or the caller is not a member
Update a policy group
Rename, describe, or set the members of one of this workspace's own groups.
Path parameters
Request bodyUpdateGroupRequest
Response200
The group as stored; the bundle republished when an Off group's members changed
One group on a workspace's wire. Provided and own alike; a provided one says provided_by and vendor_version.
On (true) or Off. Off pauses every member.
The members, in member order.
A provided group this workspace removed (listed with the removed policies).
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 400
A blank name, or a policy that may not be a member
- 401
No valid session
- 403
Caller lacks policies:write — or policies:publish, when the change takes an Enabled policy out of an Off group
- 404
No such group in this workspace
- 409
The group is provided by Oxelone; its content cannot be edited here
Delete or remove a policy group
Deletes one of this workspace's own groups (its policies stay, in no group), or removes a group provided by Oxelone and its policies from this workspace; a removed provided group can be restored.
Path parameters
Response200
Deleted, or removed for this workspace; the bundle republished when what runs changed
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 401
No valid session
- 403
Caller lacks policies:write — or policies:publish, when deleting an Off group resumes an Enabled policy
- 404
No such group in this workspace, or a provided group it already removed
- 409
A Connector group: its rules are switched on each connection, not by the group
Restore a provided policy group
Brings back a group provided by Oxelone that this workspace removed, with its policies, each in the state it had.
Path parameters
Response200
Restored with its policies; the bundle republished
One group on a workspace's wire. Provided and own alike; a provided one says provided_by and vendor_version.
On (true) or Off. Off pauses every member.
The members, in member order.
A provided group this workspace removed (listed with the removed policies).
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 401
No valid session
- 403
Caller lacks policies:write in this workspace, or policies:publish when an Enabled policy of an On group would start enforcing
- 404
Not a provided group this workspace removed
Turn a policy group On or Off
Off pauses every member: each reads as Disabled and keeps its own state. On restores each as it was set.
Path parameters
Request bodySetGroupStateRequest
true is On, false is Off.
Response200
Switched, and the bundle republished in the same request
One group on a workspace's wire. Provided and own alike; a provided one says provided_by and vendor_version.
On (true) or Off. Off pauses every member.
The members, in member order.
A provided group this workspace removed (listed with the removed policies).
Whether this publish happened while enforcement is halted, and therefore enforces nothing whatever the policy list says.
Policies that compiled but cannot fire in this workspace as it is configured — almost always because of which backend an engine is set to. Empty is the normal case.
A warning and not a refusal: such a policy is undetermined rather than invalid, and refusing the compile would let switching a backend brick publishing for a whole workspace. Silence was the other option, and it is the worse one — an operator would leave a policy in enforce believing it covers something nothing is looking for.
Errors
- 401
No valid session
- 403
Caller lacks policies:write — or policies:publish, to switch on a group holding an Enabled policy
- 404
No such group in this workspace, or a provided group it removed
- 409
A Connector group: its rules are switched on each connection, not by the group