Skip to main content
A credential is what proves to Lua who is calling. Lua has three kinds: a user session, an API key, and a device credential, because a developer at a terminal, a CI job, and a device on a factory floor need different lifetimes and different ways to be revoked.

How the CLI authenticates

lua auth configure --email [email protected] sends a one-time code to that address; lua auth configure --email [email protected] --otp <code> turns it into a user session stored on this machine. A user session renews itself, carries your current access, and is per device: lua auth sessions lists every device and app signed in as you, lua auth sessions revoke <id> signs one out, and lua auth logout --all signs out everywhere. Signing out of the admin dashboard, desktop, or mobile app ends CLI sessions too; the next command reports Your Lua CLI session was signed out. An API key is for anything that can’t answer a code: CI, a script, a server calling the REST API. lua auth configure --api-key <key> stores one in place of any user session on the machine. A legacy key acts as its owner with the owner’s full permissions in every organization the owner belongs to. A scoped key, api_<id>.<secret>, is a personal key whose grants each name one organization or agent and carry one role (viewer, operator, builder, admin, owner, or billing-admin, each a fixed list of scopes); it is issued in the admin dashboard or from a user session over the REST API, shows its secret once, and takes an optional expiry. In the dashboard, open Admin › API Keys and select Create scoped key: name the key, add one grant per organization (Entire organization) or agent with a role no higher than your own on it (billing-admin is not offered on a key), and set an expiry or leave it empty. The same page lists and revokes legacy keys but no longer creates them, and the CLI issues no keys. Two rules bound a scoped key: it never does more than its owner can at that moment, and it loses access to an organization when the owner does. The CLI resolves a credential in a fixed order on every command: LUA_API_KEY in the environment (a .env in the project counts), then the stored user session, then the stored API key. lua status --json reports the one in use as auth.source: environment, renewable session, or stored. With none, the CLI exits with code 9 and No Lua CLI authentication found. Run lua auth configure or set LUA_API_KEY. A device credential is bound to one agent, one device name, and the operations that device performs (commands, triggers, uploads). Device clients use it to connect; it is not accepted for ordinary API calls. Issue one from an email sign-in with lua devices credential; see Create a device credential. The device gateway refuses scoped personal API keys.

What a scoped key cannot do

A scoped key links the CLI to an agent that already exists; it can’t create one. lua init --agent-name … and lua init --from-agent-id … refuse with exit code 10 and Scoped CLI credentials cannot create a new agent (or … cannot duplicate an agent); create or duplicate the agent with a user session, or create it in the dashboard, then run lua init --agent-id <id>. A scoped key also can’t list, issue, rotate, suspend, or revoke credentials, including its own. Any other request outside the key’s role is answered with 403 (CLI exit code 10); an invalid, expired, suspended, or revoked key gets 401 (exit code 9).

Which scope an area needs

Scopes are named <area>:<action>. A key holding a wildcard such as automations:* covers every action in that area except the sensitive ones marked in the table, which must be granted by exact name; the full sensitive list is on the REST API overview. agents:write is the release scope and more: lua push agent changes the served persona, model, model settings, batching, and governance at once, with no promote. lua version create needs it twice over, because the source backup a version records is written under agents:write and read under agents:read. A write scope never implies its read scope, so a key that pushes and promotes needs agents:read and automations:read as well.

Credentials and environment variables

A credential is yours: it says who is calling Lua. An environment variable is the agent’s: a secret your code reads at run time to call someone else. Never put a Lua API key in the agent’s environment, and never read the agent’s environment to authenticate the CLI. A custom MCP server added from the Tools page or the admin dashboard brings a third kind: the server’s own credentials, held by the platform rather than in the agent’s environment. Its address, header values, and OAuth tokens are encrypted at rest and write-only once saved, so neither the agent’s code nor the CLI can read them; the address counts as one of them because some servers put a token in it. A saved browser login is a fourth kind, and it belongs to one end user rather than to you or to the agent: their own account on one website, so the browser can sign in as them. The agent asks for one on a live chat turn with Secrets.request({ kind: 'browser-login', name, origins }); Lua sends that person a private link, they type their username and password on a Lua page, and they choose how much the agent may do with it. The value never passes through the agent’s code, its tools, its environment or its logs, and the person can remove the login at any time.

When to use which

  • Developing at a terminal: a user session.
  • CI, a deploy script, or a server calling the REST API: a scoped key with the narrowest role, scoped to one agent where possible, with an expiry when the use has an end date.
  • One key per system that calls Lua, so a compromise means revoking one thing.
  • Hardware and local machines: a device credential, never a personal key.

Limits

  • A scoped key’s effective scopes are capped at what its owner holds on each resource.
  • lua auth configure --api-key clears the stored user session and --email sign-in deletes the stored key; only one is stored at a time, and LUA_API_KEY beats both.
  • Scoped keys need lua-cli 3.28.0 or later; older versions are refused by the server.

Next steps

Install and sign in

Create your first user session.

Automate releases in CI

Use a scoped key with --ci and exit codes.

lua auth

Configure, sessions, logout, and key.

REST API overview

Bearer authentication and the error envelope.