Gardience Documentation gardience.com →
Docs / Clients

Enrollment tokens

An enrollment is a time-limited pass that lets new agents join the fleet without someone approving each key. Each enrollment has a secret token, which Gardience puts into the enrollment playbook. Agents installed by that playbook present the token, and the Salt master accepts them while the enrollment is open. Once it expires or is closed, new agents go back to waiting for approval under Machines > Add machines.

Only admins can create, list, download and close enrollments.

How it works

  1. An admin creates an enrollment. Gardience makes a random token that starts with enr-.
  2. Gardience writes every open token to a file the Salt master reads (config/autosign/gardience_enroll in the install folder). The master uses Salt's autosign_grains feature with this file.
  3. The playbook gives each agent the token as a local grain named gardience_enroll, and configures the agent to send that grain when it first asks to join.
  4. The master compares the grain with the file and accepts the agent's key if the token is open.
  5. At the next scan, Gardience removes the token grain from accepted agents, so it does not stay readable on the machine.

Gardience rewrites the token file whenever an enrollment is created or closed, and every 60 seconds. A closed enrollment stops working at once. An expired one stops within a minute of its expiry time.

Create an enrollment

To create one in the console:

  1. Open Machines > Add machines.
  2. Under Bring your Ansible inventory, fill in:

    • Label: a name that says what the enrollment is for. The default is "Ansible inventory".
    • Groups (optional): node groups every machine that joins with it belongs to, separated by commas.
    • Open for: 4 hours, 24 hours (the default), 3 days, 7 days, or 30 or 90 days for pipelines that build machines all the time (Terraform, golden images).
  3. Select Create enrollment. The browser downloads gardience-enroll.yml.

Then either run the playbook as described in Enroll Linux machines or Enroll Windows machines, or use a first-boot script (below) for machines you are about to create.

First-boot scripts for new machines

For machines that do not exist yet, each open enrollment also offers a Linux script and a Windows script in the list below the form. Put one in the machine's first-boot user data (cloud-init, AWS or Azure user_data, a golden image's first-run step) and the machine joins on its own when it starts:

The Linux script is POSIX sh and runs as root. The Windows script is PowerShell and runs as Administrator; on AWS, wrap it in <powershell></powershell>. A machine's name in Gardience is its host name, unless the script sets one: the API and the Terraform provider can make a script per machine with its own name and extra groups. See Terraform.

Machines that join with an enrollment's groups appear in those groups at once, and an event rule of the join kind can configure them the moment they arrive. See Drift checks and event rules.

See and close enrollments

The same panel lists the 20 most recent enrollments with their label, who created them, when they close (in UTC) and their state:

StateMeaning
openAgents with this token join without approval. You can download the playbook again or close it.
expiredThe open time has passed.
revokedSomeone closed it early.

To close an open enrollment early, select Close now. New agents with that token then wait for approval. Agents that already joined stay in the fleet.

The playbook can only be downloaded while its enrollment is open. For an expired or closed one, create a new enrollment.

Creating and closing enrollments are written to the audit log (enroll.created and enroll.revoked).

From a script

The console uses these endpoints, which you can call with a session token from a sign-in. Your account must have the admin role.

# sign in and keep the session token
TOKEN=$(curl -s https://gardience.example.com/login \
  -H 'Content-Type: application/json' -H 'Accept: application/json' \
  -d '{"username":"alice","password":"...","eauth":"file"}' | python3 -c 'import sys,json;print(json.load(sys.stdin)["return"][0]["token"])')

# create an enrollment open for 8 hours; the reply is {"id": "..."}
curl -s https://gardience.example.com/gardience/api/enroll -H "X-Auth-Token: $TOKEN" \
  -H 'Content-Type: application/json' -d '{"label":"Branch office","hours":8}'

# download its playbook
curl -s "https://gardience.example.com/gardience/api/enroll/playbook?id=ID" -H "X-Auth-Token: $TOKEN" -o gardience-enroll.yml

# list enrollments, then close one
curl -s https://gardience.example.com/gardience/api/enroll -H "X-Auth-Token: $TOKEN"
curl -s https://gardience.example.com/gardience/api/enroll/revoke -H "X-Auth-Token: $TOKEN" \
  -H 'Content-Type: application/json' -d '{"id":"ID"}'

While the server still uses its self-signed certificate, pass --cacert with a copy of config/tls/gardience.crt from the install folder.

Through these endpoints, hours can be any whole number from 1 to 2160 (90 days). The default is 24. Labels are cut to 80 characters. groups is an optional list of group names.

For automation, prefer a configure API key and the REST endpoints under /gardience/api/v1/enrollments, which also return first-boot scripts. See API keys and the REST API and Terraform.

Keep tokens safe

In attach mode

Enrollment works only if your own Salt master reads the token file. On the master, set autosign_grains_dir: /etc/salt/autosign_grains and share the Gardience file config/autosign/gardience_enroll into that folder. See Attach to an existing Salt master.

Gardience by Bouziden Management LLC.