How it works

Install it, connect it, ask it. Then check its work.

A read-only agent on each machine opens one stream out. Over it, the analyst calls the checks it needs and answers with what came back attached, including what it could not see. This is the whole loop, and the things it will never do.

Three steps

Three steps, and the third one is the product.

The first two take about a minute. Then you just ask.

  1. Install the agent

    One static binary with no dependencies, for macOS, Linux or Windows. The installer checks its published SHA-256. Enrolment needs a token you paste yourself, so a leaked install command cannot add machines to your fleet.

    $ curl -fsSL https://guardyn.dev/install.sh | sh
    $ guardyn-agent enroll \
        --server https://guardyn.dev \
        --token gdn_enrol_…
    enrolled build-runner-03 (linux/amd64)
  2. Connect it

    The agent dials out and holds one long-lived stream. It never listens on a port, so there is no inbound firewall rule. When the stream closes, the console says offline instead of guessing.

    $ guardyn-agent connect
    connected as build-runner-03
    29 tools offered, elevated=true
    waiting for jobs
  3. Ask

    Pick a machine, pick a model, ask in plain language. It calls the checks it needs in parallel, reads what comes back, and answers with the evidence attached.

    > What is listening on build-runner-03?
      ▸ list_sockets  state=listening  0.4s
    Four ports. Three expected.
    One is not: 8443, held by a
    process running from /tmp.

An investigation

The evidence stays attached to the answer.

One question, five checks sent at once, one follow-up. Every result is kept with the turn, including the check that could not run. Save what matters as a finding, and decide how serious it is yourself.

KSKestrel Studio▾
InvestigateFleetFindingsUsageBillingSettings
Recent
Unsigned process with an outbound connectionWhat changed overnightLaptop network checkWho signed in to build-runner-03
D
Dana
finance-mbp-14▾3 of 4 connected▾unprivilegedUnsigned process with an outbound connection4,809 cr
Is anything odd running on finance-mbp-14?
Claude Sonnet 5· 3.42 creditsshow reasoning
What this answer is based on
6 checks, 1 could not run6 tools · finance-mbp-14
list_processesunsigned_only=trueon finance-mbp-143 rows1.2s
!Agent is unprivileged; 4 processes' signatures not checked.
outbound_connectionson finance-mbp-147 rows340ms
list_autorunssuspicious_only=trueon finance-mbp-142 rows0.9s
recent_changeshours=24executable_only=true5 rows2.4s
event_logon finance-mbp-140.1s
needs root: the agent is not elevated
process_treepid=4312on finance-mbp-140.6s

Suspicious. Investigate. An unsigned binary /tmp/.cache/nodeh (pid 4312, started 02:03) holds an established connection to 203.0.113.5:443. A launch agent that starts it was written at 01:23, forty minutes earlier. Three facts that are individually ordinary, and together are not.

Confidence: high. The plist, the binary and the socket agree on timing.

Not checked: event_log needs root, so tonight's system events were not read. needs root, so last night's system events were not read.

Do now: copy /tmp/.cache/nodeh somewhere safe before it is removed, then kill 4312. Check whether any other machine has talked to 203.0.113.5.

Copy reportAsk againSave as finding
Ask about finance-mbp-14
AnthropicClaude Sonnet 5 · Recommendedeffort: high ▾InvestigateStop
  1. 02:1409:14One question about one laptop.
  2. Five checks go out at once. The hairline under each is time against that tool’s real limit.
  3. Results land in the order they finish. One could not run, and the answer says so.
  4. The answer quotes the pid, the path and the address.
  5. Illustrative data. Fictional machines, people and addresses.
The guardyn console, drawn with the product’s own components. Illustrative data: fictional machines, people and addresses.
process_treepid=43120.6s
1launchdrootsystem
4312nodehfinanceunsigned
Children
4377shfinancesystem
4380curlfinancesystem
/tmp/.cache/nodeh, started 02:03 by launchd as finance
outbound_connections7 rows340ms
ProcessRemoteSigned
nodeh 4312203.0.113.5:443unsigned
Safari 811198.51.100.24:443system
nsurlsessiond 402198.51.100.77:443system
Mail 790192.0.2.41:993system
Show all 7 rows
!A single instant. A quiet result is not proof.
list_autorunssuspicious_only=true2 rows0.9s
com.cache.nodehlaunch agent · enabled
Location
~/Library/LaunchAgents/com.cache.nodeh.plist
Target
/tmp/.cache/nodeh
Signed
unsigned
Modified
01:23 tonight01:23 last night
crontabcron · user finance
Command
*/30 * * * * ~/bin/sync-notes.sh
Modified
6 days ago
The plist was written 40 minutes before the process started.

Then it is yours to rank.

  • Severity is your call, not the model’s.

    Save an answer as a finding and you choose critical, high, medium or low. The title starts from the verdict line, and you can change it.

  • One problem, one entry.

    Raise the same thing twice and it stays a single finding with a seen count.

  • A work queue, not a feed.

    Assign it, acknowledge it, resolve it, or mark it not an issue.

No open findings means nothing in the evidence gathered so far looked wrong. That is not the same as nothing being wrong.The empty state of the findings queue

Hard limits

Read-only is a property of the binary.

The tool set is compiled into the agent. The server can send a tool name and typed arguments, checked on both ends. It has no way to send a command.

  • It cannot run commands

    Hard limit

    There is no shell tool, no script tool and no allowlisted-command tool.

    If this server were compromised tomorrow, the worst it could do to your fleet is read from it.

  • It cannot change anything

    Nothing writes, deletes, moves, kills or quarantines. Every remediation is yours to run, spelled out precisely enough to paste.

  • It only dials out

    The agent opens one outbound stream and never listens on a port. The server pings every 20 seconds, and after 70 seconds of silence the agent reconnects. It runs at most three jobs at a time.

  • It keeps its own record

    Every run is written to an audit log on the machine itself, so the endpoint has its own account of what was looked at.

  • It tells you what it did not check

    Truncated lists, skipped privileged checks and a machine that went offline mid-scan are all said out loud. Silence about a gap reads as completeness, and that is how people get hurt.

No arbitrary file reads. File contents come back only for a short allowlist of forensic paths. A deny list for keys, .env files and credential stores always wins, matched against the canonicalised path so a symlink cannot walk around it. An investigation console that can read any file is a data exfiltration tool with a nice interface.

finance-mbp-14guardyn-agent 0.5.2listening on:nothingguardyn.devthe console andthe model calls1 · hello, with its tool specs2 · one long-lived stream3 · a job, down that same streamtool name + typed arguments4 · the result, posted backfinance-mbp-14guardyn-agent 0.5.2guardyn.devconsole and model calls1 · hello, with its tool specs2 · one long-lived stream3 · a job, down that same streamtool name + typed arguments4 · the result, posted backlistening on the machine: nothing
Every connection starts on the machine. The dashed arrow travels inside a stream the agent opened.

Find out what is actually running on your machines.

One binary, one question, one honest answer, including the parts it could not see.

macOS, in Terminal
curl -fsSL https://guardyn.dev/install.sh | sh

Keep it running with launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/dev.guardyn.agent.plist

Windows, in PowerShell
irm https://guardyn.dev/install.ps1 | iex

Needs no administrator rights. It installs under your own AppData.

Linux, in a terminal
curl -fsSL https://guardyn.dev/install.sh | sh

Keep it running with sudo systemctl enable --now guardyn-agent

Then enrol, with the token from your console
guardyn-agent enroll --server https://guardyn.dev --token gdn_enrol_…