Ephemeral Machines

Auto-enroll short-lived machines at scale with enrollment tokens. Perfect for CI runners, autoscaling groups, and ephemeral containers.

An ephemeral machine is a registered machine with a built-in expiration timestamp. When the timestamp passes, the machine is disabled automatically and its identity stops authenticating. Ephemeral machines exist for workloads that come and go too quickly to approve by hand: CI runners, autoscaling fleets, short-lived containers, preview environments.

You create ephemeral machines by issuing an enrollment token. Unlike a bootstrap token, which registers a single machine and requires a human to approve it, an enrollment token is a reusable policy template. One token can enroll up to 10,000 machines, each with the same project memberships, secret grants, and lifetime.

Enrollment tokens are available on Pro and Enterprise plans.

How It Differs From Bootstrap

BehaviourBootstrap TokenEnrollment Token
UsesSingle-useMulti-use (up to 10,000)
ApprovalRequired per machineAuto-approved on enrollment
Machine lifetimePermanent until revokedFixed TTL, auto-disabled at expiry
Projects and secretsConfigured after approvalBaked into the token
Best forLong-lived serversCI runners, autoscaling, containers

Both paths end with an Ed25519 keypair on the machine and the public key stored in SikkerKey. The authentication model is identical. What changes is the lifecycle around it.

How It Works

  1. You create an enrollment token from the dashboard, specifying the projects, secrets, token lifetime, machine lifetime, and max uses
  2. SikkerKey returns a one-time token value and a curl-ready enrollment URL
  3. You embed the enrollment command in your CI configuration, container image, autoscaling launch script, or orchestration template
  4. Each time the command runs, the machine generates its own Ed25519 keypair, sends the public key to SikkerKey, and receives a machine identity scoped to the projects and secrets configured on the token
  5. The machine authenticates with that identity for the duration of its machine lifetime
  6. When the machine lifetime passes, SikkerKey disables the machine automatically. After 30 days of retention, the row is permanently deleted.

The token value itself has two lifetimes: it stops accepting new enrollments after its token lifetime, and it runs out of slots when max uses is reached. Whichever happens first ends the token.

Creating a Token

Navigate to Enrollment Tokens in the dashboard sidebar under the Machines section and click the + button.

1. Identity

  • Name: a human-readable label for the token (e.g. "production-ci"). Shown in the dashboard list and audit log.
  • Description (optional): free-text notes about what the token is for.

2. Access

  • Projects: the projects each enrolled machine joins. At least one is required.
  • Secrets (optional): the specific secrets each enrolled machine can read. If left blank, machines get project membership with no secret grants, which is useful if you intend to grant secrets separately later.

Secrets are scoped to the selected projects. If you deselect a project, its secrets drop from the selection automatically.

3. Lifetime

  • Token lifetime: how long this token accepts new enrollments. Minimum 5 minutes, maximum 90 days.
  • Machine lifetime: how long each enrolled machine authenticates before being auto-disabled. Minimum 1 minute, maximum 90 days.
  • Max enrollments: the number of machines this token can produce. 1 to 10,000.

The two lifetimes serve different purposes. Token lifetime limits your exposure if the token value leaks. Machine lifetime limits the blast radius of any individual enrolled machine if its private key is stolen.

4. Advanced Restrictions (optional)

  • Source CIDR: a network range. Only machines connecting from inside this CIDR can enroll.
  • Hostname pattern: a regular expression the machine's hostname must match (e.g. ^ci-runner-[0-9]+$). Evaluated with a 100ms timeout to prevent ReDoS attacks; patterns that don't match within the timeout are rejected.
  • Name pattern: a template for auto-assigning machine names. Supports {uuid} (8 random characters) and {uuidN} where N is between 4 and 32 (e.g. ci-{uuid8} produces ci-k3f2hd9a).

These restrictions apply on top of SikkerKey's standard checks (vault owner active, IP allowlist if configured, plan machine limit).

5. Save

On save, the dashboard shows the token value and the enrollment commands once. This is the only time the plaintext is ever displayed. Copy it immediately or copy the full curl command. Losing it means revoking the token and creating a new one.

Using the Token

The creation modal gives you two ready-to-run commands.

Linux / macOS:

curl -sSL https://api.sikkerkey.com/v1/VAULT_ID/enroll/TOKEN | sh

Windows (PowerShell):

irm https://api.sikkerkey.com/v1/VAULT_ID/enroll/TOKEN/ps | iex

The vault ID in the URL is a second factor. A leaked token value alone is not usable without knowing which vault it belongs to.

What the Enrollment Script Does

  1. Checks that openssl and curl are installed
  2. Generates an Ed25519 keypair locally using openssl genpkey -algorithm Ed25519
  3. Extracts the raw 32-byte public key
  4. Reads the machine's hostname via hostname -s (or $env:COMPUTERNAME on Windows)
  5. POSTs the token, public key, and hostname to /v1/VAULT_ID/enroll/register
  6. Writes identity.json and private.pem to ~/.sikkerkey/vaults/VAULT_ID/
  7. Sets directory permissions to owner-only (chmod 700 and chmod 600 on POSIX)

The private key never leaves the machine. Only the public key is transmitted during enrollment.

If an identity already exists for this vault on the machine, the script replaces it. The old machine ID is invalidated immediately.

After Enrollment

The machine is approved automatically with its projects and secrets already applied. There is nothing to do in the dashboard. You can start reading secrets right away:

val sk = SikkerKey()
val dbPassword = sk.getSecret("sk_db_production")

The SDK reads the identity file the enrollment script wrote and signs requests with the private key.

Token Status

A token has four possible states, shown as a pill in the list and detail panel:

StatusMeaning
activeToken has remaining uses, has not expired, and has not been revoked
exhaustedToken has reached its max uses
expiredToken's lifetime has passed (no more enrollments accepted)
revokedToken was manually revoked

Exhausted, expired, and revoked tokens cannot enroll new machines. Machines already enrolled through the token continue to operate until their own machine lifetime expires. Changing the token's state does not retroactively kill the machines it produced.

Machine Lifecycle

Every machine enrolled through a token has a non-null expiresAt timestamp equal to enrollmentTime + machineLifetime.

Active phase

From enrollment until expiresAt, the machine authenticates like any other machine. It shows an ephemeral badge on the Machines page alongside its normal status.

Soft-expire

Once expiresAt passes, a background job disables the machine on its next sweep (within one minute). Authentication is refused. The row stays in the database so the audit trail remains intact. An audit entry machine_expire is recorded.

Hard-delete (30-day retention)

30 days after expiresAt, the machine row and its grants are permanently deleted. An audit entry machine_purge is recorded per vault owner, listing the names of the removed machines. The identity file on disk (if the machine still exists) becomes inert.

Non-ephemeral machines (those registered via bootstrap) are never touched by this process.

Revocation

Open a token in the detail panel and click Revoke Token to stop it immediately. You can optionally include a reason (recorded in the audit log).

Revocation is immediate and irreversible. The token will never accept another enrollment. Existing machines continue to operate until their individual machine lifetime expires. If you need to cut those off too, revoke the machines directly from the Machines page.

Use revocation when:

  • The token value may have leaked (e.g. committed to a repo by mistake)
  • The pipeline using it is retired
  • A scheduled rotation requires a clean cutover to a fresh token

Security Model

Every enrollment attempt runs through these checks, in order:

  1. Request validation: the vault ID and token format must match expected patterns; malformed requests are rejected before any database lookup
  2. Vault exists and is active: suspended or unverified vaults return 404 with no further information
  3. IP allowlist: if the vault owner has IP allowlisting enabled, the source IP must be on the list
  4. Token exists and belongs to this vault: the token hash is looked up scoped to the vault owner, so a token valid in another vault cannot enroll here
  5. Not revoked: revoked tokens are rejected with an audit entry enrollment_token_denied
  6. Not expired: expired tokens are rejected with an audit entry enrollment_token_denied
  7. Source CIDR: if configured, the machine's source IP must fall inside it
  8. Hostname pattern: if configured, the machine's hostname must match the regex within 100ms (ReDoS-safe)
  9. Projects and secrets still exist: if a project or secret referenced by the token has been deleted, enrollment fails with 409 rather than enrolling a partially-configured machine
  10. Plan machine limit: the vault owner's subscription must allow another machine; plan-limit failures do not consume a token slot
  11. Atomic slot claim: usesRemaining is decremented in a single SQL update guarded by usesRemaining > 0, so concurrent enrollments cannot over-consume
  12. Insertion: the machine row, project memberships, and secret grants are written inside the same transaction. If any step fails, the entire transaction rolls back and the slot is restored.

The token plaintext is hashed with SHA-256 before storage. SikkerKey never stores the raw token value.

Rate Limiting

Enrollment requests are rate-limited by source IP to 30 per hour per IP. This protects the endpoint from token-brute-forcing and enrollment flooding. Legitimate fleets rolling out dozens of machines from different IPs are not affected.

Plan Availability

PlanEphemeral Machines
FreeNot available
ProAvailable, plan-specific machine limit
EnterpriseAvailable, higher machine limit

Free plan users can see the Enrollment Tokens page in the dashboard but cannot create tokens. Attempting to open the create modal shows an upgrade prompt.

Each enrolled machine counts toward your overall plan machine limit. An enrollment is rejected with 402 Payment Required if accepting it would exceed the limit, and the token slot is not consumed.

Audit Trail

All enrollment activity is recorded in the audit log:

ActionWhen it fires
enrollment_token_createToken was created
enrollment_token_revokeToken was manually revoked
enrollment_token_expireToken's lifetime passed (fired once per token, idempotent)
enrollment_token_deniedAn enrollment attempt was blocked (revoked, expired, CIDR mismatch, hostname mismatch, plan limit)
machine_enrollA machine successfully enrolled via a token
machine_expireAn ephemeral machine's lifetime passed and it was disabled
machine_purgeAn ephemeral machine was hard-deleted after the 30-day retention period

You can subscribe to email alerts or webhooks for any of these under Settings > Alerts in the dashboard.