Authentication

Beta
View as Markdown
Early access

The CLI generator is in early access. Reach out to get started.

Each generated CLI reads authentication credentials from the security schemes declared in your OpenAPI spec. Credentials can come from environment variables, CLI flags, files, or a combination of these through fallback chains.

Without a credential, the CLI still works — you can explore the command tree, view help, and use --dry-run.

Credential sources

The CLI supports several ways to supply credentials, configured at build time.

SourceDescription
Environment variableRead from an env var (the most common option).
CLI flagAuto-registered as a --<flag-name> global flag.
FileRead trimmed contents from a file path (~ is expanded).
LiteralBaked into the binary at compile time.
Fallback chainTry multiple sources in order; first non-empty value wins.

A typical fallback chain lets the CLI flag override the env var, which in turn overrides a file:

$# CLI flag takes priority
$box users get-current-user --api-token sk-123
$
$# Otherwise falls back to the environment variable
$export BOX_API_KEY=sk-123
$box users get-current-user
$
$# Otherwise reads from a file
$echo "sk-123" > ~/.box/token
$box users get-current-user

Supported auth schemes

The CLI supports every scheme type that OpenAPI’s securitySchemes defines:

SchemeHow the CLI applies it
Bearer (http: bearer)Sends Authorization: Bearer <token>.
API key (apiKey)Sends the key in the configured header (for example, X-Auth-Token).
Basic (http: basic)Sends Authorization: Basic <base64(user:pass)>. Each field has its own credential source.
OAuth 2Sends Authorization: Bearer <token>. Declare an OAuth flow to have the CLI obtain and refresh the token itself.

OAuth flows

Declaring an oauth scheme under auth-schemes in generators.yml makes the CLI acquire tokens on its own instead of reading a pre-issued token from the environment. Three flows are supported through the type field:

FlowtypeUse case
Client credentialsclient-credentialsMachine-to-machine. The CLI exchanges a client ID and secret from environment variables for a token, configured with the same auth-schemes fields the SDKs use.
Authorization code with Proof Key for Code Exchange (PKCE)authorization-codeInteractive login. The CLI opens a browser and receives the callback on a loopback listener.
Device codedevice-codeInteractive login on machines without a browser, such as SSH sessions and containers.

The interactive flows are public-client only: they use PKCE rather than a client secret. They require CLI generator 0.29.0 or later.

Log in and out

Every generated CLI exposes an auth command group:

$my-cli auth login # run the declared flow and store the token
$my-cli auth status # show each scheme and whether a credential is present
$my-cli auth logout # remove the stored credential

Tokens are stored in the OS keyring, refreshed automatically when they expire, and sent as Authorization: Bearer <token> on every request. Pass --no-browser to auth login to print the authorization URL instead of opening a browser, and --with-token to skip the flow and read a token from stdin.

Authorization code with PKCE

generators.yml
1auth-schemes:
2 OAuth:
3 scheme: oauth
4 type: authorization-code
5 client-id: my-public-client-id
6 authorization-url: https://idp.example.com/authorize
7 token-url: https://idp.example.com/oauth/token
8 refresh-url: https://idp.example.com/oauth/token
9 scopes:
10 - plants:read
11 - plants:write

Omitting redirect-uri binds an OS-assigned loopback port at login (recommended, no port registration needed). To pin a port, set redirect-uri to a loopback URL, and list ports to add fallbacks tried in order when the primary port is busy:

generators.yml
1 redirect-uri:
2 url: http://127.0.0.1:8484/callback
3 ports: [8485, 8486]

The host must be 127.0.0.1 or localhost over http, the port is required, and the path is arbitrary. Register every redirect URI the CLI can produce, including each backup port, with the authorization server.

Device code

generators.yml
1auth-schemes:
2 OAuth:
3 scheme: oauth
4 type: device-code
5 client-id: my-public-client-id
6 device-authorization-url: https://idp.example.com/oauth/device/code
7 token-url: https://idp.example.com/oauth/token

auth login prints a user code and verification URL, then polls the token endpoint until the user approves. redirect-uri and pkce are rejected for this flow.

Extra request parameters

Authorization servers that require additional literal parameters, such as an Auth0 audience, accept them through per-request maps.

generators.yml
1 authorization-parameters:
2 audience: https://api.example.com
3 token-parameters:
4 audience: https://api.example.com
5 refresh-parameters:
6 audience: https://api.example.com

The device-code flow uses device-authorization-parameters in place of authorization-parameters.

Auth strategies

When a spec declares multiple security schemes, the CLI composes them according to one of these strategies:

StrategyBehavior
AutoDefault. Infers the right composition from the spec’s security blocks.
AnyThe API accepts any one of the declared schemes. The first scheme with a credential wins.
AllThe API requires every scheme simultaneously (for example, HMAC signature plus API key).
RoutingPer-operation dispatch. Each endpoint’s security block determines which schemes to use.

Operations that declare security: [] (an empty list) opt out of authentication entirely — no credentials are sent regardless of what’s configured.

Configure the any strategy

When an API accepts more than one credential under the any strategy, the CLI authenticates with whichever source is populated, using the first scheme that has a credential. Declaring the schemes requires two steps:

  1. In your OpenAPI spec, define the schemes under securitySchemes and list them as multiple auth schemes in the security array.

    openapi.yml
    1components:
    2 securitySchemes:
    3 # ...BearerAuth and TokenAuth defined here
    4security:
    5 - BearerAuth: []
    6 - TokenAuth: []
  2. In generators.yml, define the same schemes under auth-schemes and compose them with api.auth set to any.

    generators.yml
    1auth-schemes:
    2 # ...BearerAuth and TokenAuth defined here, each with its env var
    3api:
    4 auth:
    5 any: [BearerAuth, TokenAuth]

The scheme names must match across both files.

A scheme that’s missing from the spec is ignored without warning, even when its environment variable is set. With both declared, set either variable and the command runs:

$# Authenticate with MY_API_KEY
$export MY_API_KEY=sk-123
$my-cli users list
$
$# Or authenticate with MY_TOKEN instead
$export MY_TOKEN=tok-456
$my-cli users list

Help output

Every generated CLI includes a dynamically rendered Authentication: section in its --help output listing every scheme, the expected env var or flag, and whether a credential is detected.