Skip to main content
Security on Lua is a set of mechanisms you can observe with the CLI or in the product: where credentials are stored, how secrets reach agent code, what is scrubbed from logs, what agent code can reach, who can change production, and what is retained. This page names each mechanism so an evaluator can verify it; anything that needs a contractual statement is marked open.

Mechanisms you can verify

Credentials on your machine

lua auth configure --email creates a user session: a renewable sign-in stored under ~/.lua-cli/sessions/ with file mode 0600 inside a 0700 directory. Signing out of the admin dashboard, desktop, or mobile app also ends CLI sessions; lua auth logout revokes the session on the server and deletes the local file. An API key saved with lua auth configure --api-key is stored at ~/.lua-cli/credentials, also mode 0600. A command resolves its credential in this order: LUA_API_KEY in the environment or .env, then a stored user session, then the credentials file. lua auth sessions lists your sessions; see About credentials.

API key classes

A legacy key carries its owner’s full access. A scoped key has the form api_<uuid>.<secret> and carries named scopes, such as agents:read, workflows:execute, or knowledge:write; the REST API checks the scope on each protected route, so a key minted for CI with agents:write and automations:write cannot list end-user conversations (conversations:read) or read environment variables and Data (knowledge:read). Chat routes check no scope: any valid credential can talk to the agent as its own end user. A device credential has the same form, is issued for one agent, one device name, and a set of operations, and is the only credential a device client needs.

Secrets in the agent environment

Secrets are stored per environment with lua env production -k <KEY> -v <value> and read in code with env('KEY'); the runtime injects the environment into each invocation, and lua env production --list prints keys with masked values. Local runs read .env, which lua env sandbox writes. Nothing else holds secrets: MCP server headers and URLs resolve through env() at request time, governance in API mode reads GOVERNANCE_API_KEY, and integration credentials stay on the platform, so Integrations.passthrough calls the provider for you and your code never sees a token. The one exception is a webhook’s signing secret, a string literal in source, which travels with every source backup and with your repository.

Secret scrubbing in logs

Three redactions apply, each to its own surface. Workflow and job records (step failures, provider errors, job output, run events) pass through a scrubber that replaces recognizable credential shapes (well-known provider tokens, JWTs (signed sign-in tokens), private-key blocks, tokens inside git URLs) and any name=value pair whose name ends in a secret-like word (Authorization, x-api-key, *_KEY, *_TOKEN, password) with [REDACTED]; workflow signal payload keys such as token and api_key are stored redacted. The runtime’s own log lines redact bearer headers, credential query parameters, and JWTs. Passthrough errors have the connection’s credential removed. Nothing redacts what your code prints: console.log output is stored as written, up to 256 KB per field, so never log a secret.

What agent code can reach

Tools, webhooks, jobs, processors, and workflow code steps run in a sandbox created per invocation; module-level state does not persist between calls. Outbound HTTP is allowed. Requests from workflow code steps to private network ranges (private, link-local, carrier-grade NAT, and cloud metadata addresses) are refused with the error code EGRESS_DENIED. The optional browser feature takes an allowedDomains list that limits where a browser session may navigate. See About execution contexts.

Production change control

lua push uploads a version and changes nothing for end users, except that a pushed persona is served at once. lua version create snapshots every primitive’s version into a numbered agent version, and lua version promote <n> makes that snapshot live in one step; promoting an earlier number is the rollback. lua version list --json shows which version is active, who created each version (createdBy), and when it was promoted (promotedAt); nothing records who promoted it, but with lua git connect every promote is also an audit commit in your repository. lua sync --check reports drift between the server and your source, and lua source list keeps the history of pushed source. The Claude Code plugin adds a gate for AI-assisted work: production-affecting commands are denied unless you confirm once. See Releasing.

Human approval for consequential actions

Two mechanisms put a person in the path. Governance requireToolApproval pauses a tool call in a conversation until someone approves. A workflow approval step pauses a run with an approver rule (the run’s creator, organization admins, named members, a role, or a group), an optional four-eyes rule (a second person decides; the one who started the run can’t), and a timeout with escalation; approvals are answered in the desktop app or with lua workflows approve.

Telemetry

The CLI sends usage events to an analytics service: the command, whether it succeeded, its duration, the first 200 characters of any error, the operating system, Node and CLI versions, and the organization and agent IDs, keyed by a hash of the API key or a random machine identifier. lua telemetry off or LUA_TELEMETRY=false turns it off; lua telemetry status shows the setting. lua evals opens the evaluations dashboard with your API key in the URL query string; treat that browser history entry as a credential.

Retention

Workflow run records are kept for 90 days by default; an organization administrator can shorten the window to as few as 7 days. Trigger executions are kept for 90 days.

Security controls and compliance statements

Everything in the previous section is a mechanism: a file mode, a scope check, a redaction, a command that refuses. A compliance statement (a certification, a data-processing agreement, a residency commitment, an uptime figure) is a contractual claim that documentation cannot verify from behavior, so this page makes none. Not stated in these docs, because no verifiable mechanism was found for them:
  • Encryption at rest for environment variables and stored data.
  • Data residency.
  • Retention for conversations, execution logs, channel deliveries, and voice transcripts.
  • What the model providers do with the data they receive.
  • Audit-log export.
  • Rate limits on chat, channel, data, and commerce routes (REST API overview).

When to use it

  • Automating from CI: mint a scoped key with only the scopes the job needs and pass it as LUA_API_KEY.
  • A tool must never run, or must be confirmed by a person: use governance rules.
  • A multi-step workflow touches money or customer data: put an approval step in it.
  • Answering a vendor questionnaire: cite the mechanisms here and put the “Not stated” list to Lua as questions.

Limits

Next steps

About credentials

User sessions, legacy and scoped keys, device credentials, and the scope table.

About governance

Block or gate tool calls and scan for prompt injection.

Releasing

Push, snapshot, promote, and roll back.

About execution contexts

What each kind of code can see and how long it may run.