Skip to content

Mass provisioning

Per-agent tokens are one-shot — one click in the dashboard yields one token good for one registration. That doesn’t scale when Terraform or an autoscaling group spins up 20 or 100 VMs in parallel. You want a single secret that all hosts may use, with a built-in counter and an expiry.

An enrolment token (prefix enrl_) is a multi-use secret with:

  • max_uses — hard ceiling on the number of registrations
  • expires_at — TTL between 1 hour and 30 days
  • default_tags + default_role — auto-applied to every agent it registers
  • allowed_cidrs (optional) — source-IP allowlist for extra hardening
  • revoked_at — instant kill switch from the dashboard

The hub stores only the SHA-256; the raw token is shown once and from then on only lives in your secret store.

  1. Dashboard → Settings → Enrolment tokens
  2. Name: e.g. production-cluster-eu-west
  3. TTL: 72 h, max uses: 50, default tags: prod,eu-west,web, role: web
  4. (Optional) Allowed CIDRs: e.g. 10.0.0.0/8 if hosts sit inside the VPC
  5. Create — copy the enrl_… token immediately
#cloud-config
runcmd:
- bash -c '
export MONSYS_TOKEN="enrl_xxxxx"
export MONSYS_TAGS="$(curl -fsS http://169.254.169.254/latest/meta-data/placement/availability-zone)"
curl -fsSL https://get.monsys.ai/install.sh | sudo -E bash
'

The installer detects the enrl_ prefix, calls POST /api/v1/agents/enrol on the hub, and gets a fresh per-agent token (agt_…) back. That token is written to /etc/monsys/agent.toml. The enrolment token is never persisted on the host — from then on the agent uses only its own one-shot token.

module "monsys" {
source = "git::https://github.com/gotrust/monsys.git//agent/packaging/terraform"
monsys_token = var.monsys_enrolment_token # from Vault / SOPS
tags = ["shard-${count.index}"]
role = "web"
}
resource "aws_instance" "web" {
count = 50
ami = "ami-..."
instance_type = "t4g.small"
user_data = module.monsys.cloud_init
}

50 instances, one secret. Every host comes up with its own agt_… token plus tags prod,eu-west,web,shard-N.

- name: install monsys agent
hosts: all
become: true
vars:
monsys_token: "{{ lookup('hashi_vault', 'secret/monsys/enrolment') }}"
tasks:
- shell: |
export MONSYS_TOKEN="{{ monsys_token }}"
export MONSYS_TAGS="{{ group_names | join(',') }}"
export MONSYS_ROLE="{{ ansible_role | default('') }}"
curl -fsSL https://get.monsys.ai/install.sh | bash
args:
creates: /etc/monsys/agent.toml

Token default_tags come first; tags passed via MONSYS_TAGS or the Terraform tags variable are appended (deduplicated). Same for role: the token default wins unless the installer is given an explicit MONSYS_ROLE.

Every registration is recorded in enrolment_uses with:

  • token id
  • new agent id
  • source IP
  • timestamp

When 100 agents appear in 5 minutes you can see immediately in the enrolment-tokens list which token authorised them, and you can revoke it in one click if there’s a suspicious host in the batch.

All cases below return 401 — deliberately indistinguishable to deny an attacker useful signal:

  • token doesn’t exist (wrong hash)
  • token expired (expires_at passed)
  • token revoked
  • max_uses reached
  • source IP outside allowed_cidrs

Operator feedback comes from the dashboard (uses counter, expiry, status).

Tokens don’t renew themselves — you mint a new one and revoke the old when the batch is done. Registered agents keep working; only new registrations through that token are blocked.