sec: fail-closed verification + server-issued enrollment (v1.4.0)

Implements protocol v1.2.0.

verifySignature() returned true when no public_key was configured,
logging "skipping signature verification". The SSO installer never wrote
a public_key, so a default install executed reboot, service_restart,
configure_ldap, arbitrary_bash and update_binary UNVERIFIED from anything
that could reach its socket. An agent that cannot verify now refuses.

Canonicalization also disagreed with the server. Go's encoding/json
escapes <, > and & by default; JSON.stringify does not. Any payload
containing them hashed differently on each side and failed verification
-- for arbitrary_bash that is most real scripts (`>` redirection, `&&`).
Now uses json.Encoder with SetEscapeHTML(false), trailing newline
trimmed.

The SSO now rejects tokens it did not issue. Handles its close codes
(4001/4002/4003/4004) and backs off 5 minutes on an enrollment failure
instead of retrying every 5s forever. The connect log no longer prints
the URL, which carried ?token=.

install.sh gains --public-key and warns when none is configured.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 18:43:26 -04:00
parent 51750d01ec
commit d47d08ecab
9 changed files with 406 additions and 26 deletions
+14 -1
View File
@@ -2,6 +2,18 @@
Theta Agent is designed for rapid deployment across the fleet. The recommended method is via the "One-Liner" install, which marries the agent to a specific SSO Manager instance.
## Prerequisite: enroll the host
The agent's token is issued by the SSO, not chosen by you. In the SSO open
**Directory → Install Agent**, name the host, bind it to a host resource, and
press **Enroll & issue token**. You get:
- the **agent token** — shown once; only its hash is stored
- the **SSO public key** — pinned by the agent to verify high-risk commands
The modal builds the install command below with both already filled in. A token
the SSO did not issue is rejected at connect time with close code `4001`.
## Quick Start (The One-Liner)
The SSO Manager provides a pre-generated installation command. Copy and paste it into your terminal as root:
@@ -15,7 +27,8 @@ curl -fsSL https://sso.example.com/resources/theta-agent/install.sh | sh -s -- "
### Option B: Minimal Setup
Use this for rapid deployment with basic telemetry:
```bash
curl -fsSL https://sso.example.com/resources/theta-agent/install.sh | sh -s -- --url "https://sso.example.com" --token "your-host-token"
curl -fsSL https://sso.example.com/resources/theta-agent/install.sh | sh -s -- \
--url "https://sso.example.com" --token "<ISSUED_TOKEN>" --public-key "<BASE64_PUBLIC_KEY>"
```
### What this does: