Firewall Matrix Generation
Automatically generate a network firewall matrix by modeling application connections and network zones.
Automating Firewall Rule Generation
Manually creating and maintaining firewall rules is a tedious and error-prone process. As applications evolve and new services are deployed, the firewall ruleset must be updated precisely. A mistake can lead to service outages or security vulnerabilities.
Rescile can automate the generation of a firewall matrix by modeling your applications, their network placements, and their communication patterns. This turns your architectural blueprint into a source of truth for your network security policy.
The Model
- Assets: We define our applications, the servers they run on, the networks those servers belong to, and a crucial list of explicit connections between applications.
- Model:
model/*.tomlfiles are used to propagate network zone information up to the application level, so each application is aware of its security context (e.g.,DMZ,INTERNAL). - Connections: The importer automatically creates
connectionnodes from a CSV file. These nodes link to their source and destination applications, creating a model of traffic flow. - Output: An
output/*.tomlfile iterates over everyconnectionand generates a structuredfirewall_ruleresource containing all the necessary information: source, destination, port, and protocol.
The Graph
The final graph contains a rich, traversable model of your application connectivity.
web-frontend
zone: DMZ] AppB[application
user-api
zone: INTERNAL] AppC[application
auth-service
zone: INTERNAL] Conn1[connection
web->api] Conn2[connection
api->auth] AppA -- "source_app" --> Conn1 Conn1 -- "dest_app" --> AppB AppB -- "source_app" --> Conn2 Conn2 -- "dest_app" --> AppC end subgraph Generated Output Rule1[firewall_rule
DMZ -> INTERNAL
on port 443] Rule2[firewall_rule
INTERNAL -> INTERNAL
on port 8080] end Conn1 --> Rule1 Conn2 --> Rule2
This graph can then be queried to generate a complete, accurate, and always-up-to-date firewall matrix.
Complete Example: From Assets to Firewall Rules
Let’s walk through a full example of generating firewall rules based on modeled application traffic.
1. Asset Data (data/assets/)
We define the components of our application stack.
applications.csv
name,servers
web-frontend,web-server-01
user-api,api-server-01
auth-service,api-server-02
servers.csv
name,networks
web-server-01,dmz-prod
api-server-01,internal-prod
api-server-02,internal-prod
networks.csv
name,zone
dmz-prod,DMZ
internal-prod,INTERNAL
connections.csv
name,source_app,dest_app,dest_port,protocol
web-to-api,web-frontend,user-api,443,tcp
api-to-auth,user-api,auth-service,8080,tcp
2.1. Architectural Model (data/models/network_zones.toml)
+This model propagates the zone property from a network resource, through its connected server, and up to the application. This ensures each application node is aware of its security zone. This is achieved in a single step by using path traversal in the from selector of the copy_property rule, pulling the data from a distantly related node.
# Propagate the 'zone' property from a network, through its server, up to the application.
# This uses path traversal to find the related network for each application.
origin_resource = "applications"
[[copy_property]]
from = "servers.networks"
properties = [ "zone" ]
2.2. Architectural Model (data/models/connections.toml)
This model establishes relationships between connection assets and the application assets they refer to. Since each connection has two distinct links to applications (a source and a destination), we use link_resources to create explicit, named relations (source_app and dest_app). These named relations are essential for the output template to traverse the graph and retrieve information from the correct source and destination applications.
# This model enriches a 'connection' asset with zone information by finding
# the related source and destination applications and copying their 'zone' property.
origin_resource = "connections"
# Find the source application and copy its zone property.
[[link_resources]]
with = "applications"
on = { local = "source_app", remote = "name" }
copy_properties = [ { from = "zone", as = "source_zone" } ]
# Find the destination application and copy its zone property.
[[link_resources]]
with = "applications"
on = { local = "dest_app", remote = "name" }
copy_properties = [ { from = "zone", as = "dest_zone" } ]
3. Output Generation (data/output/firewall_matrix.toml)
This is where the magic happens. We iterate over every connection resource and generate a structured firewall_rule. The template leverages Rescile’s path traversal capability to fetch data from related nodes. It follows the source_app and dest_app relations (created in the previous step) to access properties from the connected application resources, making the template clear and explicit.
origin_resource = "connections"
[[output]]
resource_type = "firewall_rule"
# Create a unique name for each rule.
name = "rule-{{ origin_resource.source_app[0].name }}-to-{{ origin_resource.dest_app[0].name }}"
# The template traverses the graph from the 'connection' node to its linked
# source and destination applications to gather all necessary info.
template = """
{
"source_zone": "{{ origin_resource.source_zone }}",
"source_app": "{{ origin_resource.source_app }}",
"destination_zone": "{{ origin_resource.dest_zone }}",
"destination_app": "{{ origin_resource.dest_app }}",
"destination_port": "{{ origin_resource.dest_port }}",
"protocol": "{{ origin_resource.protocol }}"
}
"""
4. Generating the Matrix with GraphQL
After running the importer, we can query for all the firewall_rule resources.
GraphQL Query
query GetFirewallRules {
firewall_rule {
name
destination_zone
destination_port
destination_app
source_zone
source_zone
protocol
}
}
Result:
{
"data": {
"firewall_rule": [
{
"name": "rule-web-frontend-to-user-api",
"destination_zone": "INTERNAL",
"destination_port": 443,
"destination_app": "user-api",
"source_zone": "DMZ",
"protocol": "tcp"
},
{
"name": "rule-user-api-to-auth-service",
"destination_zone": "INTERNAL",
"destination_port": 8080,
"destination_app": "auth-service",
"source_zone": "INTERNAL",
"protocol": "tcp"
}
]
}
}
Using a simple jq command, we can transform this JSON into a clean, human-readable CSV format, which serves as our final firewall matrix.
Command
# GQL_QUERY='...' (from above)
# JQ_FILTER='(.data.firewall_rule[0] | del(.name) | values) | ["Source Zone", "Source App", "Dest Zone", "Dest App", "Dest Port", "Protocol"], (.[] | [.source_zone, .source_app, .destination_zone, .destination_app, .destination_port, .protocol]) | @csv'
# curl ... | jq -r "$JQ_FILTER"
Generated firewall_matrix.csv
"Source Zone","Source App","Dest Zone","Dest App","Dest Port","Protocol"
"INTERNAL","user-api","INTERNAL","auth-service","8080","tcp"
"DMZ","web-frontend","INTERNAL","user-api","443","tcp"
This matrix, generated directly from your architectural source of truth, can now be used to configure your firewall, fed into automation pipelines, or used for security audits, ensuring your network policy is always synchronized with your application architecture.