sam-node

sam-node is the mesh member that runs beside an agent or a service.

sam-node join [control-plane-url] [flags]   enroll and store a credential
sam-node run [flags]                        run the node
sam-node reset [--all] [--yes]              forget the credential or everything
sam-node skill install|list|show            manage the agent skill document

Files

The data directory is --data-dir if set, otherwise $SAM_DATA_DIR, otherwise the user configuration directory of the operating system (~/.config/sam-mesh on Linux, ~/Library/Application Support/sam-mesh on macOS). It is created with mode 0700 and holds:

FileContents
agent.dbThe node’s key, credential, control plane URL and public key, router addresses, and OIDC refresh token. A running node holds a lock on this file. A second node started on the same directory refuses to start.
sam.sockThe local API Unix socket, mode 0600, removed on exit.
api-tokenGenerated by --daemonize when no token is configured.
sam-node.pid, sam-node.logWritten by --daemonize.

The configuration file is --config, by default sam-node.yaml in the working directory. A missing file is treated as an empty one. See node configuration.

Global flags

Accepted by every subcommand.

FlagDefaultMeaning
--control-planestored valueControl plane URL. join takes it as a positional argument. https:// is required unless the host is loopback.
--insecure-control-planefalseAccept a plaintext http:// URL to a non-loopback host. Whoever answers that URL becomes the node’s trust root. Intended for networks that are already trusted, such as a cluster.
--configsam-node.yamlNode configuration file.
--data-dirsee aboveData directory.
--audiencesam-mesh-audienceOIDC audience to request.
--oidc-issuerfrom /infoOverride the identity provider that the control plane advertises.
--device-auth-urldiscoveredOverride the device authorization endpoint.
--headlessfalseForce the out-of-band login flow.
--auth-modeautoLogin flow: auto, device, oob or browser. auto uses the browser when one can be opened and the device flow otherwise. device fails if the provider has no device endpoint.

join

Enrolls the node with the control plane and stores the credential. Without a bootstrap token, join runs an interactive OIDC login.

FlagDefaultMeaning
--bootstrap-token-pathFile containing a bootstrap token.
--bootstrap-tokenThe token as a value. Visible in process listings. The file form is preferred.
--offline-accessfalseRequest an OIDC refresh token, so that the node can re-enroll on its own when its credential expires.
--allow-loopbackfalseAdvertise and dial loopback and link-local addresses. For several nodes on one host.
--announce-privatetrueAdvertise RFC 1918 and ULA addresses. Turn off when peers are only reachable through a relay.
--router-connect-timeout5sDial timeout per router.

Labels declared in the configuration file are sent with the enrollment. Running join for a node that already holds a credential for the same control plane enrolls it again. For a different control plane, join refuses until sam-node reset has been run.

run

Starts the node. If the data directory holds a credential, the node uses it. Otherwise the node enrolls if it has a way to (--jwt-path, --bootstrap-token-path, --client-id, or --join). If it has none, it starts an unauthenticated local MCP server whose only tool explains how to enroll.

Enrollment

FlagDefaultMeaning
--joinfalseRun the interactive login on first start if there is no credential. Needs a terminal and --control-plane (or a stored control plane). Does nothing once the node is enrolled.
--jwt-pathFile containing an OIDC token to enroll with, for example a projected service account token.
--jwtThe token as a value. Logged as a warning. The file form is preferred.
--bootstrap-token-path, --bootstrap-tokenAs for join.
--client-id, --client-secret-pathOAuth client-credentials grant against --oidc-issuer. The secret can also come from SAM_CLIENT_SECRET.
--offline-accessfalseWith --join, as for join.
--control-plane-public-keystored valueControl plane Ed25519 public key, 32 bytes in hex. Only needed when the store lacks it.

Local API

FlagDefaultMeaning
--bind-addr127.0.0.1:8080TCP address for the local API. An empty value disables TCP.
--socket-path<data-dir>/sam.sockUnix socket for the same API. An empty value disables it. At least one listener is required.
--api-token-pathFile containing the bearer token for the TCP listener, or SAM_API_TOKEN. Required when TCP is enabled, unless mTLS is enabled.
--tls-cert, --tls-keyServe the TCP listener over TLS.
--tls-caRequire client certificates signed by this CA (mTLS). Callers with a verified certificate need no token.
--metrics-addroffServe /metrics, /healthz and /readyz without authentication on this address, for scrapers. Do not expose it on shared networks.
--daemonizefalseStart detached, wait for the API to answer, print the endpoint, token file and log path, and exit. Safe to run repeatedly. Generates api-token if no token is configured. Refuses to run on a node that has never enrolled.

Mesh

FlagDefaultMeaning
--listen/ip4/0.0.0.0/udp/5001/quic-v1, /ip4/0.0.0.0/tcp/5002libp2p listen addresses. Repeatable.
--allow-loopback, --announce-private, --router-connect-timeoutAs for join.
--enable-relayfalseRelay traffic for other peers.
--meshpublic-meshMesh federation name. Must match the routers’ name.
--discovery-interval30sDHT discovery polling interval.
--dht-lookup-limit20Providers to query per DHT lookup.
--discovery-concurrency10Concurrent catalog fetches during discovery.
--dht-provider-addr-ttl, --dht-max-record-agelibrary defaultsDHT record lifetimes.
--backend-probe-timeout2sHow long a service backend may take to answer before the node declines to advertise it. Raise it for subprocesses that start slowly.
--control-plane-sync-interval15mHow often signing keys, the ban set, router addresses and the mesh policy are pulled from the control plane. Keep it well below the control plane’s --key-grace-period; raise it on large meshes.
--key-grace-period24hHow long a rotated-out control plane key is still accepted for verifying peers.
--monitor-bootstrap2mDelay before the router-connection monitor starts.
--monitor-interval1mHow often the monitor checks that a router is connected.
--autorelay-min-interval, --autorelay-boot-delay, --autorelay-backoff30s, 0s, 3slibp2p AutoRelay tuning.
--log-levelinfodebug, info, warn or error.

reset

FlagMeaning
(none)Delete the credential and control plane binding. The key and peer ID stay.
--allDelete every file the node keeps: agent.db, api-token, sam-node.pid, sam-node.log. The node gets a new peer ID. Asks for confirmation.
--yesSkip the confirmation, for scripts.

Both variants refuse while a node has the store locked.

skill

Installs the SKILL.md document that teaches an agent harness how to use the node.

CommandEffect
skill installWrite to ~/.claude/skills/sam-mesh/SKILL.md and ~/.gemini/config/skills/sam-mesh/SKILL.md.
skill install --projectWrite to ./.claude/skills/sam-mesh/ and ./.agents/skills/sam-mesh/ in the current directory.
skill install --dir DIRWrite to DIR/sam-mesh/SKILL.md.
skill listShow each install location and whether the copy matches this binary.
skill showPrint the document.

Environment variables

VariableEquivalent
SAM_API_TOKEN--api-token-path contents
SAM_CLIENT_SECRET--client-secret-path contents
SAM_DATA_DIR--data-dir

Exit behaviour

The node exits when its credential can no longer be refreshed. The causes are a ban, an expired session, or a signing key that was retired after its grace period while the node had no way to enroll again. The last lines of the log name the cause. A node that loses its routers keeps running and reconnects. A node whose control plane is unreachable keeps serving with its current credential until that credential expires.