RFDs/0013

Live terminal

State
published
Authors
Darwin D Wu
Discussion
renga-dcim/renga#149
Labels
rengaagentcontrol-planesecuritysoftware
Implemented
0%Checklist

Goal

Give authorized operators an interactive terminal on a host through Renga, when nothing else will do, with more control and a better record than handing out SSH access. RFD 1 requires live terminal access to be disabled by default and to need authentication, RBAC, agent-side allow/deny policy, short per-session leases, and target-level access rules, with step-up authentication and session recording as organization settings (RFD 19). This RFD designs each, and the installation credentials that terminals and RFD 14's VM operations both need.

Installation credentials

An intake key authenticates an organization, not a machine (RFD 3), so anyone holding it can claim to be any installation. That is fine for inventory and RFD 9's observe jobs, and fatal for a terminal.

Each installation therefore generates an Ed25519 key pair in its state directory (mode 0600) and presents the public key on check-in. Renga records the first key it sees for an installation as pending. An owner or admin approves it on the Collectors page, comparing the fingerprint the agent prints locally. From then on, every lease of an operate or interactive job must be signed with the approved key, over the job ID, lease token, and a server nonce. A key change returns the installation to pending, blocks its privileged jobs, and opens a finding. A stolen intake key alone can then report inventory, but cannot take a terminal or VM job.

Trusted privileged targets

Approving a key proves installation identity, not which resource it may control. Privileged targeting requires a separately approved, organization-scoped binding between the resource ID and installation ID plus approved key fingerprint. An owner/admin verifies this binding through a trusted enrollment process; shared intake observations, submitted identifiers, source associations, and saved-view membership cannot create or silently change it. Binding changes require explicit approval and invalidate pending authorizations for the old binding.

Grants authorize resource IDs against these trusted bindings, not whichever agent an inventory report currently associates with them. Target sets derived from views or teams must not gain privileged targets through shared-key inventory alone. Renga captures the binding/version in each job and rechecks the grant, organization policy, binding, and approved credential before dispatch and lease. The signed request includes the target and binding version alongside the job ID, lease token, and nonce. Missing, changed, or conflicting bindings block execution instead of redirecting a job to another installation. RFD 14 extends the same rule to the provider and domain identity of a VM.

Enabling terminals

A terminal session requires all of these:

  1. The agent enables it locally ([terminal] enabled = true), names the local account sessions run as (run_as), and has an approved installation key. run_as may not be root, and the agent refuses to start a session as UID 0.

  2. The organization enables terminals.

  3. The user holds a terminal grant covering the target. A grant names a target set (resources, a saved view, or an owning team) and may expire, within the organization’s maximum validity if it sets one (RFD 19). Owners and admins create grants; nobody holds one by default, including owners.

  4. If the organization requires step-up authentication for terminals, the user has authenticated strongly within the last five minutes: a passkey assertion or authenticator code (RFD 19), or a fresh password entry when the user has neither. Step-up is off by default.

Session flow

  1. The user opens a terminal from the resource page. Renga checks the grant and, where required, step-up authentication, then creates an interactive job, terminal.session@1, with a lease of at most 10 minutes that renews while the session is active and ends after 5 idle minutes.

  2. The agent leases it with a signed request and opens a PTY as run_as.

  3. Input and output flow over a Phoenix Channels relay: the browser and the agent each join the session’s topic. Terminals are the one feature that requires the channel. They are not a correctness path, so when the channel is down there is no terminal, rather than a degraded one.

  4. Revoking the grant, an admin ending the session, the lease lapsing, or the channel dropping all end the session, and the agent kills the PTY’s process group.

The browser renders the session with xterm.js, which implements terminal emulation (escape sequences, colors, mouse, paste, and resizing). The relay only carries bytes and window-size changes, so Renga implements no terminal behavior itself. Each keystroke’s round trip adds the browser-to-Renga and Renga-to-agent latency, typically tens of milliseconds, comparable to other relayed web terminals.

Native SSH clients

Operators may use their own terminal and SSH client instead of the browser. A host behind NAT cannot accept a direct connection, and an agent-generated key would have to be shipped to the user as a secret, so neither is used. Instead:

  • A renga command-line tool signs in through the browser, where any required step-up authentication happens, and serves as OpenSSH’s ProxyCommand. It tunnels the SSH stream through the same session relay, so latency matches the browser path and hosts need no inbound port.

  • Renga runs an SSH certificate authority. After the same grant and step-up checks, and the creation of the same terminal.session@1 job, it signs the user’s own public key as a user certificate valid for five minutes, with the job ID as its key ID. The certificate permits a PTY and nothing else: no port, agent, or X11 forwarding, and no exec or subsystems such as SFTP.

  • The agent terminates SSH with an embedded server rather than the host’s sshd. It accepts only a certificate from the Renga CA key it pinned when its installation key was approved, whose key ID matches the session job it holds, and opens the PTY as run_as exactly as for the browser.

CA key rotation and recovery

Pinning protects agents from a server that swaps the CA key, so the key changes only in ways the agent can verify or an operator performs locally:

  • Rotation: Renga publishes the successor CA public key in check-in responses, signed by the currently pinned key. The agent pins the successor only when that signature verifies against the key it already trusts, keeps accepting certificates from the old key until an overlap period ends, logs the change, and reports it so Renga opens an informational finding. A successor that does not chain from the pinned key is refused and opens a finding.

  • Recovery: if the pinned key is lost or compromised, an operator runs renga-agent reset-ssh-ca on the host. That clears the pin and blocks native SSH until the agent pins a key again at its next installation-key approval. Nothing Renga sends can clear a pin remotely.

A compromised pinned key can sign a successor, so recovery from compromise is always the local reset, never rotation.

Because the agent owns the PTY, recording, idle limits, and termination work the same for both paths. Using the host’s sshd was rejected: the encrypted stream could not be recorded, every host would need sshd_config changes, and sshd would allow forwarding and file transfer outside this RFD’s controls.

Recording

Recording is an organization setting, on by default (RFD 19). When it is on, Renga records each session’s input and output as an asciicast stream, with timestamps, bounded at 50 MiB per session and kept for one year by default. Command logging is not used as the record, because a shell can always hide a command from it. The user is told before a session starts whether it is recorded. Owners and admins can replay sessions, and every replay is itself logged. With recording off, Renga still records who opened each session, on which host, when, and for how long.

Threats

Threat Mitigation

Leaked intake key

Cannot sign leases; no approved installation key.

Compromised Renga account

Needs a current grant, and step-up authentication where the organization requires it; the session is recorded unless the organization turned recording off.

Malicious request to run as root

run_as is local agent configuration, never a request parameter; UID 0 is refused.

Renga server compromise

Cannot enable terminals on agents that have them disabled locally.

Stolen SSH certificate

Valid for five minutes, bound to one session job held by one agent, and useless without the matching private key.

Swapped SSH CA key

Agents accept only a successor signed by their pinned key; anything else is refused and opens a finding. Clearing a pin needs local access.

Tunneling or file transfer over SSH

The certificate and the agent’s server refuse forwarding, exec, and subsystems.

Decisions from review

  • Step-up authentication is an organization opt-in, off by default. When required, it is a passkey assertion or authenticator code (RFD 19) when the user has one, otherwise a fresh password entry, within five minutes.

  • Recording is an organization setting, on by default, and recordings are kept for one year by default; organizations may change both (RFD 19).

  • Terminal grants may expire; an organization may set a maximum validity (RFD 20).

  • Operators may connect with their own SSH client through the renga CLI, using five-minute certificates from Renga’s SSH CA and the agent’s embedded SSH server, alongside the browser terminal.

  • The SSH CA key rotates by publishing a successor signed by the pinned key; recovery from a lost or compromised key is a local renga-agent reset-ssh-ca, never a remote action.

  • Owners and admins may grant terminal access to themselves. Such a grant is audited like any other, and every session it opens follows the organization’s recording setting.

Rollout

  1. Add installation key pairs, approval, signed leases for privileged jobs, and key-change findings.

  2. Add organization enablement, terminal grants, and optional step-up authentication.

  3. Add the channel relay, the agent PTY session, and lifecycle enforcement.

  4. Add recording, replay, and replay auditing.

  5. Add the SSH CA, the renga CLI tunnel, and the agent’s embedded SSH server.

Implementation

Progress is tracked in the implementation checklist.