Deployment guide

Batfish 2026.08.27.3685

Overview

Batfish is an open source (Apache-2.0) network configuration analysis tool. You give it the configuration files of your routers, switches and firewalls, and it builds a model of the whole network without touching a single device. Supported formats include Cisco IOS, IOS-XR and NX-OS, Juniper Junos, Arista EOS, Palo Alto, Fortinet, Check Point, Cumulus, SONiC, AWS VPC data and more.

You then ask questions through the Python client, pybatfish. Which BGP sessions come up? Where does a packet from host A to host B go, and why? Which ACL line blocks it? Which references are undefined? What would a change do before you deploy it? Network teams use Batfish to validate changes in CI, to audit configurations and to answer reachability questions without a lab.

This guide covers launching and using Batfish 2026.08.27.3685 on Ubuntu 24.04 from SecureAnyCloud on Amazon EC2. It is one version of the SecureAnyCloud Hardened FRRouting, OpenBGPD & BGP Routing and Peering AMIs listing on AWS Marketplace. You pick it as the software version when you subscribe and launch. The other routing and peering products in the listing are described on the listing's guide hub.

What you get:

  • HTTPS only, on 9996. nginx serves TLS 1.3 and TLS 1.2 (ECDHE with AEAD ciphers only) on port 9996, the port pybatfish uses. It passes requests to Batfish, which listens on 127.0.0.1:19996 only. Port 80 is closed, and TLS 1.1 and 1.0 are refused (Step 9).
  • A certificate made on your instance. At first boot, the instance gets a TLS key and an end-entity certificate for its own names and addresses. The certificate can only vouch for this server and can never sign other certificates. Point pybatfish at it (Step 6), or replace it with one for your own DNS name (Step 12).
  • An API key on every request, generated for your instance. Batfish's own default setup accepts any client, and pybatfish ships a published default key of 64 zeros. On this image, every request needs this instance's 256-bit API key or this instance's HTTP Basic login. The key is the X-Batfish-Apikey header that pybatfish sends, or Authorization: Bearer. Everything else gets 401, including /v2/version. Both nginx and Batfish's own file authorizer check the key, and both refuse the published default key (Step 8).
  • No network access for Batfish. Batfish analyses the files you upload and never needs to connect anywhere. The Batfish service can reach 127.0.0.1 and ::1 only: no instance metadata, no VPC, no DNS and no internet (Step 10).
  • Services that refuse to start with a bad credential. Before each start, a preflight check refuses a missing, unreadable, malformed, empty or default key file, login file, certificate or gate map. The service is then left failed and not restarting, and nothing listens on 9996 (Step 11).
  • A source build with three security dependency raises. The Batfish jar is a SecureAnyCloud build of the Batfish project's v2026.08.27 release commit (329c14bf), unchanged except for three bundled libraries. These are raised to the versions the Batfish project itself adopted on its main branch after that release: jackson-bom 2.22.1 to 2.23.0, guava-bom 33.6.0-jre to 33.7.2-jre and lz4-java 1.11.2 to 1.14.0. The project's own release jar bundles the older versions, which have published security advisories. The build record, the exact dependency diff and the jar's SHA-256 digest are shipped on the image (Step 14). Batfish has no telemetry, and Ubuntu 24.04 LTS is fully patched at build time.
  • Batfish 2026.08.27.3685. The jar is /opt/batfish/allinone-bundle.jar. batfish.service runs it on the Ubuntu OpenJDK 21 runtime as the locked system user batfish, with analysis storage in /var/lib/batfish.
  • pybatfish 2026.08.27.3685. The Python client is in /opt/batfish/pybatfish-venv.
  • nginx from Ubuntu 24.04 as the TLS front on 9996.
  • First-boot service and helpers. batfish-firstboot.service prepares the key, the login and the certificate on first boot. The helpers are batfish-demo, batfish-preflight and batfish-tls-renew.
  • The Batfish example network. The 15-device network is in /usr/share/batfish/example-snapshot, next to the question templates and the build record. The licences are in /usr/share/doc/batfish/ and /usr/share/batfish/THIRD-PARTY-NOTICES.
  • 24/7 SecureAnyCloud support

Default user: ubuntu. Architecture: x86_64. Root volume: 8 GiB gp3.

Prerequisites

  • An AWS account and permission to launch EC2 instances
  • An EC2 key pair in the Region you launch in
  • A VPC subnet, and the addresses of the workstations or CI runners that will run pybatfish
  • A security group that allows the ports below:

Port Protocol Source Purpose

22 TCP your admin network SSH

9996 TCP the workstations and CI runners that run pybatfish Batfish over HTTPS

Nothing else needs to be open. Batfish's own port 19996 is bound to 127.0.0.1 and port 80 is not served, so opening them achieves nothing.

Recommended instance type: m5.large. Batfish runs in a Java virtual machine whose heap is sized at first boot to 55% of the instance's memory (4.2 GB on an 8 GiB instance).

Larger networks need more memory. This applies to networks with hundreds of devices or very large firewall rule bases. Launch on r5.large or r5.xlarge, and first boot sizes the heap from that instance's memory. To change the heap on a running instance, see Step 13.

Connecting to your instance

Version Operating system SSH user

Batfish 2026.08.27.3685 on Ubuntu 24.04 Ubuntu 24.04 LTS ubuntu

1

Launch the instance

Option A: AWS Marketplace console

  • Open the SecureAnyCloud Hardened FRRouting, OpenBGPD & BGP Routing and Peering AMIs listing on AWS Marketplace. Choose View purchase options, then Subscribe. One subscription covers every version in the listing.
  • When the subscription is active, choose Launch your software.
  • Choose One-click launch from AWS Marketplace, or Launch from EC2 Console for the full launch wizard. In Version, choose Batfish 2026.08.27.3685 on Ubuntu 24.04, then choose your Region.
  • Pick an instance type (m5.large recommended) and your key pair.
  • Set the security group to allow SSH (22) from your own address and TCP 9996 from the networks that will run pybatfish.
  • Choose your VPC and subnet. Leave the metadata defaults, because the image already requires IMDSv2. Then choose Launch.

Option B: AWS CLI

Run this on your own workstation. Replace the AMI ID with the one shown for your Region on the Marketplace launch page. Replace the VPC, subnet, key pair and CIDRs with your own:

SG=$(aws ec2 create-security-group --group-name batfish \
  --description "Batfish" --vpc-id vpc-0123456789abcdef0 \
  --query GroupId --output text)
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 22 --cidr <your-mgmt-cidr>
aws ec2 authorize-security-group-ingress --group-id "$SG" --protocol tcp --port 9996 --cidr <your-client-cidr>
aws ec2 run-instances \
  --image-id ami-0123456789abcdef0 \
  --instance-type m5.large \
  --key-name my-key-pair \
  --security-group-ids "$SG" \
  --subnet-id subnet-0123456789abcdef0 \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=batfish}]'

You do not need --metadata-options, because the AMI already requires IMDSv2.

2

Connect and read your instance's details

Connect as ubuntu with the key pair you chose:

ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>

First boot finishes within a minute of launch. It generates this instance's API key, its HTTP Basic password, the TLS certificate and the heap size. It records them in /root/batfish-credentials.txt, which only root can read.

First boot starts nothing itself. systemd starts Batfish and nginx once it has finished, and Batfish is ready about 20 seconds later. Run the following commands to show the lines that are not secret:

sudo stat -c '%a %U %n' /root/batfish-credentials.txt
sudo grep -E '^BATFISH_(HOST|PORT|URL|USERNAME|TLS_CERT|TLS_SHA256_FINGERPRINT)=' /root/batfish-credentials.txt
600 root /root/batfish-credentials.txt BATFISH_HOST=44.202.20.163 BATFISH_PORT=9996 BATFISH_URL=https://44.202.20.163:9996 BATFISH_USERNAME=batfish BATFISH_TLS_CERT=/etc/batfish/tls/cert.pem BATFISH_TLS_SHA256_FINGERPRINT=8F:86:B3:C8:15:1B:22:A6:C6:79:ED:5E:E9:FD:FD:59:DE:32:E4:2E:35:83:1B:44:2D:0A:88:84:7F:1C:FF:A6

The file also holds BATFISH_API_KEY, the key pybatfish uses, and BATFISH_PASSWORD, the password of the HTTP Basic login batfish. View them with sudo cat /root/batfish-credentials.txt.

Keep them in files with mode 0600 or in your CI system's secret store. Never put them on a command line, which every user on a machine can see through ps, or in shell history.

3

Check the services and the listening set

systemctl is-active batfish-firstboot batfish nginx
sudo ss -tlnp | grep -E ':(22|80|443|9996|19996) '
sudo ss -ulnp | grep -E 'java|nginx' || echo 'no UDP socket from Batfish or nginx'
active active active LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=1090,fd=3),("systemd",pid=1,fd=57)) LISTEN 0 511 0.0.0.0:9996 0.0.0.0:* users:(("nginx",pid=1155,fd=5),("nginx",pid=1154,fd=5),("nginx",pid=1153,fd=5)) LISTEN 0 4096 [::ffff:127.0.0.1]:19996 *:* users:(("java",pid=1020,fd=6)) LISTEN 0 4096 [::]:22 [::]:* users:(("sshd",pid=1090,fd=4),("systemd",pid=1,fd=58)) LISTEN 0 511 [::]:9996 [::]:* users:(("nginx",pid=1155,fd=6),("nginx",pid=1154,fd=6),("nginx",pid=1153,fd=6)) no UDP socket from Batfish or nginx

batfish-firstboot prepared the credentials, batfish is the analysis service and nginx is the TLS front.

Only nginx listens on the network (9996, IPv4 and IPv6). The Java process listens on 127.0.0.1:19996 only, shown in its IPv4-mapped form [::ffff:127.0.0.1]. Batfish's analysis worker runs inside the same process and opens no port of its own.

4

Check the certificate

The server's certificate is self-signed and made on your instance. Inspect it with:

sudo openssl x509 -in /etc/batfish/tls/cert.pem -noout -subject -enddate -ext subjectAltName,basicConstraints,extendedKeyUsage
subject=CN = 44.202.20.163, O = sac notAfter=Feb 12 22:59:36 2029 GMT X509v3 Subject Alternative Name: IP Address:44.202.20.163, DNS:ec2-44-202-20-163.compute-1.amazonaws.com, IP Address:172.31.87.25, DNS:ip-172-31-87-25.ec2.internal, IP Address:127.0.0.1, DNS:localhost X509v3 Basic Constraints: critical CA:FALSE X509v3 Extended Key Usage: TLS Web Server Authentication

The certificate names the instance's public and private addresses and DNS names, so a client can verify it whichever address it connects to.

CA:FALSE means it can never be used to sign another certificate. Trusting it in your client trusts this one server and nothing else. The SHA-256 fingerprint in the credentials file lets you check a copy of the certificate before you trust it.

5

Run the demo

The image ships the Batfish project's example network: 15 devices across three autonomous systems, with configurations for border, core, distribution and department routers, two hosts and a set of external BGP announcements. batfish-demo connects pybatfish to this instance over TLS on 9996 with the instance's API key. It uploads that network and lists its devices:

sudo batfish-demo
as1border1 as1border2 as1core1 as2border1 as2border2 as2core1 as2core2 as2dept1 as2dist1 as2dist2 as3border1 as3border2 as3core1 host1 host2 BATFISH_DEMO_OK nodes=15

The first analysis of a snapshot takes about 20 seconds. Later questions on the same snapshot answer in about a second.

6

Connect pybatfish from your workstation

Most people run pybatfish on their own workstation or in CI and point it at the instance. Install the client version that matches the server and copy the instance's certificate. Keep the API key in a file that only you can read:

python3 -m venv ~/batfish-client && . ~/batfish-client/bin/activate pip install 'pybatfish==2026.8.27.3685' scp -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip>:/etc/batfish/tls/cert.pem ~/batfish-cert.pem openssl x509 -in ~/batfish-cert.pem -noout -fingerprint -sha256
# compare with BATFISH_TLS_SHA256_FINGERPRINT ( umask 077; ssh -i ~/.ssh/my-key-pair.pem ubuntu@<public-ip> \
  "sudo sed -n 's/^BATFISH_API_KEY=//p' /root/batfish-credentials.txt" > ~/.batfish-api-key )

Then connect with TLS on, using the certificate as the trust anchor and the key from the file:

from pathlib import Path from pybatfish.client.session import Session bf = Session(host="<public-ip>", port=9996, ssl=True, verify_ssl_certs=str(Path.home() / "batfish-cert.pem"), api_key=(Path.home() / ".batfish-api-key").read_text().strip()) bf.set_network("my-network") bf.init_snapshot("path/to/snapshot", name="baseline", overwrite=True) print(len(bf.q.nodeProperties().answer().frame()), "devices")

From a second instance in the same VPC, connecting to this instance's private address, the same code against the example network printed this:

pybatfish off-host nodeProperties rows: 15

Three settings matter:

  • ssl=True, because the instance serves HTTPS only.
  • verify_ssl_certs set to the certificate file, so the client checks that it is talking to your instance. The system CA store does not know this certificate, so leaving the setting at its default fails with a certificate error.
  • api_key, because without it pybatfish sends its published default key. This instance refuses that key with 401 Client Error: Unauthorized.
7

Analyse a network

A snapshot is a directory with your device configurations in a configs folder. Use one file per device, as the device prints it with show running-config or the equivalent. You can optionally add hosts, iptables and external_bgp_announcements.json:

snapshot/ configs/ router1.cfg, router2.cfg, firewall1.cfg ... hosts/ optional: end hosts as JSON external_bgp_announcements.json optional: routes your border routers receive

These questions run against the bundled example on the instance itself. On your workstation, the same calls work on the Session from Step 6:

sudo /opt/batfish/pybatfish-venv/bin/python3 -I - <<'EOF' import logging logging.disable(logging.WARNING) import pandas as pd pd.set_option("display.width", 200) cfg = dict(l.strip().split("=", 1) for l in open("/root/batfish-credentials.txt") if "=" in l and not l.startswith("#")) from pybatfish.client.session import Session from pybatfish.datamodel.flow import HeaderConstraints bf = Session(host="127.0.0.1", port=9996, ssl=True, verify_ssl_certs=cfg["BATFISH_TLS_CERT"], api_key=cfg["BATFISH_API_KEY"]) bf.set_network("example-dc") bf.init_snapshot("/usr/share/batfish/example-snapshot", name="baseline", overwrite=True) print("parse issues:", len(bf.q.initIssues().answer().frame())) s = bf.q.bgpSessionStatus().answer().frame() print(s[["Node", "Remote_Node", "Session_Type", "Established_Status"]].head(4).to_string(index=False)) print("BGP sessions:", len(s), s["Established_Status"].value_counts().to_dict()) u = bf.q.undefinedReferences().answer().frame() print(u[["File_Name", "Struct_Type", "Ref_Name"]].to_string(index=False)) t = bf.q.traceroute(startLocation="host1", headers=HeaderConstraints(dstIps="2.128.1.101", applications=["ssh"])).answer().frame() tr = t.iloc[0]["Traces"][0] print("host1 -> 2.128.1.101 ssh:", tr.disposition, "via", " -> ".join(h.node for h in tr.hops)) EOF
parse issues: 0 Node Remote_Node Session_Type Established_Status as1border1 None EBGP_SINGLEHOP NOT_COMPATIBLE as1border1 as1core1 IBGP ESTABLISHED as1border1 None EBGP_SINGLEHOP NOT_COMPATIBLE as1border1 as2border1 EBGP_SINGLEHOP ESTABLISHED BGP sessions: 37 {'ESTABLISHED': 34, 'NOT_COMPATIBLE': 3} File_Name Struct_Type Ref_Name configs/as2core2.cfg route-map filter-bogons host1 -> 2.128.1.101 ssh: ACCEPTED via host1 -> as2dept1 -> host2

Batfish found that every configuration is parseable and that 34 BGP sessions come up. It also found 3 sessions that point at peers outside the snapshot, a route map that as2core2 refers to but never defines, and the path an SSH connection from host1 takes to host2.

The Batfish documentation lists every question. Examples are filterLineReachability (ACL lines that can never match), searchFilters, reachability, differentialReachability (what a change breaks) and compareFilters.

8

Authentication

Every request to 9996 needs this instance's API key or its HTTP Basic login. Only /nginx-health answers without one.

Run this block to read the key and the password into files in /dev/shm, never onto a command line, and to try each case:

sudo bash -s <<'EOF' umask 077
D=$(mktemp -d /dev/shm/bf.XXXXXX); trap 'rm -rf "$D"' EXIT printf 'X-Batfish-Apikey: %s\n' "$(sed -n 's/^BATFISH_API_KEY=//p' /root/batfish-credentials.txt)" > "$D/key" printf 'X-Batfish-Apikey: %s\n' 0000000000000000000000000000000000000000000000000000000000000000 > "$D/default" printf 'machine 127.0.0.1 login batfish password %s\n' "$(sed -n 's/^BATFISH_PASSWORD=//p' /root/batfish-credentials.txt)" > "$D/netrc" C=/etc/batfish/tls/cert.pem; U=https://127.0.0.1:9996 echo "no credential: $(curl -s -o /dev/null -w '%{http_code}' --cacert $C $U/v2/version)" echo "published default key: $(curl -s -o /dev/null -w '%{http_code}' --cacert $C -H @"$D/default" $U/v2/version)" echo "instance API key: $(curl -s -o /dev/null -w '%{http_code}' --cacert $C -H @"$D/key" $U/v2/version)" echo "HTTP Basic login: $(curl -s -o /dev/null -w '%{http_code}' --cacert $C --netrc-file "$D/netrc" $U/v2/version)" echo "health, no credential: $(curl -s --cacert $C $U/nginx-health)" curl -s --cacert $C -H @"$D/key" $U/v2/version; echo EOF
no credential: 401 published default key: 401 instance API key: 200 HTTP Basic login: 200 health, no credential: ok {"Batfish":"2026.08.27.3685","api_version":"0.0.0"}

The same matrix from a second instance in the VPC, against this instance's private address, gave two results:

  • 401 with no credential, the published default key, a key that differs in one character, the key of the image's build machine and a wrong Basic password.
  • 200 with the instance key (as X-Batfish-Apikey or Authorization: Bearer) and the Basic login.

Here is how it works. nginx admits a request only with the instance key (in X-Batfish-Apikey, Authorization: Bearer or X-Api-Key) or the bcrypt-hashed Basic login in /etc/nginx/batfish.htpasswd. It then removes the client's Authorization, X-Api-Key and cookies, and hands Batfish the instance key itself.

Batfish runs its own file authorizer (-authorizertype file) against that key. A request that somehow reached 127.0.0.1:19996 without the key would be refused too. The Basic login is there for tools that speak HTTP Basic. pybatfish uses the API key.

9

TLS only

for v in tls1 tls1_1 tls1_2 tls1_3; do r=$(echo | timeout 8 openssl s_client -connect 127.0.0.1:9996 -$v 2>/dev/null </dev/null | grep -E '^New, ' | head -1)
echo "$v: ${r:-refused}" done
echo "plain HTTP to 9996: $(curl -s -o /dev/null -w '%{http_code}' -m 5 http://127.0.0.1:9996/v2/version)" curl -s -m 5 http://127.0.0.1/ >/dev/null && echo "port 80 answered" || echo "port 80: connection refused"
tls1: New, (NONE), Cipher is (NONE) tls1_1: New, (NONE), Cipher is (NONE) tls1_2: New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384 tls1_3: New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384 plain HTTP to 9996: 400 port 80: connection refused

TLS 1.0 and 1.1 handshakes fail (Cipher is (NONE)). Plain HTTP sent to 9996 gets nginx's 400 The plain HTTP request was sent to HTTPS port and never reaches Batfish. Nothing listens on port 80.

10

No network access for Batfish

Batfish works only on the files you upload, so on this image it has no network access beyond loopback. systemd enforces this on the service's control group:

systemctl show batfish -p User -p IPAddressAllow -p IPAddressDeny -p CapabilityBoundingSet -p NoNewPrivileges -p ProtectSystem -p Restart
systemctl show nginx -p IPAddressDeny -p BindsTo
Restart=on-abnormal IPAddressAllow=127.0.0.1/32 ::1/128 IPAddressDeny=0.0.0.0/0 ::/0 CapabilityBoundingSet= User=batfish ProtectSystem=strict NoNewPrivileges=yes IPAddressDeny=::ffff:168.63.129.16/128 168.63.129.16/32 ::ffff:169.254.169.254/128 169.254.169.254/32 fd00:ec2::254/128 BindsTo=batfish.service

Batfish runs as the locked user batfish with no capabilities, a read-only system, and every address except 127.0.0.1 and ::1 denied. From inside the service, connections to the instance metadata service, the VPC DNS resolver, the local DNS stub and the internet are all refused. The same connections from root succeed.

nginx needs the network to serve you, but it cannot reach the instance metadata service. The TLS key and the login file are invisible to the Batfish process.

11

Fail closed and crash recovery

Each service checks its credentials before every start (batfish-preflight). Suppose the API key file, the login file, the TLS key or certificate, or nginx's gate map is missing, unreadable, malformed, empty or the shipped default. Then the service is left failed and not restarting, and nothing listens on 9996. These are the results of breaking each one on a test instance:

gate-map missing: nginx failed (exit-code), NRestarts 0 -> 0 after 11 s, nothing on 9996 htpasswd sha1: nginx failed (exit-code), NRestarts 0 -> 0 after 11 s, nothing on 9996 htpasswd plaintext: nginx failed (exit-code), NRestarts 0 -> 0 after 11 s, nothing on 9996 tls-key malformed: nginx failed (exit-code), NRestarts 0 -> 0 after 11 s, nothing on 9996 users missing: batfish failed (exit-code), NRestarts 0 -> 0 after 21 s, nothing on 9996 users default-key: batfish failed (exit-code), NRestarts 0 -> 0 after 21 s, nothing on 9996 20 cases refused (failed, not restarting, nothing on 9996) and each restored to 200

A crash is different. If the Java process or nginx is killed, systemd restarts it and the API key is served again. nginx is bound to Batfish (BindsTo=), so it never serves on 9996 while Batfish is down.

To see why a service refused to start, run:

sudo journalctl -u batfish -u nginx -b --no-pager | tail -n 20
12

Use your own DNS name for the certificate

If you reach the instance by a DNS name of your own, mint a new certificate that includes it. An example is batfish.example.com pointing at an Elastic IP. The helper keeps the instance's own names and addresses, updates the fingerprint in /root/batfish-credentials.txt and reloads nginx:

sudo batfish-tls-renew batfish.example.com

Afterwards, copy the new /etc/batfish/tls/cert.pem to your clients.

To use a certificate from your own CA instead, replace /etc/batfish/tls/cert.pem and /etc/batfish/tls/key.pem (owner root, key mode 0600). Then run sudo systemctl restart nginx. The preflight check refuses a key that does not match its certificate.

13

Manage the service

systemctl status batfish --no-pager -n 0 | head -n 6
sudo grep -E '^BATFISH_HEAP_OPTS=' /etc/default/batfish
● batfish.service - Batfish network configuration analysis service (sac; loopback only, behind nginx TLS on 9996) Loaded: loaded (/etc/systemd/system/batfish.service; enabled; preset: enabled) Drop-In: /etc/systemd/system/batfish.service.d └─50-sac-imds-deny.conf Active: active (running) since Tue 2026-11-10 22:59:44 UTC; 21min ago Docs: https://secureanycloud.com/stacks/batfish-2026-08-27-3685/ BATFISH_HEAP_OPTS=-Xms256m -Xmx4298m

Batfish keeps uploaded snapshots and answers under /var/lib/batfish/containers until you delete them with bf.delete_network("name") or bf.delete_snapshot("name").

To change the heap after resizing the instance, edit -Xmx in /etc/default/batfish (1024 to 12288 MB) and run sudo systemctl restart batfish. Common commands:

sudo systemctl restart batfish
# restart the analysis service (nginx follows)
sudo journalctl -u batfish -f
# follow the Batfish log
sudo batfish-demo
# re-run the end-to-end check
14

Check what you are running

cat /usr/share/batfish/VERSION sed -n '1,4p;9p' /usr/share/batfish/BUILD-INFO sha256sum /opt/batfish/allinone-bundle.jar /opt/batfish/pybatfish-venv/bin/python3 -I -c 'import pybatfish; print("pybatfish", pybatfish.__version__)'
2026.08.27.3685 product: Batfish 2026.08.27.3685 (allinone uber-jar), built by sac (orchestrator ruling d-5235 C1) commit: 329c14bf712f81b1522147abb00419c8e34e8f4a (v2026.08.27 release commit; no source change) raises: jackson-bom 2.22.1 -> 2.23.0 (upstream e8e8dedb3f1c5a1edc9b0076663c0ba5a5cc5666) raises: guava-bom 33.6.0-jre -> 33.7.2-jre (upstream 3ed9fb5e7b26029410f33c6c0d80c794684a46c1) jar: sha256 a78c208cbb42aef31e8543f2177d05275aa4ef0de9ba4419fdde637f7bb1387b a78c208cbb42aef31e8543f2177d05275aa4ef0de9ba4419fdde637f7bb1387b /opt/batfish/allinone-bundle.jar pybatfish 2026.08.27.3685

The full build record is in /usr/share/batfish/BUILD-INFO. It includes the third raise (lz4-java 1.11.2 to 1.14.0), the build tool and the lock file digest. The exact dependency change is in /usr/share/batfish/raises.diff.

Each raised version is the one the Batfish project adopted on its own main branch after the release. The record names the upstream commits.

Security recommendations

  • Keep the security group tight. Allow 9996 only from the workstations and CI runners that run pybatfish, and SSH only from your management address.
  • Treat the API key as a password. Anyone with it can upload networks and read every analysis on the instance. Keep it in a 0600 file or your CI secret store. To replace it, launch a new instance from the listing, because every instance mints its own key at first boot.
  • Treat uploaded configurations as sensitive. Snapshots contain your devices' full configurations, often with password hashes and SNMP communities. Delete networks you no longer need, and keep the root volume's EBS snapshots private.
  • Keep the OS patched. Unattended security upgrades are on for the Ubuntu packages. Batfish itself is the jar on the image, so updating it means launching a newer SecureAnyCloud version from the listing.

Support and licensing

Batfish and pybatfish are developed by the Batfish project and distributed under the Apache License 2.0. The licence texts are in /usr/share/doc/batfish/. Every library bundled in the jar and the pybatfish environment is listed with its licence in /usr/share/batfish/THIRD-PARTY-NOTICES.

SecureAnyCloud provides the source build, the TLS front, the per-instance key, login and certificate, the secure defaults and 24/7 support.

SecureAnyCloud is not affiliated with or endorsed by the Batfish project. Batfish is a mark of its owner and is used here only to identify the software.

For help with deployment or configuration, email sales@secureanycloud.com or visit SecureAnyCloud support.

Deploy on AWS

Launch Batfish 2026.08.27.3685 on Ubuntu 24.04 on AWS with 24/7 support from SecureAnyCloud.

View on Marketplace

Need help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on AWS