Guides
Compared with alternatives
How a fixed catalogue of authenticated, audited, redacted read-only queries compares with running an agent on the host or letting a model drive SSH with a read-only account, and what the design gives up.
Teams evaluating AI-assisted diagnostics usually weigh three designs: run the model's agent on the box, let the model drive SSH with a read-only account, or put a purpose-built read-only server in front of the host. Secronyx is the third. This page sets out where it stands against the other two so the trade-offs can be reviewed rather than assumed, and then lists what the design gives up. Every claim in the Secronyx column is backed by a flag, a file or a test in the repository; the last section says where.
The alternatives
| LLM agent on the box | LLM over SSH with a read-only user | Secronyx | |
|---|---|---|---|
| What the model can do | Anything the agent process can do: run binaries, write files, open sockets | Anything the user's shell allows; "read-only" is whatever sudoers, file modes and shell restrictions happen to permit |
Only the registered tools, each a fixed query with a typed result |
| Write capability | Present unless every path is locked down by hand | Present: >, tee, pkill, crontab -e, package managers with cached credentials, and sudo for anything the read-only account was granted |
No tool modifies system state. Commands are built as argument vectors, never as a shell command string, and Windows collectors run fixed PowerShell scripts whose caller-supplied values are quoted |
| Command injection | Model output is executed as-is | Model output is executed as-is | Tool arguments are validated against allowlists and quoted; a hostile site_name yields a refusal, not a command |
| Least privilege | Agent needs broad rights to be useful | One account, one privilege level, for every task the model might try | Scopes per tool, granted per identity. sensitive tools are not even registered unless enabled |
| Authentication | Whatever the agent framework ships with | SSH keys, usually shared or long-lived, with no notion of which queries a key may run | OIDC, OAuth introspection, API keys with expiry and CIDR pinning, mutual TLS with SPIFFE and CRLs, or SSH-key request signing with replay protection |
| Authorization granularity | None | Per account | Per tool, per identity, enforced on every call and reflected in tools/list |
| Secret leakage | /proc/*/environ, shell history, config files, all readable |
Same: cat /etc/app.conf returns the password; ps auxww returns --password= arguments |
Redaction on by default for environments, command lines, config contents and log lines; file reads limited to allowed roots with key material denied |
| Data exfiltration to the model | Unbounded | Unbounded: tar, base64, curl |
Result size capped (4 MiB), no arbitrary file read, no outbound probes to metadata or loopback addresses |
| Network reach from the host | Full | Full: the read-only user can still curl the cloud metadata service |
Probe targets policed; metadata, link-local and loopback denied by default |
| Audit trail | Agent logs, if any; not tied to the host | auditd or shell history, both circumventable by the same account |
Tamper-evident JSON Lines audit log with identity, arguments, duration and outcome, on by default, with a stderr fallback so it never silently stops |
| Output for the model | Free text the model must parse; brittle across distros and locales | Free text; ps and netstat differ by platform and version |
Typed JSON with stable field names across Linux, macOS and Windows |
| Honesty of results | Whatever the tool printed | Whatever the tool printed | Forecasts and trends carry method, sample count and caveats; a result that cannot be computed says so instead of guessing |
| Resource impact | Unbounded; a runaway loop is a runaway loop on production | Unbounded per session | A 4 MiB result cap on every transport; on the HTTP transport, per-client rate limiting, a 32-way concurrency cap and lockout after repeated auth failures |
| Blast radius of a compromised model or prompt injection | Host compromise | Host compromise within the account's reach, often escalating via misconfiguration | Read-only queries within the identity's scopes; the worst case is disclosure of what those scopes already permit |
| Compliance evidence | Reconstructed after the fact | Session recordings, if deployed | Audit log verifiable with --audit-verify; redaction coverage and scope tables documented |
| Operational cost | Agent runtime on every host | SSH bastions, key management, sudoers review |
One static binary, no language runtime, one config |
| Deployment posture | Requires an agent runtime with network access | Requires SSH exposure and key distribution | stdio by default; HTTP listener refuses to start exposed without auth and TLS |
What this design gives up
Being honest about the limits is part of the case to a security team.
- Coverage is bounded by the tool catalogue. If a question needs a command that is not a registered tool, the answer is "add a tool", not "run the command". That is the point, but it is a real constraint. The catalogue is 661 tools in the current build, of which 630 are registered by default — the 31
sensitive-scope tools need--enable-sensitive. It reaches well past resource metrics, into Windows persistence and execution evidence, file and binary integrity and signatures, browser and editor extensions, event history, macOS security controls, container security and credential hygiene, but it is still a list. They are listed in the Tool reference; the process for adding one is under. - Read-only means no remediation. Restarting a service, rotating a key or clearing a queue happens through your existing change process, with the diagnosis attached.
- Collectors still run as the server's user. The server should run as a dedicated low-privilege account with only the file and device access its tools need; the scope and path policies reduce exposure but do not replace OS-level least privilege. The Dockerfile runs as uid 1000 and the Helm chart sets
runAsNonRoot: truefor the same reason. - A leaked credential still discloses what its scopes permit. Expiry, CIDR pinning, mTLS gating and short-lived OIDC tokens exist to keep that window small.
- Redaction is pattern-based. A secret that does not look like a secret, given without a
password=style label, is not detected. Field-name rules catch the labelled cases; scope policy and the file access policy limit what can be reached at all. The Redaction page lists the known limits.
When the alternatives are reasonable
- A disposable lab host with no secrets, where an agent on the box is convenient.
- A break-glass workflow where a human, not the model, types the commands over SSH and the model only reads a session transcript.
For production hosts holding credentials or regulated data, a fixed catalogue of authenticated, audited, redacted read-only queries is the design a security reviewer can actually sign off.
Where each row comes from
A reviewer should be able to check the table rather than take it on trust. The Secronyx column maps to the code as follows.
| Row | Mechanism | Where to read more |
|---|---|---|
| Write capability, command injection | All process execution goes through internal/cmdexec, which builds an exec.Cmd from an argument vector; no call site passes a command string to sh -c. PowerShell scripts run with -NoProfile, and cmdexec.PowerShellArgs adds -NonInteractive so an unattended collector fails rather than blocking on a prompt. Caller-supplied values that reach a script — IIS site and application pool names, Windows event log channels, service names — are checked against an allowlist first (internal/windows/validate.go, internal/logs/eventlog_validate.go) and then quoted with cmdexec.PSQuote. Probe targets are checked against a policy before any packet is sent. |
Security model |
| Least privilege, authorization granularity | ScopePolicy in internal/mcp/authz.go withholds tools at registration; IdentityAllows checks every tools/call against the caller's grants and returns JSON-RPC -32003 on a mismatch. |
Scopes and authorization |
| Authentication | --token, --oidc-issuer, --auth-server, --api-keys-file, --tls-client-ca with --mtls-identity-file and --mtls-crl, --ssh-authorized-keys and --ssh-ca-keys. |
Authentication |
| Secret leakage | Redaction is on by default (--no-redact to disable, logged); the inventory of redacted fields and the tests that cover them is documented. Path policy roots and deny globs live in internal/pathpolicy. |
Redaction, Network and path policy |
| Data exfiltration, network reach | --max-result-bytes (default 4 MiB); internal/netconfig/probepolicy.go refuses metadata, loopback, link-local, multicast and unspecified addresses before any packet is sent. |
Network and path policy |
| Audit trail, compliance evidence | internal/audit: JSON Lines, SHA-256 chain, O_APPEND, stderr fallback, --audit-verify. |
Audit logging, Compliance mapping |
| Resource impact | internal/agent/executor.go deadlines (30 s default, 120 s maximum) and a concurrency cap of 4; HTTP rate limiting at 20 requests/s with burst 40, 32 in-flight, lockout after 10 authentication failures. |
Security model |
| Honesty of results | internal/analytics/history.go attaches a caveat and a confidence capped at 90 to every forecast and trend. |
Use cases |
| Deployment posture | HTTPConfig.Validate in internal/mcp/http.go refuses a non-loopback bind without authentication and TLS unless --allow-unauthenticated is passed. |
Remote access over HTTP |
Related pages: Use cases, FAQ, and the Secronyx homepage.
Built 2026-09-28. Found a mistake? Tell us.