OPL Language
This page lists the parts of OPL that the Octet policy engine decides today. The Studio column says whether the Magistrate studio writes it yet. A policy that uses a part the studio doesn't write yet can still be decided by the engine.
Grammar
| Construct | Syntax | Example | Studio |
|---|---|---|---|
| Policy | policy <name> { <clauses> } |
policy p_… { … } |
Yes |
| Rule | rule permit\|deny when <condition> |
rule deny when outside(country("AT")) |
deny only |
| Condition | within(<region>), outside(<region>) |
within(subdivision("US-CA")) |
Yes |
| Region union | <region> union <region> |
country("CU") union country("IR") |
Yes |
| Region intersection | <region> intersect <region> |
country("US") intersect disc(40.71, -74.01, 50km) |
No |
| Region difference | <region> difference <region> |
country("US") difference subdivision("US-NJ") |
No |
| Grouping | ( <region> ) |
(country("AT") union country("DE")) difference … |
No |
| Comment | // … or /* … */ |
// Sanctions list, reviewed 2026-10 |
No |
intersect binds tighter than difference, which binds tighter than union. Use parentheses when in doubt.
Keywords
Policy clauses
| Keyword | Type | Description |
|---|---|---|
rule |
permit or deny, then when <condition> |
Applies its effect when the condition holds. A rule can end with reason "<label>", a label for people reading the policy. It isn't returned in the decision |
combine |
deny_overrides |
Any applicable deny rule wins. These docs cover only deny_overrides, the default |
default |
permit or deny |
The decision when no rule applies |
on_indeterminate |
deny |
The decision when the proofs can't settle a rule. deny is the default, and the studio doesn't write the clause. These docs cover only deny |
freshness |
duration | The oldest proof that counts. The studio always writes 5m. Without the clause, 300 seconds |
requires proof_level |
comparison and level | The least precise proof the policy accepts. Studio: No |
Conditions
| Keyword | Description | Studio |
|---|---|---|
within(<region>) |
The device is inside the region | Yes |
outside(<region>) |
The device is outside the region | Yes |
A condition is true, false or unknown. It is unknown when the proofs can't settle it, for example when the device proved only its country and the region is a state.
Regions
| Region | Syntax | Description | Studio |
|---|---|---|---|
| Country | country("<code>") |
An ISO 3166-1 alpha-2 code, for example "AT" |
Yes |
| Subdivision | subdivision("<code>") |
An ISO 3166-2 code, for example "US-CA" or "UA-43" (Crimea) |
US states and the regions in the sanctions lists |
| Disc | disc(<lat>, <lon>, <radius>) |
A circle around a point, in decimal degrees. The radius must be greater than zero | No |
Proof levels
For requires proof_level, from least to most precise. OPL has more precise levels than these three, which these docs don't cover yet:
| Level | The proof says |
|---|---|
on_earth |
The device is on Earth, nothing more |
country |
Which country the device is in |
subdivision |
Which state or region the device is in |
Compare with >=, >, ==, <= or <. For example, requires proof_level >= subdivision refuses to decide on a proof that names only a country. It answers UNKNOWN even when the answer looks obvious, such as a phone in London that proves only GB.
Types
| Type | Example | Notes |
|---|---|---|
| Country code | "AT" |
ISO 3166-1 alpha-2. Lower case is read as upper case. Territories have their own codes, so "US" excludes "PR" |
| Subdivision code | "US-CA" |
ISO 3166-2. Lower case is read as upper case |
| Latitude, longitude | 48.2082, 16.3738 |
Decimal degrees |
| Distance | 2000m, 2km |
Units m and km |
| Duration | 300s, 5m |
Units ms, s, m, h, d |
| String | "E-304" |
In double quotes |
Publishing checks
The engine checks a policy when it is published and refuses it if:
- it doesn't parse, including a disc whose latitude, longitude or radius is out of range
- a name is defined twice or used without being defined
- a region code doesn't exist
- it uses a region kind the engine can't decide yet, such as
city
See Errors for the exact messages.
Not yet supported
OPL has more than this page lists, for example time windows, named regions and obligations. The engine doesn't decide those for Magistrate policies yet. See What's Next.