An agent installed on someone else’s production server is a privileged, permanent guest. It runs continuously, usually with elevated access, on a machine whose workload you do not control and whose owner will blame you for the next unexplained slowdown.
That framing decided most of what SecAI collects, and rather more of what it deliberately does not.
These are design notes rather than a product page. Everything here concerns publicly documented behavior.
Why an agent at all
The questions that actually matter after a compromise cannot be answered from outside the machine.
A network scan can tell you which ports respond. It cannot tell you that a process is running from a
binary that has been deleted from disk, that a systemd drop-in was added to an otherwise
legitimate service, that a new key appeared in an authorized_keys file, or which packages are
installed at which versions.
MITRE catalogues persistence as a distinct tactic precisely because it is a separate objective from initial access, and almost every technique in it is invisible from the network. If you want to know whether someone still has access, you have to be on the host.
That is the entire justification for an agent, and it is worth being clear about, because an agent is a significant thing to ask someone to install.
Collect narrowly, on purpose
The instinct when building a monitoring agent is to gather everything and decide later. It is the wrong instinct, for three reasons.
Volume is a cost you impose on someone else. Every byte collected is disk, CPU and bandwidth on a server the customer is paying for. An agent that is expensive to run gets uninstalled, and an uninstalled agent detects nothing.
Broad collection is a privacy liability. If the agent reads application data, it has to be treated as a system holding customer data, with everything that implies. Narrow collection avoids that category entirely rather than managing it.
Undirected data does not become insight. Collecting more does not produce better findings, it produces a larger haystack. The useful question is which specific state changes indicate a problem.
So the design principle is: collect the state whose change is meaningful, not the content of the system.
Worth collecting, because a change is significant and the volume is bounded:
- Installed package inventory and versions, for matching against public CVE data
- Listening sockets and the processes that own them
- Authentication events and privilege escalation
- Scheduled tasks and enabled service units
- Accounts, group membership and SSH authorized keys
- Firewall rules
- Resource trends: disk, memory, load
Each of these is small, changes infrequently on a stable server, and a change is genuinely worth a look. That combination is what makes something a good signal.
Deliberately not collected:
- Application database contents
- Files from user or upload directories
- Environment variables, which routinely contain credentials
- Full request bodies from web traffic
- Private keys, in any form
The line is straightforward: the agent monitors the state of the machine, not the data on it. That boundary is easier to hold if it is decided at the start rather than defended later.
The command channel is the real attack surface
This is the part we would defend most strongly, and the part most easily got wrong.
Any system that sends instructions to agents across many customer servers is, from an attacker’s perspective, an extremely attractive target. Compromise the backend and you have a command channel into every monitored machine. The security product becomes the intrusion.
Transport security is not sufficient here. TLS tells the agent it is talking to a server presenting a valid certificate for the expected hostname. It does not tell the agent that the instruction it just received was legitimately authorized.
SecAI signs its policies with Ed25519 and the agent verifies the signature on every cycle. The verification key is embedded in the agent binary. The consequence is that possession of the backend is not sufficient to direct the fleet: an attacker also needs the signing key, which lives somewhere the backend does not.
Two implementation notes that generalize:
Verify on every cycle, not at enrolment. Checking a signature once when the agent registers, then trusting the channel afterwards, reduces to trusting the transport.
Build it before the features that use it. Retrofitting cryptographic verification onto an existing command path means auditing every route into that path. Building it first is cheaper and produces a stronger result.
The same reasoning applies to updates. Any mechanism that puts new code onto a customer’s server is a supply chain, and it is exactly as trustworthy as its weakest verification step.
Automated response, bounded by reversibility
The most interesting design constraint was not detection accuracy. It was deciding what the system may do without a human.
The organizations this exists for do not have a security analyst. If the answer to every finding is “escalate to a person,” the product is a notification service and the alerts go unread at three in the morning, which was the original problem.
But anything automated will eventually fire on a false positive. That is not a possibility to guard against, it is a certainty to design around.
The line we settled on is reversibility.
Automatic, because a mistake costs one action to undo:
- Blocking a source address at the firewall layer, through fail2ban or CrowdSec
- Collecting evidence and constructing a timeline
- Raising and prioritizing a finding
Requires a human, because the system cannot know what depends on the thing it would change:
- Restarting or stopping a service
- Creating, modifying or removing accounts
- Rotating credentials that other systems rely on
- Installing or removing packages
The reasoning for the second list is not that these are technically harder. It is that undoing them requires knowledge the agent does not have. It cannot know that the service it just restarted was mid-transaction, or that the credential it rotated is also used by a cron job on a different machine.
The safety net is part of the capability
The first serious failure mode of any auto-blocking system is locking the administrator out of their own server during an incident. Their address looks anomalous precisely because they are responding to something unusual.
Trusted infrastructure is exempted from automatic blocking. This is not a nice-to-have that was added later. It is what makes automatic enforcement safe enough to enable at all, and the guard rail and the capability are the same design decision.
Detect harm and revert it
If the system is permitted to change a production server, it has to be able to recognize that the change broke something and undo it without waiting for someone to notice.
A remediation that takes a service down has made things worse than the problem it addressed. Building that detection is more work than building the remediation, and skipping it is how automated fixes become a liability.
Alert volume is a design problem, not a presentation problem
A system that reports everything gets ignored, which is functionally identical to reporting nothing while feeling more diligent.
For a team without an analyst, an unprioritized list of findings is equivalent to no findings. Ranking is not a display concern, it is the product.
That is what the multi-role AI review pipeline is for: not to detect more, but to take raw evidence and produce a judgement about what matters, with the reasoning attached. The output that is actually useful is “this specific thing, for this reason, here is what to do,” at a volume a busy person can read.
Evidence has to survive the incident
Logs held only on the affected host are logs an intruder with root can edit.
This is obvious when stated and consistently absent in practice. It is also the single reason many compromise investigations cannot establish an entry point: everything available was on the machine the attacker controlled.
Operating a monitoring product makes this concrete rather than theoretical. It is why remote log collection appears in nearly every hardening engagement we run, ahead of more interesting controls.
Compliance output is a data integrity problem
Reporting aligned to a named framework, such as UAE NESA or PDPL, is useful exactly to the extent that the underlying evidence is real and traceable.
The engineering work is not document formatting. It is ensuring every statement in the report can be traced back to a specific observation with a timestamp and a source. A report that cannot be traced is a formatted assertion.
What we would tell someone building one
- Decide what you will not collect, first. It is a much harder boundary to establish once you have a pipeline that accepts everything.
- Sign the command channel before you build commands. Cheaper by a wide margin.
- Pick the automation boundary on reversibility, not on technical difficulty or on confidence in your detection.
- Ship the safety net with the capability, not after the first lockout.
- Treat alert volume as the core problem. For the customer without an analyst, prioritization is what they are buying.
- Get the thing validated by someone who is not you. We submitted SecAI to StackAttest, which produced a public Passport with the evidence behind each verified capability. Being judged by a process you do not control is uncomfortable and useful.
What this has to do with client work
Almost all of it transfers.
The reversibility test is now how we scope automation and AI agents for clients: not whether the system can perform an action, but what happens the time it performs it wrongly. Remote logging goes into hardening engagements because we have seen what its absence costs. Update channels get treated as supply chains.
Building a product you have to operate is an expensive way to learn these things, and it is a good deal more convincing than reading them.