Introduction to Access Policy Comparison
Understanding Intended Access Policy
Intended access policy is the declarative expression of who or what may communicate with whom, under which conditions, and with what protocol/port constraints. It is typically authored in a high‑level language (e.g., YAML, JSON, or a domain‑specific DSL) that is independent of any particular device syntax. The intent captures:
- Trust boundaries – logical zones (e.g.,
frontend,backend,db) defined by identity tags, labels, or security groups. - Allow/deny rules – ordered statements that map source selectors to destination selectors with action (
allow/deny) and optional logging. - Temporal or contextual qualifiers – time windows, authentication state, or posture attributes that may modify the rule’s effect.
Because the intent is abstract, it must be rendered into device‑specific configuration (ACLs, firewall rules, security group entries) before it can be enforced. The correctness of the enforcement hinges on the fidelity of each transformation step.
Rendered ACL Lines and Merged Device Config
Rendered ACL lines are the low‑level statements produced by a policy engine after it has translated the intent into the syntax of a target device (e.g., Cisco IOS access‑list, Juniper firewall filter, Linux iptables/nftables, or AWS security group JSON). Each line contains:
- Sequence number – determines evaluation order.
- Match criteria – source/destination IP, port, protocol, optionally DSCP, VLAN, or interface.
- Action –
permit/deny(oraccept/drop). - Optional modifiers – logging, rate‑limit, or count.
Merged device config is the final set of configuration lines that exist on the device after the rendered ACL has been combined with any pre‑existing configuration (e.g., legacy rules, interface‑specific overrides, or static NAT). Merging may involve:
- Append – new lines added at the end of an existing ACL.
- Insert – new lines placed at a specific sequence number, shifting existing lines.
- Replace – entire ACL swapped out, discarding prior content.
- Comment preservation – some engines keep human‑readable comments; others strip them.
If the merge operation is not deterministic or if the device’s parser interprets overlapping ranges differently, the applied state (what the device actually evaluates) can diverge from the rendered state (what the policy engine emitted).
Access Policy Drafting by AI Assistants
Overview of AI‑Driven Segmentation Changes
AI assistants that propose segmentation changes typically operate in a loop:
- Ingest current policy repository, topology data, and observed flow telemetry.
- Generate a candidate diff (add, modify, delete rules) that satisfies a stated goal (e.g., “allow
api‑svcto talk todb‑svcon TCP 3306”). - Score the candidate using a learned model that estimates risk, blast‑radius, and compliance with organizational guardrails.
- Emit a proposed change set in the same declarative format used by the policy‑as‑code pipeline.
Because the model is trained on historical configs, it may reproduce patterns that are syntactically correct but semantically misaligned with the current intent (e.g., using a stale subnet, mis‑typing a protocol number, or omitting an implicit deny). The assistant’s output looks plausible in a code review, yet the rendered ACL may enforce a different boundary.
Review Process for Drafted Segmentation Changes
A robust review combines static analysis and policy‑path tracing:
- Static lint – verifies syntax, checks for duplicate sequence numbers, ensures all referenced objects (address‑groups, service‑groups) exist.
- Semantic diff – compares the proposed intent against the baseline intent, highlighting added/removed selectors, changed actions, or altered ordering.
- Render‑time simulation – feeds the proposed intent through the same rendering engine used in CI to produce a predicted ACL; this ACL is then diffed against the current device config to surface any unintended inserts or deletions.
- Policy‑path verification – for each new rule, the reviewer explicitly states:
- Which selector (source/destination) caused the rule to match.
- Which evaluation order (sequence number) places it before or after existing rules.
- What action results for a given flow tuple.
If any step yields a mismatch between the reviewer’s expectation and the simulated outcome, the change is rejected or revised before merging.
Comparison of Intended and Rendered Policies
Identifying Discrepancies in ACL Lines
Discrepancies appear when the rendered ACL lines do not faithfully implement the intended rule set. Common patterns:
| Symptom | Likely Cause | Detection Method |
|---|---|---|
Missing deny for a subnet that should be blocked | Rendering engine omitted implicit deny or collapsed overlapping ranges | Compare intent‑derived deny list vs. rendered ACL; look for gaps in coverage. |
Extra permit for a service port not in intent | AI assistant inserted a rule with an overly broad port range (e.g., tcp any any 1024-65535) | Parse rendered ACL, extract port ranges, intersect with intent‑specified services. |
| Sequence number shift causing a rule to be evaluated after a conflicting deny | Merge operation used insert at wrong index or device renumbered ACL on reload | Render ACL with explicit sequence numbers; compare to device show access‑list output. |
Use of deprecated protocol number (e.g., ip vs tcp) | Rendering engine defaulted to ip when protocol unspecified | Verify each line’s protocol field against intent. |
A practical technique is to normalize both intent and rendered ACL into a common representation (e.g., a list of 5‑tuples: <src_ip/src_mask>,<dst_ip/dst_mask>,<proto>,<src_port>,<dst_port>,<action>) and then compute set differences.
Analyzing Merged Device Config for Inconsistencies
Even if the rendered ACL is correct, the merged config may introduce inconsistencies:
- Shadowing – a preceding rule in the merged ACL matches the same traffic with a conflicting action, rendering the intended rule ineffective.
- Overlap – two rules cover overlapping address spaces; the device’s algorithm may pick the first match, which may not be the rule the author expected.
- Interface binding mismatch – the rendered ACL is intended for
Gig0/1but the merge applied it toGig0/2due to a template error. - ACL type mismatch – applying an IPv4 ACL to an IPv6 interface (or vice‑versa) results in silent ignore on many platforms.
To detect these, extract the effective ACL from the device (show access‑list <name> or show firewall) and compare it to the rendered ACL after applying the same merge logic that the device uses (often documented in the vendor’s configuration guide). Any divergence points to a merge‑layer issue.
Tools and Techniques for Policy Comparison
| Tool | Primary Use | Example Command |
|---|---|---|
batfish | Intent‑to‑render validation, header space analysis | batfish analyze --questions HeaderSpace --inputs intent.yaml --snapshot ./configs |
cisco‑acl‑parser (Python) | Normalize Cisco ACL lines to 5‑tuples | python -m acl_parser --input rendered.acl --output normalized.json |
nftables‑json | Convert nftables rule set to JSON for diffing | nft list ruleset > current.json |
git diff --no-index | Quick textual diff of rendered vs. merged config | git diff --no-index rendered.acl merged.cfg |
opa (Open Policy Agent) | Evaluate custom policy (e.g., “no rule may permit 0.0.0.0/0”) | opa eval --data policy.rego --input rendered.json "data.allow" |
tcpdump / flowmon | Observe actual packets to validate enforcement | tcpdump -i eth0 -nn src 10.0.1.5 and dst 10.0.2.10 |
A typical CI job might run:
# .gitlab-ci.yml snippet
validate_policy:
script:
- batfish snapshot set ./intents ./rendered
- batfish question run HeaderSpace --snapshot ./intents
- python compare_acls.py --intent intent.yaml --rendered rendered.acl --device merged.cfg
Troubleshooting Wrong Boundary Enforcement
Common Causes of Enforcement Errors
- Incorrect selector expansion – AI generated
src: 10.0.0.0/8when intent wassrc: 10.0.1.0/24. - Implicit deny omission – rendering engine assumes a permissive default and does not add the final
deny any any. - Sequence number collision – two rules get the same number; the device keeps only the last one loaded.
- NAT or proxy interference – traffic is translated before ACL evaluation, causing the ACL to see post‑NAT addresses.
- Policy drift – a legacy rule not captured in the intent repository remains in the merged config and overrides the new intent.
- Vendor‑specific quirks – e.g., Cisco ACLs evaluate
establishedkeyword only for TCP; mis‑specifying it for UDP results in no match.
Step‑by‑Step Troubleshooting Guide
- State the observed symptom – e.g., “Host A (10.0.1.5) cannot reach Host B (10.0.2.20) on TCP 443.”
- Capture the flow – use a mirror or flow export to confirm the packet’s 5‑tuple as seen by the device.
- Retrieve the applied ACL –
show access‑list <name>or equivalent. - Trace the policy path:
- Identify the first ACL line that matches the