Skip to content

`GET /v1/orgs/{org}/policies/preview/context`.

GET
/v1/orgs/{org}/policies/preview/context
curl --request GET \
--url https://api.updawg.net/v1/orgs/example/policies/preview/context

Everything preview reads besides the document, so that the portal can run the same engine in the browser on every keystroke instead of asking this endpoint each time (DAWG-93). Capped at the same number of hosts, oldest first, so the two answer about the same fleet.

org
required
string

Organization slug.

The policies in force and the fleet a preview evaluates. ⚠️ Check engine against the engine you run it with: a different version may decide differently, and the preview endpoint is the answer then.

Media typeapplication/json

Everything a preview reads besides the document: what the server hands the portal so the portal can preview without asking again on every keystroke.

object
engine
required

[ENGINE_VERSION] of the server that answered. A portal whose engine reports a different one must not preview with it.

string
hosts
required

At most the server’s preview cap, oldest first.

Array<object>

One host and the updates it has outstanding.

object
host
required

A host as the engine sees it.

object
groups

The groups this host belongs to, by name.

Array<string>
id
required

An enrolled host.

string format: uuid
labels

The host’s labels. A map rather than pairs, because a host cannot have one label twice and the type should say so.

object
key
additional properties
string
reboot_required

Whether the host is already waiting for a reboot, before any of these updates are applied. Not a selector today; carried because a proposal that will add a second reboot requirement to a host already needing one is worth showing, and because leaving it out of the input would make adding it later a change to every caller.

boolean
updates
required
Array<object>

One pending update, already classified against advisory data.

This is host_updates after evaluate_host has run (DAWG-56, DAWG-68): the kind is decided, the advisories are attributed, and the severity is whatever they said.

Ord is derived, and the field order is the sort order

The engine sorts the contents of a proposal so that two evaluations of the same fleet produce byte-identical output. Sorting on the package name alone is not enough: two updates for the same package compare equal, the sort is no longer a total order, and the caller’s input order leaks into the result. A property test found that within a minute of being written, which is more than the comment asserting the opposite had managed.

package is therefore first, and the rest of the fields follow so that any two distinguishable updates have a defined order. Reordering the fields changes the sort; nothing else depends on it.

object
advisory_ids

Which advisories this update would fix. Empty is not the same as unassessed: it means nothing published covers this package version.

Array<string>
candidate_version
required
string
current_version
required
string
kind
required

Ord is derived so this can key an ordered collection — the policy engine groups proposals by kind in a BTreeMap and needs a total order to produce the same output twice. The order itself is the declaration order and carries no meaning; nothing should read severity into it.

string
Allowed values: security patch kernel dist_upgrade
package
required
string
requires_reboot

Whether applying this one needs a reboot to take effect. From domain::classify::needs_reboot, which reads it off the package rather than off the kind — a kernel security update is classified security, so the kind cannot be trusted to carry this.

boolean
severity
One of:

None means nobody rated it, not “rated as harmless”.

This is an Option rather than a Severity for the reason domain::Severity spends twenty lines on: Debian publishes a rating for almost nothing, so on a Debian fleet unrated is the common case, and a policy that quietly treated it as a level would be making a judgement nobody made. [crate::SeverityMatch] is where that distinction is enforced.

string
Allowed values: none low medium high critical
hosts_total
required

How many hosts the organization has.

integer format: int64
live
required

Every live policy, disabled ones included: a disabled policy still holds its name and can still be edited.

Array<object>

A live policy, as the identity checks need it.

object
id
required

A policy.

string format: uuid
name
required
string
version
required

Which version is in force.

integer format: int32
policies
required

The enabled ones, compiled, in evaluation order: what the engine runs.

Array<object>

One policy, as the engine sees it.

object
enabled
required
boolean
id
required

A policy.

string format: uuid
maintenance_window
One of:

When a policy is willing to let work happen.

object
days

Empty means every day. The design document’s example lists three.

Array<string>
unique items
duration
required
string
start
required

Local wall-clock time in timezone, not UTC. A window written 02:00 is meant to stay at two in the morning through a clock change, which is the entire reason this field is not an offset.

string
timezone
required
string
name
required
string
priority
required

Higher wins. The column defaults to 100, which is what the design document’s example uses.

integer format: int32
rollouts

Named rollout strategies a rule may refer to. The engine only carries the name through to the intent — staged rollouts are epic 09, and what a stage does is not a decision this function makes.

object
key
additional properties

A named rollout strategy.

Carried through the engine untouched: all the engine does is refuse to name one that does not exist. What a stage selects is [crate::rollout::plan] (DAWG-107); advancing through them is the worker’s rollout_tick.

object
halt_on
object
failed_health_checks
integer format: int32
failed_jobs
integer format: int32
stages
required
Array<object>
object
count

Exactly this many more hosts (DAWG-107). Unlike percent, counted from this stage, because “the next five” is how a count is meant.

integer | null format: int32
hosts
One of:

Which hosts this stage covers, when it is selected by label rather than by proportion.

object
groups

The host is in any of these groups. Empty means “any group”.

Array<string>
unique items
labels

The host carries all of these labels, with exactly these values. Empty means “any labels”.

object
key
additional properties
string
name
required
string
percent

Bring the rollout up to this share of its hosts, counted from the start: 25 then 100 is a quarter, then everybody else. Hosts an earlier stage already took count towards it.

integer | null format: int32
soak
string | null
rules
required

Evaluated in order. The first rule that matches an update decides it.

Array<object>

One rule inside a policy.

object
action
required

What a rule decided should happen.

string
Allowed values: propose auto_merge ignore
apply

When an approved proposal may start.

string
Allowed values: asap asap_in_window
approval
One of:

None means “whatever this action implies” — see [Rule::requested_approval]. It is an Option rather than a defaulted value because the sensible default depends on the action, and a rule that says action: auto_merge and nothing else must not acquire an approval requirement that turns it into a proposal.

object
min_approvers
required

Ignored when required is false. Zero is meaningless and the schema rejects it; the engine treats anything below one as one rather than as “no approvers needed”, because rounding towards asking is the safe direction.

integer format: int32
required
required
boolean
batch
One of:

weekly in the example: fold everything this rule catches into one proposal per period rather than a stream of them.

string
Allowed values: daily weekly monthly
match

What an update has to look like for a rule to catch it.

Every field is a filter, and they are ANDed. A Match with nothing set catches every update, which is how the example policy’s last-resort rules are written.

object
kind

None means any kind.

Array<string> | null
unique items
Allowed values: security patch kernel dist_upgrade
packages

Empty means any package.

Array<string>
unique items
severity
One of:

None means any severity, including unrated.

object
levels
Array<string>
unique items
Allowed values: none low medium high critical
unrated

Spelled unrated in the YAML list, alongside the levels.

boolean
preflight

A step that may be required before a proposal applies.

string
Allowed values: optional required
reboot

What to do about a host that needs a reboot afterwards.

string
Allowed values: never immediate in_window
rollout

The name of one of the policy’s rollouts.

string | null
snapshot

A step that may be required before a proposal applies.

string
Allowed values: optional required
selector
required

Which hosts a policy applies to.

An empty selector matches every host

Deliberately, because “the org-wide default policy” has to be writable and the natural way to write it is to say nothing. It is also the way to apply a policy to the whole fleet by accident, so the schema (DAWG-86) should warn on it and the portal’s preview (DAWG-94) should show the host count before anybody saves.

object
groups

The host is in any of these groups. Empty means “any group”.

Array<string>
unique items
labels

The host carries all of these labels, with exactly these values. Empty means “any labels”.

object
key
additional properties
string
version
required

The row in policy_versions this came from. It travels into every proposal so “why was this proposed” stays answerable after an edit.

integer format: int32

Example

{
"hosts": [
{
"updates": [
{
"kind": "security",
"severity": "none"
}
]
}
],
"policies": [
{
"maintenance_window": {
"days": [
"tue"
],
"timezone": "Europe/London"
},
"rules": [
{
"action": "propose",
"apply": "asap",
"batch": "daily",
"match": {
"kind": [
"security"
],
"packages": [
"openssl*"
],
"severity": {
"levels": [
"none"
]
}
},
"preflight": "optional",
"reboot": "never",
"snapshot": "optional"
}
]
}
]
}

No session.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string

Example generated

{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

Not permitted for this role.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string

Example generated

{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

No such organization, or not yours.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string

Example generated

{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

The organization’s data is in another region (wrong-region, DAWG-159). detail names that region’s API; send the request there.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string

Example generated

{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}

Over the organization’s request limit. Retry-After says when to try again; RateLimit-Limit is the burst.

Media typeapplication/json
object
detail
string | null
status
required
integer format: int32
title
required
string
type
required
string

Example generated

{
"detail": "example",
"status": 1,
"title": "example",
"type": "example"
}