Parse Cisco ASA and FTD running configurations into the shared firewall schema. Use when input contains show running-config, access-list, access-group, object network, object-group, nameif, security-level, NAT, interfaces, or failover, including audit, conversion, diff, summary, and explanation tasks.
Installation
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Parse Cisco ASA and FTD running configurations into the shared firewall schema. Use when input contains show running-config, access-list, access-group, object network, object-group, nameif, security-level, NAT, interfaces, or failover, including audit, conversion, diff, summary, and explanation tasks.
Use this skill to parse Cisco ASA and ASA-style FTD running configurations into the shared vendor-neutral firewall intermediate schema. It focuses on line-oriented show running-config text with parent commands and indented subcommands, including interfaces/nameifs, ACLs/access-groups, network and service objects, object-groups, NAT, routes, VPN, failover, and system settings.
Treat FMC-managed FTD exports and API data as adjacent but not identical inputs: parse what is present, preserve unresolved or unsupported structures in residual_raw, and call out assumptions rather than inventing missing policy context.
Scope and routing
Use only for Cisco ASA or FTD syntax. Hand off FortiOS config/edit/next/end blocks to parsing-fortinet-configs, PAN-OS XML or set deviceconfig to parsing-palo-configs, and Junos hierarchy or set security to parsing-srx-configs. Verify production-bound results against current device documentation and output. Downstream consumers are the audit, conversion, and diff skills.
Input Format
Cisco ASA configs are line-oriented with indented sub-commands:
Named interfaces use nameif (e.g., inside, outside, dmz)
security-level (0-100) determines trust level
Building Command Blocks
Group indented lines under their parent top-level command — see references/parsing-patterns.md "Building Command Blocks" for the algorithm and worked example.
Extraction Pipeline
1. Interfaces
Source: interface <hardware-id> blocks
Extract from sub-commands:
nameif <name> — the logical name used everywhere else
security-level <0-100> — trust level
ip address <ip> <mask> — IP and subnet mask
vlan <id> — VLAN assignment
shutdown — interface is administratively down
description <text>
bridge-group <id> — transparent mode bridge group membership
Interface types: detect Port-channel* as lag, Tunnel* as tunnel, Loopback* as loopback, Management* as management. Sub-interfaces contain . in name (e.g., GigabitEthernet0/0.100) — derive parent from name before the dot.
2. Zones (Derived from Interfaces)
ASA doesn't have explicit zones. Derive them from nameif values:
Each unique nameif becomes a zone
security-level values are parser-internal inference metadata used to determine relative trust ordering between zones (higher = more trusted). This is NOT emitted as a security_level or trust_level field in the intermediate schema — use it only to guide ordering or warn when ACLs are absent.
Associate the interface with its zone
3. Network Objects
Source: object network <name> blocks
Types from sub-commands:
host <ip> → type: "host", value: ip + "/32" (or "/128" for IPv6)
subnet <ip> <mask> → type: "subnet", value: ip + "/cidr" (convert mask to CIDR)
range <start> <end> → type: "range", value: "start-end"
fqdn v4 <domain> or fqdn v6 <domain> → type: "fqdn"
Note: bare fqdn <domain> (without v4/v6 qualifier) is also valid.
subnet <ipv6-prefix> → for IPv6 subnets the value is already in CIDR form, no mask conversion needed.
Also extract: description, inline nat statement (for object/auto NAT).
4. Network Object Groups
Source: object-group network <name> blocks
Members from sub-commands:
network-object host <ip> → inline host
network-object <ip> <mask> → inline subnet
network-object object <name> → reference to named object
group-object <name> → nested group reference
5. Service Objects
Source: object service <name> blocks
Parse: service <protocol> [source <op> <port>] [destination <op> <port>]
Operators: eq, range, gt, lt, neq
6. Service Object Groups
Source: object-group service <name> [<protocol>] blocks
Members:
port-object eq <port> / port-object range <start> <end>
Parse source static|dynamic and optional destination static components.
The optional numeric token is a line number — the rule's position within its manual NAT section — NOT a section selector. Derive the section from rule form: Section 1 = manual/twice NAT without after-auto (evaluated before object/auto NAT); Section 2 = object/auto NAT (rules inside object network blocks); Section 3 = manual NAT with the after-auto keyword (evaluated after all auto NAT).
Note: route-map and prefix-list references are not converted (warn)
OSPF:router ospf <pid> block — extract:
router-id, auto-cost reference-bandwidth
network <ip> <wildcard> area <id> — match interfaces to areas via wildcard mask comparison
Area types: stub, nssa, with no-summary; area default-cost; area authentication
passive-interface default + no passive-interface <nameif> exceptions
redistribute (connected/static with metric/metric-type)
Interface-level: ip ospf cost, ip ospf priority, ip ospf hello-interval, ip ospf dead-interval, ip ospf network point-to-point, ip ospf authentication message-digest + key
Normalize area IDs to dotted-decimal (0 → 0.0.0.0)
OSPFv3:router ospfv3 block with address-family ipv6 unicast — similar structure to OSPFv2
13. Infrastructure
Hostname:hostname <name> and domain-name <domain> → system metadata
Version:asa version <X.Y> or firepower version <X.Y> → metadata.source_version
HA/Failover:failover presence + failover lan unit primary|secondary (capture unit role),
failover interface ip, failover link
Flag weak algorithms (DES/3DES, MD5, DH group ≤ 5)
Syslog:logging host <nameif> <ip>
DHCP Server:dhcpd address <start>-<end> <nameif> (pool range),
dhcpd dns <ip1> [<ip2>], dhcpd domain <domain>, dhcpd lease <seconds>,
dhcpd enable <nameif> (commit trigger — binds staged options to interface).
Derive network CIDR from the interface IP.
DHCP Relay:dhcprelay server <ip> <iface> + dhcprelay enable <nameif>
14. Application Mapping (L7 → Canonical)
ASA/FTD is a port-based platform — it does not have native L7 application awareness in ACLs.
However, when converting FROM ASA to an app-aware platform (PAN-OS, FortiGate), or comparing
configs, the parser should attempt to resolve well-known port/protocol combinations to canonical
application names.
Resolution from port-based services:
For each service object or inline port match, check if the protocol+port maps to a known application:
Protocol
Port(s)
Canonical App
Category
TCP
443
https
web
TCP
80
http
web
TCP
22
ssh
remote-access
TCP
3389
rdp
remote-access
UDP
53
dns
network-mgmt
TCP
25
smtp
email
TCP
465
smtps
email
TCP
993
imaps
email
TCP
143
imap
email
UDP
123
ntp
network-mgmt
UDP
161
snmp
network-mgmt
UDP
162
snmp-trap
network-mgmt
TCP
21
ftp
file-transfer
TCP
23
telnet
remote-access
TCP
389
ldap
auth
TCP
636
ldaps
auth
UDP
69
tftp
file-transfer
TCP
1433
mssql
database
TCP
3306
mysql
database
TCP
5432
postgresql
database
TCP
445
smb
file-transfer
UDP
500
ipsec
tunnel
UDP
4500
ipsec-nat-t
tunnel
TCP
5060
sip
voip
UDP
5060
sip
voip
ASA named port keywords: Map ASA port names to numbers before resolving — full table in references/parsing-patterns.md "Port Name Resolution". Caution: ASA literals predate IANA assignments (radius=1645, radius-acct=1646, kerberos=750) — do not "correct" them from prior knowledge; use the reference table.
On policy output: When a service match resolves to a known application, populate the policy's
apps array with { vendor_name: "tcp/443", canonical: "https", confidence: 1.0, category: "web" }.
The services array still keeps the port-based match. This enables downstream converters to use
the app-aware rule on platforms that support it.
Unresolvable services: Complex port ranges, non-standard ports, or protocol groups that don't
map to a single known application → keep as port-based services only, no apps entry.
15. Application Groups
ASA does not have application groups. However, when converting FROM an app-aware platform,
object-group service entries that resolve entirely to known applications should be flagged
as potential application_groups in the IR for downstream use.
16. Anonymous Objects
When inline addresses/services appear in ACLs or object groups without a named reference (e.g., host 10.0.1.10 directly in an ACL line), create anonymous objects with auto-generated names (e.g., anon-1-host, anon-2-net). This ensures every IR reference points to a named object.
17. Residual Config Capture
Capture unrecognized top-level commands verbatim. Categorize into: VPN/IPsec, AAA, QoS, PKI/Certificates, IPv6, Other. Store in residual_raw for manual review.
18. Transparent Mode
Detect: firewall transparent in config
When in transparent mode:
Interfaces are in bridge-groups instead of having IPs
bridge-group <id> on interfaces
BVI interfaces (interface BVI<id>) carry the management IP
Zones derived from nameifs still work the same way
19. Implicit Rules
The ASA implicit deny is scoped per bound ACL, not global: each ACL applied via access-group
ends with an implicit deny for that interface/direction only. Applying an ACL on one interface
does NOT disable security-level defaults for other interface pairs.
After building all policies from ACLs + access-groups, append:
Implicit: Default Deny — one per access-group binding — action: "deny",
src_zones: [<bound nameif>] for in direction (dst_zones for out; all any for
global), remaining fields any, _implicit: true
When every traffic-passing interface has a bound ACL (or a global access-group exists),
the per-binding denies may be collapsed into a single final any→any deny, _implicit: true
For interfaces with NO ACL bound: do not fabricate a deny — security-level defaults still
apply (higher-to-lower permitted, lower-to-higher denied). Add a metadata.warnings entry
("no ACL bound on — security-level high-to-low permit applies") and, if downstream
consumers need explicit rules, model the default permit as an _implicit: true allow policy
from that zone to lower-security zones
Implicit-rule name values (e.g. "default-deny", "Implicit: Default Deny") are free-form labels; consumers must match implicit rules on _implicit: true, never on the name.
Output Format
Present results in the intermediate schema format documented in references/intermediate-schema.md.
Note: schema sections not yet populated by this pipeline (e.g., security_profile_objects, routing_contexts) are emitted empty ([]/{}); any unhandled source constructs are captured in residual_raw rather than dropped.
Full intermediate-schema emission is optional for single live-device work. The complete JSON schema exists primarily for cross-vendor conversion and multi-config diffing. When interpreting or auditing a single live device pulled via SSH/API for an ops/audit task, it is fine to reason directly from the running config and skip full schema emission — extract the sections relevant to the question. Emit the full schema when the parse will feed firewall-config-conversion, firewall-config-diff, or another config for comparison.
Parser Quality Gates
Before returning a parse, run these common quality gates and include the results in the response:
Format and scope detection — report detected vendor, platform family, config format, version clues, virtual context names (VDOM/vsys/logical-system/routing-instance), and whether input appears complete or partial.
Schema conformance — emit the vendor-neutral JSON sections defined in references/intermediate-schema.md; use empty arrays/objects for absent sections rather than omitting expected top-level keys.
Object counts — summarize counts for zones, interfaces, address objects/groups, service/application objects/groups, policies, NAT rules, routes, VPNs, HA, admin users, and residual blocks.
Reference resolution — list unresolved object, service/application, zone/interface, profile, route, VPN, and NAT references with source rule/context where possible.
Ordering preservation — preserve security policy order, NAT order, route order when relevant, and inherited/pre/post/global ordering metadata with _rule_index or a vendor-specific context field.
State preservation — preserve disabled/inactive objects and rules, comments/descriptions, tags, schedules/time-ranges, negation flags, logging settings, and profile attachments.
Residual capture — put unsupported or ambiguous source lines/blocks into residual_raw with enough context for manual review. Do not silently drop unknown syntax.
Warnings and assumptions — populate metadata.warnings with parser limitations, partial-input assumptions, ambiguous conversions, and version-specific caveats.
Conversion readiness — if the user asks for migration/conversion, explicitly separate parsed facts from proposed target-platform design choices and call out non-isomorphic features.
A high-quality parse is not just valid JSON: it must make uncertainty visible. Prefer a complete parse with warnings and residuals over a clean-looking parse that hides unsupported constructs.
Analysis Checks
After extraction, run these checks and report findings:
Unused objects — network/service objects not referenced in any ACL
Shadowed ACL entries — rules that can never match due to earlier entries
Overly permissive — permit ip any any or broad rules
Missing logging — permit ACL entries without log keyword
Inactive entries — ACL entries with inactive flag
Duplicate objects — same value, different names
Empty groups — object-groups with no members
Unbound ACLs — access-lists without matching access-group (never applied)
Subnet mask validation — flag any non-standard subnet masks
references/fixture-expected-output.json — Expected high-level intermediate-schema output for the minimal fixture
Secret Handling
Never emit secrets raw. Tunnel-group pre-shared keys, username ... password hashes, BGP neighbor passwords, and SNMP community strings must be masked as "****" (or represented as a presence flag) with a metadata.warnings entry noting the secret was redacted — matching the shared-schema convention ("psk": "****").
Common Pitfalls
Do not treat IOS wildcard masks as ASA subnet masks; ASA object subnets use standard dotted masks.
Do not infer policy direction from ACL names alone; bind ACLs to interfaces with access-group.
Object NAT and manual/twice NAT order matters. Preserve NAT section/order metadata and flag ambiguous translations.
Security levels are not zones by themselves, but they help infer trust roles when no explicit design notes exist.
FTD/FMC-managed output may omit policy context available in FMC; preserve gaps as warnings instead of fabricating rules.
Verification Checklist
Input vendor/platform and config format were detected correctly
All major object counts are reported: zones, interfaces, addresses, services/applications, policies, NAT, routes, VPN, HA, and system settings
Output conforms to references/intermediate-schema.md
Disabled/inactive rules and objects are preserved with explicit state
Unresolved references, unsupported blocks, and parser assumptions are listed in metadata.warnings and/or residual_raw
Rule order and NAT order are preserved with _rule_index or equivalent ordering metadata
Cross-vendor conversion caveats are called out before suggesting target-platform config
No raw secrets in output — PSKs masked as "****", routing-protocol passwords/keys reduced to presence flags with warnings