Node Enrolment
A node is a machine that has enrolled with a Vagaris instance and can prove it. Enrolment gives the machine a server-side identity that leases can be bound to, so a run claimed by this machine cannot be replayed from another one.
Enrol
vagaris node enroll --company-id <company-id>
- The CLI computes a machine fingerprint and generates an Ed25519 key pair. The private key never leaves the machine.
- It creates an authentication challenge (
POST /api/cli-auth/challenges) carrying the selected company, fingerprint and public key, and prints an approval URL and the challenge id. - Open the URL as an operator with current write access to that company and approve. Viewers cannot approve enrollment. An already-authorized board credential may approve; this is not product ratification or a new permission grant. The CLI polls for up to two minutes; Ctrl+C stops waiting.
- On approval it calls
POST /api/nodes/enrolwith the challenge id, fingerprint, hostname, platform and the public key, then saves the key pair to~/.vagris/node-identity.jsonwith mode 0600.
The command prints the node id and hostname on success. A denied or timed-out challenge does not enroll a node or save the new local identity.
Enrollment, status, doctor and revoke use --company-id, the configured company environment variable, or the selected context profile. They never choose the first company membership. HTTP clients pass ?companyId=<uuid> on node routes; a company-scoped agent can omit it and use its authenticated company, but still needs a legitimately approved enrollment challenge.
The server binds enrollment to the approved company, fingerprint, key, algorithm and approver's current authority in one transaction. Legacy login challenges cannot enroll nodes. Identical replay is idempotent while the approval remains valid. Key rotation requires a new approval obtained after the last enrollment; replaying an older challenge cannot restore an old key. A key-bearing node cannot be downgraded to fingerprint-only enrollment.
Approve an enrolment
printf '%s' "$APPROVAL_LINK" | vagaris node approve-enrolment --link-stdin
Answers a pending enrolment from the terminal, as the operator who is signed in. The approval link is what
the enrolling machine printed. Pipe it in whole on stdin: it carries both the challenge id and the
challenge secret, and anything passed as an argument lands in your shell history and in ps output for
everyone else on the machine. If only the id reached you, pass the id as the argument and the secret on
stdin:
printf '%s' "$CHALLENGE_TOKEN" | vagaris node approve-enrolment <challenge-id> --token-stdin
Passing the whole link as an argument (vagaris node approve-enrolment "<approval link>") still works, but
the command warns that the secret has already reached your shell history.
Before it sends anything, the command asks the server who this sign-in is, then prints the server's own
description of the request — the command, the client, the access asked for, the company, and when the
challenge expires — and asks you to confirm. --yes skips the prompt for non-interactive use; with no
prompt available and no --yes, it refuses rather than approving something unattended.
It refuses, without sending, when:
| Refusal | Why |
|---|---|
An --api-key or environment key is in use | Approving a credential request is a human act. A service principal that could mint its own next credential would hold one nobody can revoke. |
| No credential at all | Sign in first with vagaris auth login --operator --device. |
| The sign-in authenticated but is not linked to a user | The server cannot attribute the approval to anyone. The message names the identity subject an instance admin must link. |
| The challenge is not pending | Approved, denied, cancelled and expired challenges are final. |
| The server says this sign-in cannot approve it | Enrolment approval needs current write access to the requested company. |
Authority is the server's decision, not the command's: it submits through the ordinary approval path and reports what comes back. Approving from a different machine than the one enrolling is supported and normal — the two are separate commands precisely so that one invocation can never create and approve its own challenge.
Status
vagaris node status
vagaris node status --json
Looks the node up by this machine's fingerprint and prints its id, hostname, platform, health (healthy, degraded or otherwise), enrolment time, last heartbeat, the CLI version it last reported, and a revocation notice if revoked. A machine that has not enrolled is told to run vagaris node enroll.
Doctor
vagaris node doctor
Five checks:
| Check | Pass condition |
|---|---|
| Node enrolment | The fingerprint resolves to a node that is not revoked |
| Cryptographic attestation | The server issues a nonce, the CLI signs it with the local private key, the server verifies it against the enrolled public key. A cloned identity file without the private key fails here even with the same fingerprint. |
| Node health | The server reports healthy (warn on degraded) |
| Heartbeat recency | Last heartbeat under 5 minutes ago (warn under 30) |
| Platform compatibility | darwin or linux; anything else is reported as untested |
A missing local key file yields a warning telling you to re-run enrolment. The repair hint printed by a failed enrolment check reads node enrol; the command is vagaris node enroll.
Capabilities
vagaris node capabilities --json
Reports the platform, the runtimes detected on PATH (node, python3, git with their versions) and the CLI version. Used when deciding which work a machine can host.
Revoke
vagaris node revoke --reason "laptop reassigned"
Asks for confirmation, then POST /api/nodes/<id>/revoke. A revoked node can no longer present valid credentials: its active leases are marked revoked and its running runs cancelled on the server. A process already executing on the node stops the next time it touches the server (lease verification or heartbeat); the revoke itself does not signal it. This enrollment flow cannot reactivate revoked nodes.
Using the node
Pass the node id when claiming a run so the lease is bound to it:
vagaris dev --agent-id <agent-id> --run-id <run-id> --node-id <node-id>
Enrolment, attestation and lease state also appear in vagaris support-bundle output (redacted), so support can see whether a node problem is identity or health.