Skip to main content

SDK connection

Use devices.sdk.connect to connect one DevKit to an SDK endpoint over WireGuard and mount the endpoint's NFSv4 workspace on the DevKit. MQTT carries the setup command and progress events; workspace traffic flows directly between the DevKit and SDK endpoint through the tunnel.

Your cloud integration configures the SDK endpoint and authorizes its peers. Kerrigan configures the selected DevKit over local SSH and reports the outcome. The Cloud Control CLI implements both sides of this workflow for the supplied AWS endpoint.

Why use SDK Connection instead of ICE Peer Pairing?​

SDK Connection is the simplified path for controlled cloud SDK endpoints, including managed EC2 instances. The integration knows the endpoint address, can configure its WireGuard peer automatically, and can expose an NFS workspace for the DevKit. Kerrigan therefore needs only the endpoint's public WireGuard configuration; it does not need ICE candidate gathering, a signaling service, or a TURN relay.

Use ICE Peer Pairing when the other peer is an authorized developer's machine on an arbitrary network and its reachable UDP path is not known in advance. Both models use WireGuard to protect traffic; ICE adds path discovery and relay fallback, while SDK Connection assumes the controlled endpoint can be configured directly.

Before connecting​

  • Select one enrolled, reachable DevKit and an authorized Kerrigan command topic.
  • Configure the endpoint's WireGuard listener and NFS export, and obtain its public key, public HOST:PORT, tunnel address, and export path.
  • Allocate a DevKit tunnel address and a connection_id for this pairing.
  • Ensure the DevKit has WireGuard, iproute2, and NFS client tools, or request installation with install_tools: true.

The supplied endpoint serves 10.77.0.1:/srv/kerrigan/sdk; the default DevKit mount point is /workspace. NFSv4 uses TCP port 2049 through WireGuard.

Connection flow​

Open the sequence diagram in a full page.

  1. Submit. Subscribe to the command-specific event topic, then publish devices.sdk.connect with the endpoint configuration. Use the MQTT request example inside the command envelope.
  2. Exchange public keys. Kerrigan asks the DevKit to generate its key pair locally, then publishes command.progress with phase awaiting_endpoint_peer and the DevKit public key in detail.sdk_connection.
  3. Authorize the endpoint peer. Your integration consumes that event and installs the DevKit public key on the endpoint, restricting its AllowedIPs to the allocated DevKit tunnel address, for example 10.77.0.42/32.
  4. Establish the tunnel. Kerrigan also tells the DevKit to configure and start wg-quick@wg-kerrigan. Endpoint authorization and DevKit setup can overlap: there is no second MQTT acknowledgement or finalize command. The DevKit waits for a real WireGuard handshake with the authorized endpoint.
  5. Mount and complete. After the handshake, the DevKit mounts the NFS export. Kerrigan emits command.completed only after the handshake and mount succeed. The result includes the handshake epoch and mounted NFS source.

The awaiting_endpoint_peer event is an instruction for your integration to act, not a successful connection result. Subscribe before publishing so you can handle it promptly. Deduplicate events and match the command and connection IDs; make endpoint peer configuration safe to repeat. See the delivery rules.

The CLI uses AWS Systems Manager for endpoint lookup and peer administration. A direct MQTT integration must supply equivalent endpoint operations; sending the MQTT command alone does not authorize the endpoint peer.

Key ownership​

Each WireGuard private key is generated and retained by the peer that owns it. The controller distributes only public keys:

KeyGenerated and stored onShared with
DevKit private keyDevKitNobody. It is never returned through SSH, MQTT, command storage, or logs.
DevKit public keyDevKitController and SDK endpoint peer configuration.
Endpoint private keySDK endpointNobody. It remains on the endpoint.
Endpoint public keySDK endpointController and DevKit WireGuard configuration.

The DevKit stores its private key in /etc/wireguard/wg-kerrigan.key, with mode 0600. Controllers use devices.sdk.connect for SDK pairing without handling DevKit private-key material.

Retries and failures​

command_id and connection_id have different scopes. command_id deduplicates one MQTT command. connection_id identifies the active SDK pairing on both peers and must be reused when retrying that pairing or disconnecting it.

Repeating connect with the same connection_id reuses the DevKit key pair, refreshes the matching endpoint peer, and restarts WireGuard as needed. If the workspace is already mounted from the requested NFS export, Kerrigan preserves that mount so active processes are not disrupted. It replaces the mount only when it points at a different source. A new connection ID replaces the previous local pairing. Connection-ID checks prevent a late cleanup request for an old attempt from tearing down a newer pairing.

Kerrigan refuses an offline DevKit, based on its most recent heartbeat, before key preparation starts. After that, the SSH session that prepared the key is the proof of reachability, so a slow preparation, such as an install_tools package index refresh, does not fail the connection as offline.

If a new pairing fails after the DevKit has generated its key pair, including a lost SSH session, a failed handshake, or a failed mount, Kerrigan attempts a connection-ID-guarded local rollback. It removes the workspace, tunnel, key, and state only while the failed attempt still owns the active connection and the workspace can be unmounted. It preserves a newer pairing, and it does not tear down WireGuard under a busy NFS mount. Because Kerrigan cannot directly administer an arbitrary endpoint, the controller must also remove any peer it authorized for the failed attempt. The cloud control CLI performs this endpoint rollback automatically.

A failed repeat of a pairing that was already active is not rolled back, so a workspace in use is not torn down. The pairing keeps its key and connection ID; retry the connect or disconnect it with the same connection_id.

Disconnecting​

Publish devices.sdk.disconnect with a new command ID, the same DevKit target, and the active connection_id. Kerrigan unmounts the workspace, removes its managed /etc/fstab entry, stops WireGuard, and deletes the DevKit's connection files and keys. A stale connection ID cannot remove a newer pairing.

Disconnect can kill processes using a busy workspace to unmount it. Stop work using the mount before requesting disconnect. Kerrigan verifies that the mount is gone before stopping WireGuard or deleting keys.

After successful DevKit cleanup, your integration must remove the matching endpoint peer with the same connection-ID guard. The CLI performs this ordering automatically. If local cleanup fails, inspect the command error before retrying; do not assume either side has been removed.

Endpoint capacity​

The supplied staging endpoint is single-peer: a new CLI connection replaces its existing peer. Avoid overlapping pairings against that endpoint. MQTT can track concurrent commands independently, but that does not provide endpoint capacity or serialize conflicting operations on one DevKit.