The CLI needs a valid license to run, and it can obtain one on its own from two different credentials: an API key or a device token from a browser sign-in. This page explains which one belongs where, and what happens when a machine has both.
Which credential for which machine
| Situation | Use | Why |
|---|---|---|
| Developer workstation, laptop | codecharter login |
No secret to copy around, revocable per machine from the portal |
| CI runner, build agent, container | API key as CODECHARTER_API_KEY |
Unattended, no browser, one secret shared by every job in the pipeline |
| Air-gapped or offline machine | Downloaded license file | Validates offline until it expires |
The short version: a browser sign-in identifies a person on one machine, an API key identifies a pipeline. A device token belongs to the developer who approved it and can be revoked without touching anybody else. An API key is a shared, long-lived secret that outlives individual jobs, which is exactly what a runner needs and exactly what you do not want lying on a laptop.
An API key can do more than a device token, which is the other reason not to mix
them up. A key carries read:rules and optionally write:rules, so it can read
your rules and profiles and, if granted, push drafts. A device token can only
renew a license, nothing else, see
Browser sign-in.
Which credential renews the license
When the CLI needs a fresh license it resolves the credential in this order:
- The
CODECHARTER_API_KEYenvironment variable, if it is set and not empty. - The device token stored by
codecharter login, if this machine is signed in.
The first match wins. If neither is present, the CLI does not renew and falls back to whatever license file it can find; without a valid one it exits with exit code 6.
Why the environment variable wins
This order is deliberate. A CI job that sets CODECHARTER_API_KEY on a machine a
developer once signed in on must use the CI credential, not silently borrow that
developer's identity. Setting the variable is an explicit, per-invocation
decision; a stored device token is ambient state from some earlier day. The
explicit choice therefore wins.
The practical consequence is that you never have to sign out before running a CI job locally, and a self-hosted runner on a shared machine cannot accidentally produce license activity under a colleague's account.
To check which credential is actually in effect on a machine, run:
codecharter auth status
Where the license file fits in
Credential resolution and license lookup are two separate steps. Before renewing anything, the CLI looks for a usable license file, and if it finds one with more than an hour of validity left it uses it and never touches a credential at all. The full search path is described under License file.
Two of those entries are pins that renewal never overwrites: a path passed via
--license and the CODECHARTER_LICENSE environment variable. Use them to
force a specific file, for example on a machine that must stay on an offline
license.
Which credential authenticates a portal call
Some commands talk to the portal for something other than a license: update,
restore, push, rules search, and verify --against-portal. They resolve the
credential for that call in the same order:
- An explicitly passed
--api-key, where the command offers the option (update,push,rules search,verify --against-portal). - The
CODECHARTER_API_KEYenvironment variable, if it is set and not empty. - The installed license, as a short-lived JWS.
The environment variable outranks the license for the same reason it outranks a stored device token during renewal: setting it is an explicit decision for this invocation, while a license file is ambient state from an earlier day and may belong to a different account. A profile owned by your organization is only visible to that organization, so a call made under the wrong identity does not merely look odd, it fails outright with a "not found" error.
Passing --api-key to one of those commands still does not change which
credential renews your license; that is decided by the order above.
Signing out and revoking
Removing a credential and disabling it are different actions:
| Goal | Do this |
|---|---|
| Stop using the device token on this machine | codecharter logout |
| Lock a machine out for good | Revoke the device on /api-keys, see Authorized devices |
| Disable a CI key | Revoke the key on /api-keys, see Managing API keys |
Revocation takes effect for renewals immediately. A license that was already issued keeps working until it expires, which is at most 24 hours.
Rules of thumb
- Never put an API key on a developer machine if a browser sign-in will do. A key on a laptop is a shared secret in an unmanaged place.
- Never use a browser sign-in for CI. It needs a browser and ties your pipeline to one person's account.
- One key per pipeline, so you can revoke one without stopping the others.
- Sign in per machine. Copying
codecharter.device-tokento a second machine is pointless: both then share one entry in the portal and you lose the ability to revoke them individually.