Licensing for CLI tools
Sell a paid command-line tool in any language. A key in an env var or config file, activate on first run, validate on each run, and per-seat limits so one key does not license a whole team.
Start FreeFor the solo builder shipping a paid CLI in Go, Python, or Rust, installed on laptops and CI machines both.
- One customer's key ends up in a shared dotfiles repo and runs on the whole team.
- A CLI has no UI to paste a key into, so licensing has to fit an env var and a config file.
- Your tool is written in a language with no first-party licensing SDK.
Updated September 2026
A paid CLI is the simplest product to ship and one of the easiest to lose money on. There is no UI, so the key goes in a config file. Config files get committed, shared, and copied onto CI runners. One customer’s key quietly becomes a team license. This page is the narrow case: you ship a binary, people install it on laptops and build machines, and you want to get paid once per seat.
Where the key lives
Treat the license key like any other credential the tool reads. An environment variable for CI, a line in the config file for laptops, and the env var wins when both are set. Customers already know this pattern from every other tool they use, and it means there is nothing new to explain.
Activate on first run, validate on each run
The first time the tool sees a key, it activates. That registers the machine against the key and consumes one seat. Every run after that validates. Validate is cheap, it is the moment a refund or a revocation lands, and the result is not something to cache. The server owns expiry and entitlements, so every check should be a real check.
Per-seat limits
Every key carries an activation limit. A personal key allows two or three machines. A third activation from the same key is refused and the tool prints a clear message: this key is at its seat limit, free one in the portal or upgrade. That is the whole defense against the shared dotfiles repo, and it needs no work on your side beyond picking the number per tier.
Customers free a seat themselves in the hosted customer portal, so a replaced laptop is not a support ticket. The device activations page covers the model.
Any language, one honest rule
Keylight has SDKs for Swift, Rust, JavaScript, C#, and C++. A CLI in Go or Python goes through the API path: activate and validate are two HTTPS calls, authenticated with a runtime token.
The rule is that the runtime token never ships inside the binary. It can activate and validate any key on your account, so a token in a downloadable tool is a token you have already leaked. Put it behind a small endpoint you host. The tool sends the key and a machine identifier to your endpoint, your endpoint calls Keylight with the token, and the answer comes back. Fifty lines in any language, and the secret stays on infrastructure you control.
The API path is online-first. There is no lease to verify locally, so there is no offline mode. For a tool that runs on CI and connected laptops that is the right trade, because a revoked key is caught on the very next run. If the tool must work with no network at all, write it in Rust and use the crate, which verifies a signed lease on the machine. Licensing for Rust Apps covers that path.
Where to start
Two steps.
- Read License Your App With No SDK: The Keylight API Path. It shows activate and validate with curl, then the same two calls in Python and Go.
- Run
keylight init --mode apiin the project that will hold the token. It mints a token scoped to activate and validate only, writes it to.env, and prints a copy-ready first call.
Keylight plans start at $19/month on the pricing page. The free tier supports up to 25 licenses, enough to license your own machines and a CI runner and see the seat limit refuse a third one.
Frequently asked
How does a customer enter a key in a CLI?+
The same way they enter any credential: an environment variable or a line in the tool's config file. The tool reads it, activates on first run, and validates on every run after that.
How do I stop one key from running on a whole team?+
Every key carries an activation limit. A personal key might allow two machines. When a third one tries, activation is refused and the customer frees a seat in the portal or buys a team tier.
My CLI is in Go or Python. Is there an SDK?+
Not a first-party one today. Those tools call the Keylight API through a small endpoint you host, which holds the runtime token. The tool itself never carries the secret.
Does the API path work offline?+
No. Every check is a live read, which is the right trade for a tool that runs on CI and connected laptops. If the tool must work with no network, a Rust CLI can use the crate and verify a signed lease locally.
Start licensing your app today
Drop in the Swift SDK, point it at your dashboard, and sell paid apps in under a minute. Free forever tier included.
Start Free