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_idfor 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.
- Submit. Subscribe to the command-specific event topic, then publish
devices.sdk.connectwith the endpoint configuration. Use the MQTT request example inside the command envelope. - Exchange public keys. Kerrigan asks the DevKit to generate its key pair
locally, then publishes
command.progresswith phaseawaiting_endpoint_peerand the DevKit public key indetail.sdk_connection. - Authorize the endpoint peer. Your integration consumes that event and
installs the DevKit public key on the endpoint, restricting its
AllowedIPsto the allocated DevKit tunnel address, for example10.77.0.42/32. - 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. - Mount and complete. After the handshake, the DevKit mounts the NFS export.
Kerrigan emits
command.completedonly 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:
| Key | Generated and stored on | Shared with |
|---|---|---|
| DevKit private key | DevKit | Nobody. It is never returned through SSH, MQTT, command storage, or logs. |
| DevKit public key | DevKit | Controller and SDK endpoint peer configuration. |
| Endpoint private key | SDK endpoint | Nobody. It remains on the endpoint. |
| Endpoint public key | SDK endpoint | Controller 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.