Skip to content

Enrolling a fleet agent

This page walks through installing the fleet agent on a Linux host end to end: getting an enrollment token, installing and connecting the agent, confirming it appeared, and re-enrolling or removing it later. For what the agent actually does once connected, see Fleet agent.

  • A Linux host, amd64 or arm64, with root access
  • Outbound network access from that host to Sencai: HTTPS (443) to storage.googleapis.com for the installer and binary, and TCP 4400 to the fleet gateway (fleet.sencai.space). The agent only ever initiates the connection - no inbound port needs to be opened
  • Sencai must have admitted your host’s public IP address to the fleet gateway. Access to port 4400 is allowlisted per customer during onboarding - give your Sencai contact the public (egress) IP of every host you plan to enroll
  • An enrollment token. Tokens are issued by a Sencai platform administrator, not by organization Owners or Admins
  1. Go to Fleet → Agents (/gravity/agents).
  2. Click Enroll New Agent.
  3. Click Generate Token.
  4. Copy the install command shown - it already has the token embedded, and the token is shown in full only at this step.

Enrollment tokens are organization-scoped and single-use in the sense that they’re tied to the agent record created when you generate them - don’t share one across organizations, and treat it like any other credential.

The supported path is the install script, run as root on the target host:

Terminal window
curl -fsSL https://storage.googleapis.com/sencai-agent-downloads/latest/install.sh \
| SENCAI_GATEWAY_URL=https://fleet.sencai.space:4400 \
SENCAI_TOKEN=<your-token> \
SENCAI_GATEWAY_FINGERPRINT=<sha256-fingerprint> bash

Use the exact command shown in Fleet → Agents - it already contains the gateway address, your token and the gateway certificate fingerprint. This downloads the agent binary, verifies its checksum, installs a systemd unit, enrolls the host, and starts the service - you don’t need to run any further commands.

Check that the service is running:

Terminal window
sudo systemctl status sencai-agent

If you already have the agent binary - for example, deploying it through your own configuration management rather than the install script - the same steps happen as two separate commands:

Terminal window
sencai-agent enroll --gateway https://fleet.sencai.space:4400 --token <your-token>
sencai-agent start

enroll also accepts --gateway-fingerprint <sha256> (preferred) or --insecure-tofu (explicit opt-in, no certificate verification at all) - one of the two is required. start normally runs under the systemd unit the install script sets up; running it directly is mainly useful for testing.

Back in Fleet → Agents, the new host shows up shortly after its first successful heartbeat, initially as pending, then active once it’s reporting normally. If it doesn’t appear within a couple of minutes, see the troubleshooting table below.

On the host itself, you can check the agent’s own view of things:

Terminal window
sencai-agent status

This prints the agent’s ID, which gateway it’s connected to, its granted capabilities, and its certificate’s expiry and reachability - useful for confirming the agent thinks it’s healthy even if the app hasn’t shown it yet.

Running enroll again with a fresh token replaces the existing configuration and certificate - useful if you need to move an agent to a different organization, or if its certificate needs replacing. There’s no separate “re-enroll” flow; it’s the same command with a new token.

Re-enrolling gives the agent a new certificate, so a host that was trusted for secret delivery has to be trusted again.

Delivering environment variable and file secrets to a host (see Secret injections) stays off until someone with root on that host turns it on. The agent reads its secret delivery policy from a file of its own, which it never writes, and nothing sent from Sencai changes it. Sencai therefore can’t enable delivery on a host for you, and removing the file or setting enabled: false stops the next delivery.

  1. Upgrade the agent to a release that supports secret delivery - see Agent releases for rolling a version out with Force Update.

  2. Write the policy file, secret-delivery.yaml, for example:

    # /etc/sencai-agent/secret-delivery.yaml - read by the agent, never written by it
    enabled: true # default false
    file_path_prefixes: # omitted: /run/sencai-secrets/ only; []: no file targets
    - /run/sencai-secrets/
    env_units: [] # services that may receive environment variables
    try_restart_units: [] # services Sencai may restart; each must match env_units
    cleanup_on_revoke: true # omitted: true

    Install it owned by root and not writable by group or others:

    Terminal window
    sudo install -m 0600 -o root -g root secret-delivery.yaml /etc/sencai-agent/secret-delivery.yaml

    The agent picks up a change within a minute, without a restart. The app shows it after the agent’s next report, within about five minutes.

  3. Grant the Secret Delivery capability on Fleet → Agents: select the host, click Grant Capability and choose Secret Delivery. Only an Owner or Admin can grant it, and it can’t be included when you generate an enrollment token.

  4. Trust the host from its secret delivery details on Fleet → Agents - see Trusting a host.

The agent refuses the whole file, and keeps delivery off, if the file isn’t owned by root, is writable by group or others, is a symbolic link, is larger than 16 KiB, or contains a setting it doesn’t recognize. Fleet → Agents then shows Config error for the host, with the reason in its secret delivery details.

Rules for the settings:

  • file_path_prefixes - absolute directories, each ending in /. A file target must be below one of them. Up to 20, with no duplicates and no prefix inside another.
  • Locations that are never allowed, whatever the file says: system directories such as /bin/, /boot/, /dev/, /lib/, /proc/, /root/, /sbin/, /sys/ and /usr/; authentication, cron, PAM, SSH, sudo and systemd configuration under /etc/; and the agent’s own directories. A prefix that is one of these, sits inside one, or contains one is refused, so broad prefixes such as /etc/, /run/ or /var/lib/ are refused too.
  • Read-only locations - the agent’s systemd unit keeps /etc, /usr and /boot read-only to the agent, so a prefix there is refused. Use a location such as /run/sencai-secrets/, /var/lib/<app>/ or /srv/<app>/.
  • env_units - the systemd services that may receive environment variables, such as myapp.service, or myapp@.service to allow every instance of a template. Up to 50. Core services are never allowed, including sshd.service, cron.service, dbus.service, polkit.service, the agent’s own sencai-agent.service, and any unit whose name starts with systemd-, getty@, serial-getty@ or user@.
  • try_restart_units - the services the agent may restart after it delivers or removes a variable, and only when the injection asks for a restart. Each must also match env_units.
  • cleanup_on_revoke - whether the agent removes what it delivered when it’s disconnected; see Uninstalling. On unless set to false.
  1. In Fleet → Agents, find the host and click Disconnect - this revokes the agent’s credentials and removes it from your organization’s fleet view.
  2. On the host itself:
Terminal window
sudo systemctl disable --now sencai-agent
sudo rm -f /usr/local/bin/sencai-agent
sudo rm -rf /etc/sencai-agent

Disconnecting from the app is the important step - an agent that’s stopped locally but never disconnected still shows up as disconnected/stale in your fleet view rather than disappearing.

Secret values already delivered to the host

Section titled “Secret values already delivered to the host”

Disconnecting an agent doesn’t always remove the secret values Sencai delivered to its host:

  • If the agent is connected when you click Disconnect and cleanup_on_revoke is on, it removes the files it delivered and the environment variables it set - including its environment files under /run/sencai-agent/env/ and their drop-ins - within about a minute, before it wipes its own configuration.
  • If the agent is offline at that moment, it never learns that it was disconnected and can’t reconnect afterwards, so everything it delivered stays on the host. Remove those files, environment files and 50-sencai-agent-secrets.conf drop-ins yourself. /etc/sencai-agent/secret-deliveries.json lists what the agent delivered - paths, services and variable names, never the values - so read it before you remove /etc/sencai-agent.
  • Deleting an agent’s record removes nothing from the host.

The Disconnect confirmation tells you how many delivered secrets are on the host. The host’s injections then show Host disconnected; close them to delete the stored values from Sencai Vault.

Symptom Likely cause What to do
Installer exits immediately with a missing-variable error SENCAI_GATEWAY_URL or SENCAI_TOKEN not set Re-run with both set; copy the exact command from Fleet → Agents rather than retyping it
“gateway certificate fingerprint mismatch” The SENCAI_GATEWAY_FINGERPRINT value doesn’t match Get the correct fingerprint from whoever issued the token - don’t guess or drop the flag to work around it
Connect timeout while “enrolling with gateway” The host’s public IP is not on the fleet gateway allowlist (or an outbound firewall blocks TCP 4400) Ask Sencai to admit the host’s public egress IP; check that outbound TCP 4400 is open
“enroll failed: gateway returned …” The token is expired, already used, or invalid Generate a new token from Fleet → Agents
Service is active (running) but the host never appears in the app Outbound connectivity to the gateway is blocked, or the token belonged to a different organization Check outbound firewall/proxy rules for the host; confirm you’re looking at the organization the token was generated for
sencai-agent status/start says “not enrolled” Configuration is missing or corrupted Re-run enroll with a fresh token
Secret Delivery shows Off on host The policy file doesn’t exist, or doesn’t set enabled: true Write it as described in Enabling secret delivery on a host
Secret Delivery shows Config error The agent refused /etc/sencai-agent/secret-delivery.yaml Open the host’s secret delivery details for the reason, then fix the file on the host - no restart needed
  • Fleet agent - what the agent does once it’s connected
  • Agent policies - autonomy levels, freeze windows, secret injections and custom probes (capabilities are granted on Fleet → Agents)
  • Monitoring - reading telemetry from your connected agents
  • Kubernetes clusters - the separate enrollment path for a cluster