> ## Documentation Index
> Fetch the complete documentation index at: https://docs.heylua.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Credentials

> User sessions, legacy and scoped API keys, and device credentials — what each can do, how the CLI picks one, and which scope each area needs

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 user@example.com` sends a one-time code to that address; `lua auth configure --email user@example.com --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](/concepts/organizations-and-roles) (`viewer`, `operator`, `builder`, `admin`, `owner`, or `billing-admin`, each a fixed list of scopes); it is issued from a user session over the REST API, shows its secret once, and takes an optional expiry. Two rules bound it: it never does more than its owner can at that moment, and it loses access to an organization when the owner does.&#x20;

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. The [devices](/concepts/devices) pages cover provisioning.

## 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 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](/reference/rest/overview#scopes).

| Scope                                                                                      | What it covers                                                                                       | Typical use                                                                                                       |
| ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `agents:read`, `agents:write`, `agents:manage`                                             | Agent configuration, persona versions, agent versions, source backups                                | `lua push agent`, `lua version create` and `promote`, `lua push backup`; `agents:manage` deletes versions         |
| `automations:read`, `automations:write`                                                    | Skills, webhooks, jobs, triggers, processors, MCP servers, devices, marketplace publishing           | `lua push`, `lua deploy`, `lua webhooks`, `lua jobs`, `lua triggers`, `lua mcp`, `lua devices`, `lua marketplace` |
| `api-keys:issue` (sensitive)                                                               | Rotating a trigger token                                                                             | `lua triggers rotate-token`                                                                                       |
| `workflows:read`, `workflows:write`, `workflows:execute`                                   | Workflow definitions and runs                                                                        | `lua workflows list`, `lua push workflow`, `lua workflows deploy`, `lua workflows start` and `approve`            |
| `workflows:read-outputs`                                                                   | Step inputs and outputs, artifacts, journal payloads, run exports; `workflows:read` alone hides them | Reading run payloads over REST                                                                                    |
| `knowledge:read`, `knowledge:write`                                                        | User data, `Data` collections, environment variables, knowledge resources                            | `User` and `Data` over REST, `lua env production`, `lua resources`                                                |
| `channels:read`, `channels:manage`, `channels:send`                                        | Listing and linking channels; sending messages                                                       | `lua channels`, `Channels.send`, the channels REST family                                                         |
| `telephony:read`, `telephony:write`, `telephony:manage`, `telephony:provision` (sensitive) | Phone numbers, voices, SIP trunks, carrier registration                                              | `lua voice`, number purchase and binding, 10DLC and toll-free registration                                        |
| `commerce:read`, `commerce:write`                                                          | Products, baskets, orders                                                                            | `Products`, `Baskets`, `Orders` over REST                                                                         |
| `integrations:read`, `integrations:write`, `integrations:manage`                           | Connected integrations and their event subscriptions                                                 | `lua integrations`                                                                                                |
| `analytics:read`, `analytics:write`                                                        | Evaluations and QA runs                                                                              | `lua evals`, QA from the dashboard                                                                                |
| `marketplace:read`                                                                         | Templates and install requests                                                                       | `lua marketplace template install` and `status`                                                                   |
| `org:read`, `org:manage`                                                                   | Organization listing and settings                                                                    | `lua agents`, `lua chat clear --user`                                                                             |
| `secrets:write` (sensitive)                                                                | Organization-level provider keys                                                                     | Dashboard only                                                                                                    |
| `members:*`, `billing:*`                                                                   | People and payment; `members:assign-role` and `billing:manage` are sensitive                         | Dashboard only                                                                                                    |

`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](/concepts/environments) 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.

## 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

<Columns cols={2}>
  <Card title="Install and sign in" href="/get-started/install">Create your first user session.</Card>
  <Card title="Automate releases in CI" href="/ship/ci-and-automation">Use a scoped key with `--ci` and exit codes.</Card>
  <Card title="lua auth" href="/reference/cli/auth">Configure, sessions, logout, and key.</Card>
  <Card title="REST API overview" href="/reference/rest/overview">Bearer authentication and the error envelope.</Card>
</Columns>
