Skip to content
Browse the docs

Command line

Enroll a machine and run the service

How crunu enroll registers a server with a single-use code and prints its fingerprint, and how the crunu daemon service keeps environments in memory.

Last updated

On this page

A machine is a server with the crunu agent. It gets its own keys at enrollment and then runs the crunu-agent service, which keeps the granted environments decrypted in memory and serves them to crunu run and crunu pull. For the full flow in the web app, see Install the agent.

crunu enroll

Shell
crunu enroll [--server URL] [--name NAME] -

An owner or admin creates the machine in the web app and gets a single-use enrollment code that starts with crunu_enr_. The code is valid for 15 minutes by default and at most 24 hours, and it can be tied to specific addresses. Pass it on one line through stdin, or in CRUNU_ENROLL_CODE:

Shell
printf '%s\n' "$CODE" | sudo crunu enroll --server https://app.crunu.com -

crunu enroll refuses a code given as an argument. Arguments are visible to every user of the machine in the process list, so it exits with code 2 before contacting the server and without repeating the code. Giving the code both ways at once is also an error.

What happens next:

  1. crunu checks that the organization key on the server matches the fingerprint inside the code. If it doesn't match, the code is not presented.
  2. It creates the machine keys and sends their public parts, authenticated with a MAC derived from the code.
  3. It prints the machine fingerprint on the first line of its output, then says that the machine is waiting for approval. An owner or admin compares this fingerprint with the one in the web app before approving.

Run it as the service user or as root, so the files get the owner of the state directory. The server address comes from --server, then CRUNU_SERVER, then server in agent.json. --name sets the host name the admin will see, which defaults to the system host name. The machine's own name is set by the admin when creating it.

If the connection drops during enrollment

If the server answered 409 because data changed at the same time, crunu enroll retries the same request up to 3 times with a growing pause. If no answer came at all, the outcome is unknown: the keys are kept, no enrollment record is written, and the exit code is 1. Run crunu enroll again with the same code. crunu signs in with the saved keys and learns from the server whether the enrollment went through, without presenting the code a second time. If the server rejected the request outright, nothing was enrolled and the keys are deleted.

crunu daemon

The service runs under systemd as crunu-agent.service. Start it with:

Shell
sudo systemctl enable --now crunu-agent

It opens its socket with mode 0660 for the crunu group, then tells systemd it's ready. It signs in with the machine key, checks the server every minute and renews its lease every 5 minutes. Decrypted environments are kept only in memory. Without an enrollment it doesn't start, and the unit checks for one.

What happenedWhat the service doesWhat crunu run gets
The machine isn't approved yetKeeps trying at each checkExit code 5 and a hint to verify the fingerprint
The machine was revoked or its lease expiredWipes the environments from memoryExit code 4
No connection or a server errorRetries with a growing pause and serves the last verified state until the lease endsThe last verified variables, then exit code 4 after the lease ends
Organization data failed verificationDoesn't apply it, logs an alert, serves nothingExit code 6
One environment failed verificationDoesn't serve that environment, logs an alert, serves the othersExit code 6 for that environment
The machine's address is outside an environment's network ruleStops serving that environment at once, unless the machine has a valid machine passExit code 7 for that environment
crunu is older than the server's minimum agent versionDoesn't sync and explains why in its logExit code 1
state.json can't be writtenKeeps serving the last saved state, no longer than its saved leaseThe last saved variables, then exit code 4

The service saves its rollback-protection state to state.json before it serves newly verified data. After a restart, the server can't quietly bring back anything older than what the service already served.

SIGHUP makes the service check the server now:

Shell
sudo systemctl kill -s HUP crunu-agent

SIGTERM wipes the environments from memory and stops the service with exit code 0. systemctl status crunu-agent shows the number of environments, how many are closed by network rules, and when the lease ends.

Service settings

/etc/crunu/agent.json is optional. Without it the service uses the server address from its enrollment and the defaults below. The file is strict JSON, and an unknown key is an error. Updating the agent doesn't change it.

KeyDefaultMeaning
serverthe enrollment addressThe server address, if the server moved. It must match the server's public address.
pollInterval"1m"How often to check the server.
renewInterval"5m"How often to renew the lease.
socket/run/crunu/agent.sockSocket path. CRUNU_SOCKET takes priority.
socketGroupcrunuGroup of the socket. Without a group, only root and the service user can connect.
releasesUrlbuilt into the releaseRelease directory for crunu self-update.

Durations are Go strings such as "30s", "5m" or "1h":

JSON
{ "server": "https://vault.company.example", "pollInterval": "30s" }

A shorter pollInterval means the service notices a revocation sooner. With the default of one minute, revocation reaches an online machine within minutes. An offline machine keeps serving what it has until its lease ends, 24 hours by default. Programs that are already running keep their variables until they restart.