Licensing Software That Runs on Ephemeral CI and Cloud Build Agents Without Burning Seats
Node-locked licensing assumes stable machines. CI runners and autoscaled agents are born and destroyed constantly, so each run looks like a new machine and burns a seat. Here is how to license ephemeral compute without exhausting your seat count.
Licensing models were mostly designed for machines that stay put — a desktop, a server, a workstation. CI and cloud build agents violate that assumption on purpose: they exist for the duration of one job and then vanish, and the next job gets a brand-new VM or container. Point a node-locked license at that environment and it does exactly the wrong thing — every build looks like a new machine, activates, consumes a seat, and then the machine is destroyed without ever releasing it. A ten-seat license can be exhausted before lunch. The fix is not a bigger seat count; it is licensing the dimension that actually varies.
Why ephemeral breaks node-locking
Node-locking derives a fingerprint from a machine’s hardware and binds the license to it, so a seat represents a distinct device. That is exactly right for desktops and exactly wrong for ephemeral compute, where “distinct device” is a meaningless unit — there is a new one every few minutes, none of them lasts, and the thing you actually want to limit is not how many machines but how much concurrent (or total) use.
Worse, the cleanup assumption fails too. Node-locked seats are normally freed by an explicit deactivation when a user moves machines. A CI runner is not deactivated; it is deleted. So its seat lingers until something reclaims it, and in a busy pipeline seats are consumed far faster than any manual process frees them.
Three models that fit ephemeral compute
Pick by what you actually mean to limit.
Floating / concurrency. License the number of simultaneous uses, not machines. A pool of N concurrent leases means at most N builds run at once; a finished (or destroyed) runner’s lease is reclaimed and the next build takes it. This is the natural fit when parallelism is what you are selling — see floating concurrent licenses. Pair it with heartbeat lease reaping so a runner that vanishes without deactivating has its lease freed after a short timeout rather than lingering.
Build-scoped entitlement. If you only need to gate the feature in CI (prove the customer is licensed, without counting machines), validate a signed entitlement with a token that does not consume a seat at all. The build checks the entitlement offline and runs; nothing is node-locked.
Metered builds. If the fair unit is total runs, meter them — count builds as usage against a quota, with an idempotency key so a retried build does not double-count.
Detecting CI and taking the right path
The implementation hinge is letting your software know it is in CI so it takes the ephemeral path instead of the desktop one:
static bool IsCi() =>
Environment.GetEnvironmentVariable("CI") is "true" or "1"
|| Environment.GetEnvironmentVariable("GITHUB_ACTIONS") == "true"
|| Environment.GetEnvironmentVariable("GITLAB_CI") == "true"
|| Environment.GetEnvironmentVariable("TF_BUILD") == "true" // Azure Pipelines
|| Environment.GetEnvironmentVariable("JENKINS_URL") is not null;
// In CI, validate against a concurrency/entitlement path — not a node-locked activation.
var result = IsCi()
? keyright.ValidateFloating() // or a build-scoped entitlement check
: keyright.Activate(); // normal desktop node-lock
The desktop experience is unchanged; the CI path simply validates the dimension that makes sense there and never writes a per-machine activation that would strand a seat.
Doing this with Keyright
Keyright supports all three models — floating concurrency with heartbeat reaping, build-scoped entitlements validated without consuming a seat, and metered build counting — so you can license ephemeral CI and autoscaled agents by concurrency or usage instead of by machine, and never watch a pipeline exhaust your seats. Each path validates offline against a signed payload, so a runner with restricted egress still works. Keyright is self-hosted, so your entitlements and usage data stay on infrastructure you control.
See the plans, or start from floating concurrent licenses and add CI detection to route runners onto it.
Try Nebula.NET
Harden your .NET code in minutes — start with the free edition.