Security Model
mTLS trust, the pairing protocol, serial-based identity, and the auth hook system.
mTLS Trust
ctrl-exec uses a private CA for all mTLS trust. The CA is created once on the ctrl-exec host. All agent certificates are signed by this CA. Neither side trusts certificates from public CAs or other sources for the operational port.
When ctrl-exec connects to an agent:
- The agent verifies the ctrl-exec certificate was signed by the CA.
- ctrl-exec verifies the agent certificate was signed by the CA.
- The agent additionally checks the ctrl-exec certificate serial number against the value stored at pairing time. A serial mismatch is rejected even if the certificate is otherwise valid.
There are no passwords, no shared secrets, and no SSH keys to distribute or rotate.
The Pairing Protocol
Pairing is the ceremony by which a new agent joins the fleet. It runs on a separate port (7444 by default) using server-TLS only — the agent does not yet have a certificate to present.
- The operator starts
ced pairing-modeon the ctrl-exec host. - On the agent host, the operator runs
ctrl-exec-agent request-pairing --dispatcher <hostname>. The agent generates a key pair, creates a CSR, and connects to the pairing port. - Both sides independently compute a 6-digit verification code from the CSR content. The operator verifies the codes match before approving — this prevents CSR substitution or misrouting attacks.
- On approval, ctrl-exec signs the CSR with the CA and returns the signed certificate, the CA certificate, and the current ctrl-exec certificate serial. The agent stores all three.
- ctrl-exec records the agent in the registry.
Pairing is a deliberate one-time ceremony. No keys are copied or distributed. The verification code step ensures a rogue pairing request cannot be approved by mistake.
The Auth Hook System
The auth hook is the policy engine. ctrl-exec has no built-in ACL system — all access control beyond the allowlist is implemented in hooks.
The ctrl-exec-side hook is called before every run, ping, capabilities, and API request. The agent-side hook is called after allowlist validation, before script execution. Both hooks operate independently and can be active simultaneously.
The hook receives request context as environment variables with the ENVEXEC_ prefix — action, script name, host list, arguments as a JSON array (ENVEXEC_ARGS_JSON), username, token, source IP, and timestamp. The same context is piped as JSON to the hook's stdin.
Exit codes: 0 = authorised, 1 = denied, 2 = bad credentials, 3 = insufficient privilege.
Certificate Serial Tracking
At pairing time, the agent stores the ctrl-exec's certificate serial in /etc/ctrl-exec-agent/dispatcher-serial. Every incoming connection is checked against this value. A mismatch is rejected and logged as ACTION=serial-reject.
After cert rotation (ced rotate-cert), all agents must receive the new serial. The overlap window (cert_overlap_days, default 30 days) allows offline agents to reconnect and receive the update before being marked stale.
Reference Documentation
Full security model, threat table, and file permissions: SECURITY
Operational guidance — cert lifecycle, revocation, CA compromise recovery, monitoring: SECURITY-OPERATIONS