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 530 tools in the current build, of which 521 are registered by default — the nine
sensitive-scope tools need--enable-sensitive. They are listed in the Tool reference; the process for adding one is under Contributing. - 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-19. Source: levantar-ai/secronyx. Found a mistake? Tell us.