Skip to content
User Guide

Govern → Fact Policy

Fact Policy is the compliance layer over Facts. Where Session Policy is a firewall for live sessions, Fact Policy continuously asks “do my resources’ collected facts meet the rules I care about?” — for example “every router must have NTP synchronized,” “no host should expose Telnet,” or “production firewalls must run an approved software version.” Results are recorded over time and surfaced as a Compliance heatmap.

The tab has two sub-views, selected with the Rules / Checks toggle in its toolbar: Rules (the compliance rules) and Checks (reusable sets of assertions that rules reference).

How compliance is evaluated

After facts are collected, each rule whose scope matches the resource runs its checks; the result feeds the compliance heatmap and raises automation events when it changes:

flowchart TB
  facts["Collected facts about a resource"]
  facts --> match["Rules whose scope matches the resource<br/>by resource type / location / tags"]
  match --> checks["Each rule's checks &amp; assertions<br/>evaluated against the facts"]
  checks --> result{"Result"}
  result -->|pass| pass["Pass"]
  result -->|fail| fail["Fail · violation"]
  result -->|no applicable checks| na["N / A"]
  pass --> heat["Compliance heatmap<br/>+ automation events on change"]
  fail --> heat
  na --> heat

How rules are evaluated

Fact Policy is not a first-match firewall. Unlike Session Policy, rule order carries no precedence:

  • Evaluation is all-match: every rule whose selectors apply to a resource produces its own pass / fail / na / error result for that resource. One resource can be measured by many rules at once.
  • A rule’s position in the list is for display and organization only — it never shadows the rules below it.
  • Rules are re-evaluated automatically each time a resource’s facts are collected (on every snapshot). You do not run them by hand.
  • A rule applies to a resource only when every non-empty selector cell matches it. Within one cell, multiple values mean “any of these”; an empty cell means “any” and places no restriction on that dimension.
  • Checks use individually valid observations from the same resource and collection time, including partial collections. Collection warnings and fact-storage failures describe the evidence; they do not override a check’s verdict.
  • A disabled root fact type, missing/failed collection with no usable observations, or collection whose every supplied row was rejected makes that check N/A. An explicitly empty, valid ok or partial collection is different: its empty set is evaluated using the quantifier below.
  • Rules combine the pass/fail checks that were evaluated. Unavailable checks remain N/A, and the details show evaluated, unavailable, errored, and total check counts. With none evaluated, the rule is N/A. A genuinely invalid check or evaluation failure makes that resource’s rule result Error; errors and N/A are never inverted by Expected result.

Rules view

What a rule contains

FieldMeaning
NameA label for the rule.
CommentOptional notes.
Expected resultThe compliance polarity. Pass (default) means the checks must hold — the resource is compliant when they succeed. Fail inverts it — the rule records a violation when the checks hold (use it for “this must never be true”).
Resource TypesWhich resource types the rule measures (empty = all).
LocationsWhich locations (empty = all).
TagsResources carrying any selected tag (empty = all).
ChecksOne or more Fact Checks to evaluate; when several can be evaluated, all evaluated checks must hold. At least one is needed for the rule to do anything: a rule with no checks (or whose referenced checks are all disabled) is treated as not applicable — it produces no pass/fail result, and any result it previously produced is withdrawn.
NotifyWhen on, a compliance change fires an automation event — see Notify and Log.
LogWhen on, each compliance change is written to the audit trail — see Notify and Log.
EnabledTurn the rule on or off without deleting it.

Each rule row also shows a Hits badge — a running total, incremented each time the rule matches a resource during an evaluation (so it grows with every snapshot, rather than showing how many resources currently match). Use the Clear hit count control to reset it.

Common tasks

  • Create a rule — Click Create Rule, fill the form, save.
  • Reorder — Drag a row by its handle, or use the up/down arrows. This only changes the display order; it does not change which rules apply or their precedence.
  • Edit — Click the pencil icon on a row.
  • Enable / disable — Flip the Enabled toggle. The rule is kept but stops being evaluated while off.
  • Toggle Notify / Log — Flip these inline on the row; the change applies immediately.
  • Delete — Click the delete icon and confirm.

Checks view

A Fact Check is a reusable, named set of assertions evaluated against one fact type (for example interfaces, routes, or system NTP). Rules reference checks instead of repeating assertions, so you can maintain “ntp-synchronized” or “no-telnet” in one place and point many rules at it.

What a check contains

FieldMeaning
NameIdentifies the check (this is what rules select).
DescriptionOptional notes.
Fact typeThe root fact collection, selected from the installed definitions. Fields and declared relationships follow that definition.
AssertionsOne or more assertions. A check passes only when all assertions pass.

Author an assertion

Use Add assertion, give it an Assertion description, and choose Matching facts. Under Root fact conditions, use Add condition to select a Field, Operator, and typed Value. With no conditions, the group says Any fact.

All conditions in an assertion must hold on the same root fact. Its relationship requirements must also hold for that root. Conditions within a related-fact group must hold on the same related fact before its quantifier is applied. Separate assertions and separate relationship requirements are AND-ed; they do not require a shared candidate across those separate groups.

Matching factsMeaningWith an explicitly observed empty set
At least oneAt least one candidate matches all conditions.Fail
EveryEvery candidate matches. Require at least one fact is checked by default.Fail by default; pass if that checkbox is cleared
NoneNo candidate matches.Pass
CountCompare the number of matching candidates with Count, using Exactly, At least, or At most under Count comparison.Compare zero with the entered count

Count must be a whole number of zero or more; a blank count is invalid. These rules describe observations, not proof that something is physically absent. Unavailable observations do not use this empty-set table.

Fields inside ordinary objects can appear with qualified labels. Scalar lists support Contains with a typed item. Object/table arrays cannot be traversed as scalar conditions. Values retain their types: 10 as a name is a string; a numeric metric needs a number; a Boolean uses true or false. Date/time comparisons require a timezone and compare instants. An invalid observed date/time fails the comparison and carries a diagnostic.

No value (null) means explicit null, not an empty string. Nullable fields support null with Equals and Does not equal. Missing fields fail ordinary comparisons, including Does not equal. Is present means the path exists, even when null; Is absent means it is missing. These two operators need no value.

Use Add relationship, choose Relationship, then add Related fact conditions. The relationship follows only outgoing references declared on the root fact. It never infers a reverse relationship, joins names, crosses resources or collection times, or follows a second relationship from a related fact. For example, an L3 context does not gain an outgoing IPv4-assignments relationship merely because an assignment refers to it.

Singular and plural relationships use the same four Matching facts controls. A resolved singular reference supplies one candidate; an absent, null, or unresolved reference supplies zero. Plural references count distinct target identities, so repeated references do not inflate Count.

When a reference permits several target types, choose Target fact type. Only resolved targets of that selected type count; other branches are excluded. A type that was not collected, a target with no observations, or a missing referenced identity produces a diagnostic and zero resolved candidates, not a fabricated related fact. Apply the same empty-set rules to those candidates. Keep conditions intended to match one related fact together in one relationship section.

Changing a fact type, relationship, or target type identifies affected conditions. Use Clear affected conditions to accept that change, or Keep current selection to retain the current rows. Invalid saved values remain visible so they can be repaired before saving or testing.

Assertions start collapsed. Open an assertion header to edit its conditions and direct relationships; its description remains visible when collapsed. If validation finds an error, the affected assertion opens so you can correct the field.

Example: installed default IPv4 route in L3 context “10”

  1. Click Create Check, enter a name, and select Network > IPv4 routes (network_ipv4_route) as Fact type.
  2. Use Add assertion, open its header, and choose At least one under Matching facts.
  3. Under Root fact conditions, add Destination → Equals → 0.0.0.0/0 and Installed → Equals → true.
  4. Use Add relationship and choose Context l3 (context_l3). Its target is L3 contexts (network_context_l3). Keep At least one and add Name → Equals → 10 under Related fact conditions. Enter 10 as the string name, not a numeric value.
  5. Select Resource to test and click Run Test. Inspect the observation timestamp, counts, and examples, then save the check and attach it to a rule with Expected result: Pass.

The destination, installed flag, and reference to the context named “10” must belong to the same route. A default route in one context and another installed route in context “10” do not satisfy this assertion. False, null, or missing Installed does not match true.

Test assertions

Resource to test searches permitted resources by name as you type. Select a matching resource from the suggestions. Up to 20 matches are shown; keep typing to narrow broader searches. Run Test evaluates the current draft against one existing observation; it does not save, collect a snapshot, change compliance history, or send notifications. The timestamp is the observation time, not the time you pressed Test. When there is no observation, no timestamp is shown.

Results show assertion truth, candidate/matching/unresolved counts, collection diagnostics, and bounded matching/nonmatching examples. Counts cover every candidate even when samples are truncated. Missing values and explicit null are displayed separately. Changing the draft or selected resource makes the result stale until you test again.

Preview requires app.fact_policies.read and app.resources.read, with both permissions covering the selected resource’s location. Editing also requires app.fact_policies.write. Without preview access you can still author a check if you have the editing permissions.

Deleting checks

A check that is referenced by a rule cannot be deleted until the rule stops using it. (The list also carries a Built-in column reserved for system-maintained checks; all checks you see are your own.)

Common tasks

  • Create a check — Click Create Check, name it, choose a Fact type, then Add assertion for each assertion. Save.
  • Edit / delete a check — Use the pencil and delete icons on the row.

Notify and Log

The first evaluation establishes a baseline without sending an alert or security-log entry. After that, Notify fires resource.compliance.violation on a transition to Fail, including N/A → Fail and Error → Fail. It fires resource.compliance.resolved on Fail → Pass and Error → Pass. Moving to N/A or Error emits neither event; N/A → Pass also emits no resolution. A resource that still fails after a period without observations can therefore notify again. Wire these events to Automation Studio, filtering by rule and from/to status (Pass, Fail, N/A, or Error).

Log records those notification transitions as security-log entries, suitable for Log Forwarding. This is separate from Session Policy’s Policy Log.

Stored explanations can change while status remains the same. Those changes preserve historical evidence without firing an alert or adding a compliance transition to History. Actual status transitions remain visible independently of Notify and Log.

Seeing the results

Rules and checks define what to measure. Read the results in the Compliance heatmap on Dashboards or in the Summary → Compliance card on a location or resource, with drill-down to the failing resources and assertions.

Prerequisites

Fact Policy depends on the Facts subsystem. An administrator must enable the Facts toggle, and the relevant fact types must be collected for your resource types (see Facts configuration). With Facts off, no facts are collected and rules have nothing to evaluate.

Fact Policy is also an Enterprise feature. Without that edition the create/edit buttons show a lock and, more importantly, evaluation does not run: configured rules produce no compliance results until the entitlement is present. Previously recorded results stay visible.

Permissions

  • View rules and check definitions: app.fact_policies.read.
  • View compliance results and history: app.fact_policies.execute, within its allowed locations. This does not grant access to policy definitions.
  • Run Test and observed values in compliance details additionally require app.resources.read, with resource access at the resource’s location.
  • Create / edit / reorder / delete rules and checks: app.fact_policies.write.
  • Requires Facts to be enabled by an administrator.