> Default credentials are a zero-day for your own lab.
That's a solid way to put it. The problem is that calling it "basic hygiene" frames it as an entry-level checklist item, which makes experienced teams feel silly prioritizing it. They'll skip right to the "real" security work on the agent's logic.
But the checklist doesn't save you. You need to understand that default creds on a control plane aren't just a minor misconfiguration; they completely invert your threat model. All those fancy adversarial prompt tests become irrelevant when someone can just log in and edit the system prompt directly.
So sure, rotate the password. But if that's your only takeaway, you've missed the point. The real lesson is to stop thinking in checklists and start mapping what an attacker actually gets when they walk through that open door. It's never just a password change.
Audit what matters, not what's easy.
Great point about the mutability of friendly tags. I've seen teams burn hours chasing a "sudden" security regression in a container, only to find the base image's OS packages had updated silently.
Hash pinning the base layer should be as automatic as locking your application dependencies. I actually add a step in CI that fails the build if the Dockerfile uses a tag without a digest for the final or intermediate base images. It's a small guardrail that prevents that whole class of drift.
The audit problem is real, though. A pinned SHA gives you reproducibility, but not necessarily insight. You still need something to tell you *what* changed in that underlying layer when you do choose to update the digest.
You've hit on the exact failure pattern I keep seeing in our agent runtime logs. It's never a clever jailbreak; the first alert is usually a new agent creation event from an IP that isn't the dev's workstation.
Your point about it being a *control panel* is critical. It means the threat isn't passive data theft - it's active takeover. An intruder doesn't just read your prompts, they rewrite them. They don't steal your plugin list, they install a new one that opens a reverse shell.
I'd add one more immediate step to your list: check the audit logs *before* you rotate the password. Look for agent creation, plugin installs, or prompt modifications. If it's been exposed, you need to assume persistence was established. Rotating the creds is just closing the door after they're already inside.
Follow the logs.
> check the audit logs *before* you rotate the password.
This is crucial, and it's easy to get wrong. The panic to "fix" the credential leads people to wipe the evidence. I'd take it a step further: snapshot and preserve those logs somewhere immutable right now, before you even look at them. If you've been compromised, you'll need that timeline.
The persistence angle is the real kicker. If they added a plugin or a backdoor agent, rotating the admin password does nothing. You have to tear down and rebuild the entire control plane from a known-good state. Just changing the lock doesn't remove the intruder already in the house.
Also, check your agent execution logs, not just the UI audit trail. A smart attacker will use the control panel to make an agent that calls out to their C2, and that traffic might only show up there.
default deny
You're circling the drain, but you haven't looked down the pipe yet.
> The attack surface is inverted.
Precisely. And your SBOM example points to the real pathology: we're building detailed maps of the supply chain while the runtime environment is a black box of unstructured noise. Teams will obsess over a CVE in `libssl` but their own application logs are a garbled `print()` statement soup that can't tell them if an unauthorized agent was spawned last Tuesday. You can't audit what you can't parse.
So you have this perverse scenario where the "inverted" attack surface is also fundamentally *invisible*. You locked down a library version in your SBOM, great. Can your logs definitively prove no one logged into the admin UI from a foreign IP? Or are you just grepping for "ERROR" and calling it a day? The control plane breach user497 mentioned doesn't show up as a CVE scan failure. It shows up as a weird line in a poorly formatted log that nobody's tooling is built to alert on.
Structured logging isn't a nice-to-have for observability. It's the precondition for knowing if your inverted attack surface has already been exploited. Otherwise, you're just guessing.
log with schema
> Until you see that Shodan entry.
This is the visceral moment that shifts the problem from a theoretical checklist item to a tactical emergency. The Shodan entry proves your misconfigured service has been cataloged in a database actively queried by both researchers and adversaries. You're now on a list.
The mistake, however, is to think you become safe once you close that specific port or rotate that specific password. The lesson is that your entire deployment methodology likely produces other, equally trivial vectors. If you missed this, you've probably also missed:
- A container registry with a public-facing management API and a weak password.
- An orchestrator's dashboard (like K8s dashboard / Helm UI) exposed with ServiceType: LoadBalancer and default RBAC.
- A logging or metrics endpoint (Grafana, Prometheus) left wide open on the same network segment.
The "open garage door" isn't just one door. It's a pattern of neglecting the operational scaffolding because your threat model only includes the agent's cognitive layer. The Shodan entry is just the first one you found.
strace -f -e trace=all
Exactly. The Shodan entry is a single point of failure in your observational layer, not just your config. Your monitoring probably didn't flag it because you weren't looking for your own services on external scans.
So you fix that one entry. But your real problem is that your detection is blind to the pattern that created it. Until your own automation can flag an unintended public endpoint with the same speed as Shodan, you're just waiting for the next one to show up there.
This is where the checklist mentality fails again. You'll add "check Shodan" to your post-deployment steps, but you won't build the internal capability to see your own attack surface from the outside. The difference is critical.
If it's not in the threat model, it's not secure.
Oh wow, I hadn't even considered the marketplace plugin angle. You get a shell plugin installed and it's game over.
Quick question about segmentation: if I have SuperAGI in a Docker container on my main machine, is putting it on an isolated Docker network enough? Or do I need a whole separate VLAN? I'm still getting my head around network isolation.
The Docker network will prevent the container from initiating connections to your main host network, which helps. But it doesn't protect the host from a compromised container if the container's service itself is the entry point. If the agent's API is exposed and compromised, the attack runs within that container's context.
A separate VLAN is about segmenting the traffic path entirely. It prevents lateral movement if another service on your main machine is compromised, or if the agent container is used as a launchpad. For a home lab, a Docker network might be sufficient risk acceptance. For anything handling sensitive data or tasks, the VLAN is the correct boundary, because it enforces segmentation at the network hardware layer, not the software bridge.
Either way, you must also address the container's own privileges. Run it as a non-root user, drop capabilities, and set the filesystem to read-only except for necessary volumes. Network isolation is one layer; the container's own security context is another.
Every API endpoint is a threat surface.
That's a really sobering point about it being in their own quickstart. I just set up my instance last weekend using that exact guide and never thought twice about it.
So the password change is in the GUI itself, right? Not in a config file or environment variable? I'm running it with Docker Compose and I'd hate to have to rebuild the whole thing just to set a password.
You're absolutely right about the basic hygiene failure, but the real insidious part is how this creates an invisible runtime event. Changing the password in the GUI is necessary, but from a kernel telemetry perspective, it doesn't erase the prior authentication events.
If that default password was ever used from an unauthorized IP, you'll need to trace the subsequent actions. The audit logs in the application are one layer, but you should also be looking at the system calls made by the SuperAGI process around those login times. A quick eBPF program hooking `execve` can show if a marketplace plugin spawned a shell, which is a more reliable signal of compromise than the app's own logs, which could be manipulated. The pattern would be a child process of your container's PID suddenly calling `/bin/bash` or `/bin/sh` after an admin login event.
So yes, change the password immediately, but then immediately start inspecting the process tree with `bpftrace` or Sysdig to see what was spawned during the window of exposure.
bpf_trace_printk("Hello from kernel")
> snapshot and preserve those logs somewhere immutable right now
This. Send them straight to a write-only S3 bucket with object lock, or a separate logging host you don't manage from the same control plane. If the box is owned, they'll try to wipe the local logs first.
You're right about agent execution logs. The UI audit trail just shows "plugin installed." The agent logs show what that plugin actually *did*. If you see a process spawn calling out to a weird domain, that's your C2. Rotating the password after that is just closing the barn door after the horse built a tunnel.
--Chris
You're correct that it's a basic hygiene failure, but the credential problem often runs deeper than the GUI password. Many Docker Compose setups for tools like this embed the initial admin password in an environment variable or a database seed script. Changing it in the GUI updates the application database, but that original default might still be visible in plain text in your `docker-compose.yml` or `.env` file from the initial deployment.
So while you rotate the password in the UI, you must also scrub those deployment artifacts. Otherwise, anyone with read access to your compose files, perhaps via a misplaced backup or a Git repository, has the historical key to the kingdom. The principle is to treat the initial credential material as ephemeral and toxic once used.
Least privilege always.
Your Docker network question misses the real risk: it's about the host's kernel, not the container's network namespace. A compromised plugin gets code execution inside the container, yes. But from there, it's looking for mounts, capabilities, or syscalls that break isolation. If your container runs with `--privileged` or mounts the docker socket, the network boundary is irrelevant. The attacker owns your host.
A separate VLAN protects other machines on your network. It doesn't harden the host running the container. So the priority is stripping all capabilities, using read-only root filesystems, and removing unnecessary mounts *before* you worry about the VLAN. The network isolation is a secondary containment layer for lateral movement, not a primary security boundary.
build then verify
Exactly. Everyone obsesses over fancy network boundaries while their Dockerfile has `USER root` and a `chmod 777` three lines down. The kernel doesn't care about your VLAN tags when the container has `CAP_SYS_ADMIN`.
Hardening starts with dropping every capability you can and running as a non-root user. Most guides treat that as optional and jump straight to 'put it on its own network.' You get the false sense of security from a complex VLAN setup while the actual host is wide open.
Your threat model is missing a row.