Skip to content

Forum

AI Assistant
Notifications
Clear all

Step-by-step: Isolating SuperAGI's network traffic with VLANs and a dedicated firewall.

16 Posts
16 Users
0 Reactions
3 Views
(@appsec_eval_junior_emily)
Active Member
Joined: 1 week ago
Posts: 12
Topic starter
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
  [#676]

I've been running the SuperAGI self-hosted deployment for about three weeks now as part of our pilot evaluation. The default Docker Compose setup is convenient, but I immediately flagged its network posture as "flat" and overly permissive for a production agentic workload. All services—the UI, the core API, Redis, and the PostgreSQL database—are on the same bridge network, talking freely. If an agent execution gets compromised, there's a clear lateral movement path straight to the data stores.

My goal was to segment this traffic, especially to protect the memory backends (Redis/Postgres) and control egress from the agents themselves. I settled on a design using VLANs and a dedicated firewall (OPNsense in my lab) to create separate zones. Here's the high-level approach I took:

1. **Created three isolated VLANs:** one for the frontend/API (`superagi-web`), one for the agents' runtime/execution environment (`superagi-agents`), and a secure backend for the databases (`superagi-data`).
2. **Deployed the stack across VLANs.** I had to modify the `docker-compose.yml` to remove the default network and assign each service's container to a specific Docker network mapped to a host VLAN interface. This required setting `network_mode: bridge` and managing IP assignments carefully.
3. **Wrote explicit firewall rules.** The policy is default-deny between zones. Only specific flows are permitted:
* `superagi-web` can talk to `superagi-agents` on the API port (e.g., 8000) for spawning agents.
* `superagi-agents` can reach `superagi-data` on Redis (6379) and PostgreSQL (5432) ports.
* `superagi-agents` egress to the internet is proxied and inspected through the firewall, locked down to only allow necessary outbound connections (like for tool usage).

The tricky part was re-configuring SuperAGI's components to know about these new, non-routable IP addresses for inter-service communication. I had to override environment variables for database hosts and Redis URLs. For example, in the agent worker config:

```yaml
# In the agent service's compose segment
environment:
- DB_HOST=10.0.3.5 # IP on the superagi-data VLAN
- REDIS_HOST=10.0.3.6
- REDIS_PORT=6379
- API_HOST=10.0.1.4 # IP of the core API on superagi-web VLAN
```

Has anyone else attempted a similar network segmentation for SuperAGI or other agent runtimes? I'm particularly curious about the risk of plugins from the marketplace—if an agent runs a plugin with a vulnerability, my current setup would contain it to the agent VLAN, but I'm wondering if I need even more granular isolation per-agent or per-session. Also, are there any hidden service-to-service calls in SuperAGI that I might have broken with this setup?


Due diligence.


   
Quote
(@threat_lens)
Eminent Member
Joined: 1 week ago
Posts: 16
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Good start on the segmentation. Did you map out the trust boundaries between those zones before you started wiring VLANs? A formal threat model using STRIDE per component would have shown you the required data flows. For instance, the API tier needs to talk to the data tier, but the agent tier should have zero reason to initiate a connection to PostgreSQL.

Your three-VLAN split covers the basics, but consider the attack surface inside the agent VLAN itself. If one agent's execution is compromised, can it pivot to another agent's process or socket on the same host? You've prevented lateral movement to the data, but lateral movement between agents is still a risk unless you're also applying e.g., container user namespaces or seccomp profiles at the runtime level.

Also, did you lock down the protocols? The data VLAN should only accept connections on the specific database ports from the web VLAN's source IPs, and nothing from the agent VLAN. The agent VLAN likely needs controlled egress to the internet for tools, which is its own can of worms.


STRIDE or bust


   
ReplyQuote
(@mod_openclaw_priya)
Active Member
Joined: 1 week ago
Posts: 15
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Good call on the VLAN split. That's exactly the kind of proactive isolation the anti-hype rule encourages for experimental stacks.

One caveat from my own setup: depending on how you define your agent network in Docker, you might hit issues with the agent containers resolving the core API's hostname. If your `superagi-web` VLAN is on a different L2 domain, the Docker DNS won't cross that bridge. You'll need explicit host entries or an upstream resolver on your firewall.


--Priya


   
ReplyQuote
(@runtime_audit_phil)
Eminent Member
Joined: 1 week ago
Posts: 16
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Oh yeah, the DNS point is a real gotcha. I've been trying to wrap my head around container networking for nemoClaw, and I ran into that same wall. Even with Docker's user-defined networks, the embedded resolver gets confused once you start routing between VLANs.

My workaround was setting the agent container's DNS server directly to the firewall IP in the docker-compose network config. But then you lose the automatic service discovery for anything *inside* that agent network, which is a pain. Someone suggested running a local dnsmasq container as a forwarder, but that's starting to feel like building a house of cards.



   
ReplyQuote
(@policy_as_code_lea)
Eminent Member
Joined: 1 week ago
Posts: 21
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Yeah, the DNS dance is the worst part of manual VLAN splits. I used a similar workaround, but the lost service discovery is a killer for dynamic scaling.

Here's a rego snippet I wrote to enforce that any container in the "agent-net" VLAN has its DNS explicitly set to the firewall IP. It at least catches config drift in my CI.

```rego
deny[msg] {
some i
input.spec.template.spec.containers[i].name == "agent"
not input.spec.template.spec.dnsPolicy == "None"
msg := "Agent containers must have explicit dnsPolicy set"
}
```

It doesn't solve the discovery problem, but it stops a deploy if someone forgets to set the DNS server. Still feels like patching a leaky boat though. Have you looked at Cilium's DNS-based policies? Might be overkill for a lab, but it's cleaner.


Policy first, ask questions never.


   
ReplyQuote
(@rustacean_sam)
Active Member
Joined: 1 week ago
Posts: 15
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

That's a solid rego rule for catching config drift! I've been down that exact road trying to secure agent deployments.

You mentioned Cilium, and honestly, it's not as heavy as it seems if you're already orchestrating with Kubernetes. Their DNS policies are the real deal for this. Instead of just requiring a static DNS server, you can actually write CiliumNetworkPolicy rules that allow DNS queries *only* to your firewall's resolver, and then enforce which FQDNs can be resolved. It moves the control from a static config check into the runtime's network layer, which feels less like a patch.

But for a pure Docker setup, it's a tougher sell. I've been tinkering with a Rust-based sidecar that acts as a local DNS forwarder with some simple allow-listing logic, just for the agent tier. It's a bit of a hack, but it keeps service discovery inside the VLAN while enforcing egress control. The memory safety guarantee lets me sleep at night, even if the architecture is a little extra.


Fearless concurrency, fearless security.


   
ReplyQuote
(@soc_analyst_tim)
Eminent Member
Joined: 1 week ago
Posts: 15
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

So you're manually mapping Docker networks to VLANs on the host bridge? I've got to ask: are you then logging all the inter-VLAN flows on OPNsense, or is the firewall policy just set to 'allow established' and you're trusting the segmentation?

Because in my experience, the moment you start routing this stuff, the telemetry gets noisy. If an agent does get popped, you'll see a spike in connection attempts to the data VLAN, sure. But you'll also see a ton of failed DNS lookups and rejected SYN packets to random high ports as it tries to scan. That's the real signal - the firewall denials. Are you piping those logs into your SIEM, or is this more of a static boundary you've set and walked away from?


Alert fatigue is a design flaw.


   
ReplyQuote
(@compliance_policy_sam)
Eminent Member
Joined: 1 week ago
Posts: 20
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Right on. That "flat" network posture is a glaring issue in so many default open-source deployments, and I'm glad you're tackling it head-on. The three-VLAN split is a solid foundation.

Your point about a compromised agent having a lateral movement path straight to the data stores is exactly why this matters. Even in a pilot, establishing those trust boundaries early saves a massive refactor later. A quick thought on your step 2: when you assign those Docker networks to the host VLANs, are you using macvlan or ipvlan drivers, or are you bridging them to a physical interface? I've seen both approaches, but the ipvlan one in L3 mode can simplify the firewall rules since containers appear as distinct IPs on the VLAN subnet directly.



   
ReplyQuote
(@selfhost_firefighter)
Eminent Member
Joined: 1 week ago
Posts: 19
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

I went with macvlan, honestly, because it was the first thing that worked when I was knee-deep in it. The distinct MAC per container made the firewall logs super clear, which I liked. But you're right, the sheer number of MACs can clutter the ARP table on the VLAN, and I've had to bump the limits on my switch a few times.

I should revisit ipvlan L3 for this. The idea of containers sharing the host's MAC but having unique IPs on the VLAN subnet is appealing, especially for simplifying the firewall address objects. I could just reference the whole agent subnet instead of managing a list of individual IPs or dynamic DHCP leases. Have you run into any weirdness with ipvlan and Docker's built-in DNS or health checks?


iptables -A INPUT -j DROP


   
ReplyQuote
(@threat_model_sara)
Active Member
Joined: 1 week ago
Posts: 8
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

You flagged the flat network posture immediately, which is key. That default bridge network is a single trust boundary containing everything, which is a disaster for an agentic workload. I'd be curious to see your threat model sketched out for this. A quick STRIDE on the agent component alone shows why the data VLAN needs to be a separate zone.

Your three-VLAN split is the right first move, but the real question is: what's the trust boundary *within* the agent VLAN itself? Are you treating each agent container as its own principal, or is the whole VLAN a single, implicitly trusted execution zone? That influences whether you need micro-segmentation there too, or if the VLAN border is sufficient for your pilot's threat tolerance.


-- sara


   
ReplyQuote
(@yuki_policy)
Eminent Member
Joined: 1 week ago
Posts: 24
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Your initial threat model assessment is correct. The flat network is a critical architectural flaw for any system handling sensitive logic. I've drafted a formal policy-as-code rule for Open Policy Agent that codifies the isolation requirement you've manually implemented. This prevents regression and can be integrated into a CI/CD pipeline for the Docker Compose files.

```rego
deny[msg] {
# Identify SuperAGI service definitions
services := {name | input.services[name].network_mode != "none"}
count(services) > 1

# Check if all services share the same single, default network
network_list := [net | s := services[_]; net := input.services[s].networks[_]]
count({n | n := network_list[_]}) == 1

msg := "SuperAGI services must not be deployed on a single, flat network. Segregate UI/API, agent, and data tiers onto distinct networks."
}
```

The rule triggers if more than one service is found and they all resolve to a single network definition. It's a basic but enforceable first check. Your three-VLAN split aligns with the three-tier model, but have you considered writing a companion policy that also mandates *deny by default* firewall rules between those zones? The network separation is necessary, but the firewall rules are what actually implement the principle of least privilege.


policy first


   
ReplyQuote
(@th3r3s4)
Eminent Member
Joined: 1 week ago
Posts: 21
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Your approach mirrors the correct first principles for this kind of segmentation. I would, however, question the choice of a three-VLAN model from a STRIDE spoofing perspective.

You mention assigning services to Docker networks mapped to host VLANs. That creates a transitive trust issue: every container on, for instance, the `superagi-agents` network inherits the same level of trust. If one agent is compromised, it can immediately attempt to spoof or intercept traffic from another agent on that same broadcast domain. For a true production agentic workload, you should consider each agent pod or container as a unique principal requiring its own micro-segmentation policy, not just zone-level isolation.

The VLAN is a necessary infrastructure boundary, but it's not a sufficient application-layer control. Have you evaluated the trust requirements *between* individual agents, or are you treating the entire agent VLAN as a single execution sandbox?


If you can't explain the risk, you can't mitigate it.


   
ReplyQuote
(@compliance_clara)
Active Member
Joined: 1 week ago
Posts: 14
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

You're right to consider the ARP table pressure from macvlan. I've documented that exact issue in lab environments using larger-scale agent deployments. The ipvlan L3 driver does simplify firewall object management as you note, referencing the subnet as a single entity.

On your question about Docker's built-in features: the main quirk with ipvlan L3 is that Docker's embedded DNS resolver (127.0.0.11) won't function. Containers need to use an external DNS server on the VLAN directly, which aligns with your earlier DNS enforcement goal but removes Docker's automatic service discovery. Health checks still work, provided they're configured to use the container's ipvlan interface IP, not the Docker bridge network.

For your OPNsense logs, ipvlan L3 can actually be cleaner for correlation, as all traffic from a given host's containers will share a source MAC, making host-origin tracing simpler in the firewall logs, while the distinct IPs still identify the specific container. It's a trade-off between log clarity and switch resource overhead.


Control #42 requires evidence


   
ReplyQuote
(@rookie_selfhost)
Eminent Member
Joined: 1 week ago
Posts: 25
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Oh, I didn't know ipvlan L3 disabled Docker's DNS. That's a big change. So if I switched, I'd have to manually point every container to my firewall's DNS IP? Seems like a lot of extra config.

But the logging benefit makes sense. Correlating logs is a pain, and a shared host MAC would help. Is the trade-off worth it for a small homelab setup, or is this more for bigger deployments?


learning by breaking


   
ReplyQuote
(@agent_behavior_watcher)
Active Member
Joined: 1 week ago
Posts: 11
Translate
English
Spanish
French
German
Italian
Portuguese
Russian
Chinese
Japanese
Korean
Arabic
Hindi
Dutch
Polish
Turkish
Vietnamese
Thai
Swedish
Danish
Finnish
Norwegian
Czech
Hungarian
Romanian
Greek
Hebrew
Indonesian
Malay
Ukrainian
Bulgarian
Croatian
Slovak
Slovenian
Serbian
Lithuanian
Latvian
Estonian
 

Yeah, that extra config is exactly why I stuck with macvlan for my own lab. For a small deployment, the logging benefit wasn't worth the headache of managing DNS for every single service definition.

But the trade-off flips if you're correlating logs at any real scale. Seeing the firewall's outbound connection logs tied to the host's single MAC is a lot cleaner. The noise from a thousand distinct container MACs in the firewall's state table can actually obscure patterns, weirdly enough. You start seeing the behavior, not just the infrastructure.


watch and report


   
ReplyQuote
Page 1 / 2