Security model
A tool that reads your machines is itself a target. What follows is the threat model it was built against, stated plainly enough to argue with.
The worst case, and why it is reading#
Assume this server is fully compromised. An attacker then controls what jobs are pushed to every enrolled agent. So the only defence that matters is the one in the agent binary itself:
- No tool runs a command it was sent. The agent does call the operating system’s own read-only utilities (
ps,lsof,codesign,screencapture, and on Windows PowerShell scripts compiled into the binary), but which program runs, and with which flags, is written into the agent. Nothing the server sends becomes a program or a command line. There is no tool that takes a command: not with an allowlist, not with escaping, not “just for diagnostics”. The moment one exists this becomes a command-and-control framework aimed at the machines it is meant to defend. - No tool writes, deletes, moves or changes anything. The one file a tool creates is a screen capture’s own image, in a private temporary folder, removed as soon as it has been read.
- The tool set is compiled in. The server can name a tool. It cannot supply a command, a script, a path or an argument the agent has not declared.
- The agent validates every argument itself, in addition to the server validating it. The agent does not trust the server, because the server is the thing that might be lying.
- File content is allowlisted. Content is returned only for a small set of forensic files. Everything else can be listed and stat’d, never read. A deny list covering private keys,
.envfiles,.netrc, credential stores and certificate bundles beats the allowlist always, matched against the canonicalised path so a symlink or a traversal cannot walk around it. - Screen capture is off unless someone at the machine turns it on (
guardyn-agent screenshots on, or--allow-screenshotsat enrolment). The server cannot enable it, so a compromised server cannot photograph an endpoint that never opted in. The image goes to the console for a person to look at; the model never receives it. Every capture and every refusal is written to the machine’s own audit log first. Capturing on a timer is a second opt-in, made the same way. How to turn it on or off.
An investigation console that can read any file is a data exfiltration tool with a nice interface. That is the line, and it is enforced in the binary rather than in policy.
Network posture#
The agent dials out. It never listens on a port, so there is no service on the endpoint to attack and no inbound firewall rule to open. It refuses plain HTTP unless the target is loopback — a snapshot describes exactly how to attack the machine that produced it, so it must not travel in clear text. It refuses to follow redirects while carrying a credential.
Credentials#
| Credential | Scope | Storage |
|---|---|---|
| Session cookie | One browser | Only its SHA-256 is stored; httpOnly, SameSite=Lax, Secure (HTTPS only) |
| Enrolment token | One workspace, optionally use-capped and expiring | Hash only |
| Machine token | One endpoint | Hash only |
| API key | One workspace, scoped | Hash only |
| Provider API key | The platform | AES-256-GCM, with a key derived from a server-side secret; never returned to any client |
Anything handed to a client is 32 random bytes and only its hash is kept, so a database dump yields nothing replayable. Passwords are scrypt (N=32768, r=8, p=1) with the cost parameters recorded per row, so an upgrade rehashes on next sign-in rather than locking anyone out. Every secret comparison is constant-time.
Tenant isolation#
Every tenant-scoped table carries the workspace id directly, even where a join could reach it, so the isolation check is always one predicate away and cannot be lost in a join chain. A connection belongs to exactly one workspace and the tenancy check on tool dispatch happens at the last possible moment, inside the dispatcher, so no caller can skip it.
Accounts#
- Optional TOTP two-factor with single-use recovery codes.
- Failed sign-ins are throttled per account and per source address, in a short rolling window.
- Sign-in answers identically for an unknown address and a wrong password, and spends the same CPU either way, so it cannot be used to enumerate accounts.
- A password change or reset revokes every other session.
- Password reset always reports the same result whether or not the address has an account.
Audit#
The audit log is append-only. When a platform administrator acts as a customer, both identities are recorded on the session and on every entry written during it, so nothing done during impersonation can be mistaken for the customer’s own action. Every tool call is also recorded on the endpoint itself, where the machine’s owner can read it without asking us.
What your evidence is used for#
Evidence from your machines is sent to the model provider you selected, in order to answer the question you asked, and nowhere else. It is not used to train anything. Raw snapshots are not kept: a digest is stored, because that is what an analysis reads.
A screen capture, on a machine where someone turned it on, is the exception: it is not sent to any model. It is kept for people in your workspace to look at, one frame per machine, and each new capture replaces the last.
Reporting a vulnerability#
security@guardyn.dev. Please include enough detail to reproduce. We will confirm receipt and keep you informed; we will not take legal action against good-faith research that does not access other customers’ data.