TL;DR: CLI authentication to enterprise SSO works best when teams choose between OAuth Device Code and PKCE based on runtime context, not convenience, according to WorkOS. The broader lesson is that headless and local environments need different identity patterns, and refresh-token storage becomes the control point that matters most.
At a glance
What this is: This is a tutorial on adding enterprise SSO to a CLI with OAuth Device Code and PKCE, with the main finding that flow choice should follow runtime context.
Why it matters: It matters because CLI auth is still identity architecture, and practitioners need patterns that work across local laptops, remote shells, containers, and enterprise SSO policies without weakening token handling.
By the numbers:
- A 0600 file is portable, has no native dependencies, and works in containers, WSL, and CI runners that do not have a keyring service running.
- AWS CLI v2 writes SSO tokens as 0600-permissioned JSON files in ~/.aws/sso/cache/.
👉 Read WorkOS's tutorial on adding enterprise SSO to a CLI
Context
Enterprise CLI sign-in is a governance problem, not just a developer convenience problem. Once a command-line tool has to pass an SSO review, static API keys stop being a credible answer because they cannot express browser-mediated enterprise identity controls such as MFA, conditional access, or IdP routing.
The practical choice is between two browser-delegated OAuth patterns. Device Code fits headless and remote contexts, while PKCE fits local machines with a browser and a loopback callback, which means the access model should follow execution environment rather than a one-size-fits-all authentication design.
Key questions
Q: How should security teams choose between Device Code and PKCE for CLI sign-in?
A: Use PKCE when the user has a local browser and the CLI can bind to a loopback redirect. Use Device Code when the environment is headless, remote, or browserless. The deciding factor is not preference but whether the runtime can preserve a browser-tied authorization path without adding unnecessary phishing or polling exposure.
Q: Why do CLI refresh tokens need stronger protection than access tokens?
A: Refresh tokens matter more because they last longer and can mint new access tokens after the short-lived access token expires. If the refresh token is exposed, the attacker can keep re-establishing the session. Teams should therefore protect refresh-token storage with the same seriousness they apply to other durable credentials, including rotation and revocation.
Q: What breaks when a CLI relies on a single login flow for every environment?
A: A single flow usually fails either in headless environments, where loopback browser redirection is unavailable, or on local machines, where Device Code adds a manual transfer step and a polling window. The result is brittle authentication that pushes teams toward weaker workarounds such as static keys or unnecessary exceptions.
Q: Who is accountable for CLI session security when tokens are stored locally?
A: The application team is accountable for the storage model, expiry handling, and revocation path, while the identity team is accountable for enforcing the enterprise authentication policy behind the flow. In practice, that means CLI design has to align with access governance rather than being treated as a standalone developer convenience.
Technical breakdown
Device Code flow in CLI authentication
The Device Code flow splits the secret and public parts of sign-in. The CLI requests a device code and shows the user code and verification URL, while the authorization happens in a browser on any device. The CLI then polls the token endpoint until the user approves or the code expires. That polling loop is defined by RFC 8628 and includes backoff handling such as slow_down responses. The key security characteristic is that the user manually transfers trust into a browser session, which makes the flow workable for SSH, containers, and other headless contexts.
Practical implication: use Device Code only where a local browser callback is not available, and treat the polling endpoint as part of your token-risk surface.
PKCE for local browser-based CLI sign-in
PKCE protects public clients by binding the authorization code exchange to a verifier that only the initiating client can prove. In a CLI, the tool creates a code_verifier and code_challenge, opens a browser to the authorization endpoint, and listens on a loopback server for the redirect back with the code. The browser session and the callback are tied together, which closes the phishing gap that exists when a user must type a code by hand. Because the authorization code is redeemed synchronously, there is no polling loop and no need to wait on the IdP between requests.
Practical implication: default to PKCE for local CLI logins and reserve Device Code for environments where loopback redirect is impossible.
Refresh token storage and session renewal in CLI tools
A CLI does not have a persistent web session, so token renewal becomes a storage and expiry problem. Access tokens are typically short-lived, but refresh tokens are the durable asset and the real target if storage is weak. Teams usually choose between a permission-restricted file and an OS keychain, each with trade-offs between portability, dependency management, and local protection. Because refresh tokens may rotate on use, the stored value must be replaced every time the token endpoint returns a new pair.
Practical implication: protect refresh tokens as the primary asset, and make token replacement on refresh an explicit part of the CLI state model.
NHI Mgmt Group analysis
CLI SSO is now an identity governance problem, not a developer ergonomics problem. The article shows that terminal-based tools must inherit enterprise SSO controls rather than bypass them with static secrets. That matters because the security review question is no longer whether the CLI can authenticate, but whether it can participate in the organisation's existing identity policy stack. For practitioners, the right lens is whether the command-line workload can be brought under the same governance model as web and internal apps.
Device Code exposes a user-code transfer trust window that policy teams often underestimate. The flow depends on a human moving from terminal to browser and back again, which creates a different abuse path than browser-bound authorisation. That does not make the flow unsafe by default, but it does mean the approval step is no longer anchored to a single device session. For IAM teams, this is a reminder that user interaction itself becomes part of the security boundary when terminal auth is delegated outside the client process.
PKCE is the more defensible default for local CLI sign-in because it preserves browser-session binding. The authorization code is not useful until the same client proves possession of the verifier, which is exactly the property public clients need. This is a better fit for local developer laptops, where loopback redirect is available and enterprise controls such as MFA and conditional access can still be inherited. The implication is that CLIs should be designed around environment-aware auth selection, not a single universal login path.
Refresh-token handling is the real lifecycle control in CLI identity, not the initial login flow. Once the CLI has tokens, operational risk shifts to how refresh tokens are stored, rotated, and invalidated across sessions. A permissioned file may be practical, but the governance question is whether the stored session can be protected and revoked cleanly across containers, laptops, and shared systems. Practitioners should treat token persistence as a lifecycle domain, not a code snippet detail.
CLI identity should be treated as workload identity with human delegation, not as a special-case authentication shortcut. The article's architecture joins browser SSO, public-client OAuth, and local token persistence into one identity path. That combination shows why human IAM, workload access, and secrets handling increasingly overlap in developer tooling. The practitioner takeaway is to govern the CLI as a first-class identity surface with explicit policy, not as an informal wrapper around API access.
From our research:
- Only 1.5 out of 10 organisations are highly confident in their ability to secure NHIs, compared to nearly 1 in 4 for securing human identities, according to the State of Non-Human Identity Security.
- 85% of organisations lack full visibility into third-party vendors connected via OAuth apps, with 38% reporting no or low visibility and 47% reporting only partial visibility.
- The next governance step is to compare CLI auth patterns with the Guide to the Secret Sprawl Challenge, especially where refresh-token storage resembles broader secret lifecycle risk.
What this signals
CLI authentication is converging with workload identity governance. As developer tools move into enterprise SSO, the control question shifts from whether a command can log in to how its tokens are issued, stored, and revoked across laptop, container, and remote-shell environments. That is why the operational boundary between human sign-in and non-human session management is getting thinner.
The 85% third-party OAuth visibility gap from our research on NHI security is a useful warning signal here, because CLI auth can create the same kind of hidden delegated access if teams do not inventory where tokens live and who can reuse them. Practitioners should expect audit pressure on token persistence, not just on initial authentication.
A practical concept emerging from this pattern is delegated terminal identity: a CLI that inherits human SSO but persists machine-readable tokens across sessions. That model is manageable, but only if refresh-token lifecycle, revocation, and storage location are treated as first-class governance controls rather than implementation detail.
For practitioners
- Default CLI sign-in to PKCE where a browser callback exists Use the loopback redirect pattern for local developer machines and keep Device Code only for SSH, containers, and other headless environments where callback handling is impossible.
- Treat refresh tokens as the durable credential asset Store them in a permission-restricted location or OS keychain, and replace the stored value whenever the refresh response rotates the token pair.
- Keep the device code secret out of user-facing output Show only the user code and verification URL, because the device_code is the private half of the pair and should never be displayed in the terminal.
- Document explicit environment-based auth selection Make the CLI choose PKCE for local machines and Device Code for remote or browserless contexts so developers do not need to guess which flow applies.
Key takeaways
- CLI SSO design is an identity architecture decision, and the right flow depends on whether the runtime can support a browser callback.
- Refresh tokens are the durable risk object in command-line auth, so storage and rotation matter more than the initial login ceremony.
- Teams that want enterprise-ready CLI auth should design for environment-aware flow selection, strong token hygiene, and explicit revocation paths.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 address the attack and risk surface, while NIST Zero Trust (SP 800-207) and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-03 | Refresh-token handling and secret storage are central to this CLI auth pattern. |
| NIST Zero Trust (SP 800-207) | The article applies continuous trust checks through browser-mediated auth and token renewal. | |
| NIST CSF 2.0 | PR.AC-4 | The CLI inherits enterprise identity policy through SSO and token controls. |
Map CLI authentication to access-control policy and require revocation paths for stored tokens.
Key terms
- Device Code Flow: A browser-delegated OAuth pattern for devices or tools that cannot complete a normal redirect locally. The client shows a user code and polls for completion while the user signs in elsewhere, which makes it useful in headless environments but introduces a manual approval step and a polling window.
- Pkce: A proof-binding OAuth extension for public clients that prevents an intercepted authorization code from being reused by another party. In CLI contexts, it ties the browser session to the same client that started the flow, which makes it the stronger choice when loopback redirect is available.
- Refresh Token: A long-lived credential that lets a client obtain new access tokens after the original access token expires. For command-line tools, it is the most sensitive stored artifact because it can silently extend a session, so it needs stronger storage, rotation, and revocation handling than short-lived access tokens.
Deepen your knowledge
NHI governance, agentic AI identity, and machine identity lifecycle are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are responsible for identity security strategy or identity programme maturity, it is worth exploring.
This post draws on content published by WorkOS: How to add enterprise SSO to your CLI. Read the original.
Published by the NHIMG editorial team on 2026-05-08.
NHI Mgmt Group — the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org