feat(cli): add 'coder login token' command to print session token (#21627)

Adds a new subcommand to print the current session token for use in
scripts and automation, similar to `gh auth token`.

## Usage

```bash
CODER_SESSION_TOKEN=$(coder login token)
```

Fixes #21515
This commit is contained in:
Kacper Sawicki
2026-01-29 16:06:17 +01:00
committed by GitHub
parent 9a417df940
commit d09300eadf
9 changed files with 123 additions and 0 deletions
+29
View File
@@ -462,9 +462,38 @@ func (r *RootCmd) login() *serpent.Command {
Value: serpent.BoolOf(&useTokenForSession),
},
}
cmd.Children = []*serpent.Command{
r.loginToken(),
}
return cmd
}
func (r *RootCmd) loginToken() *serpent.Command {
return &serpent.Command{
Use: "token",
Short: "Print the current session token",
Long: "Print the session token for use in scripts and automation.",
Middleware: serpent.RequireNArgs(0),
Handler: func(inv *serpent.Invocation) error {
tok, err := r.ensureTokenBackend().Read(r.clientURL)
if err != nil {
if xerrors.Is(err, os.ErrNotExist) {
return xerrors.New("no session token found - run 'coder login' first")
}
if xerrors.Is(err, sessionstore.ErrNotImplemented) {
return errKeyringNotSupported
}
return xerrors.Errorf("read session token: %w", err)
}
if tok == "" {
return xerrors.New("no session token found - run 'coder login' first")
}
_, err = fmt.Fprintln(inv.Stdout, tok)
return err
},
}
}
// isWSL determines if coder-cli is running within Windows Subsystem for Linux
func isWSL() (bool, error) {
if runtime.GOOS == goosDarwin || runtime.GOOS == goosWindows {
+28
View File
@@ -537,3 +537,31 @@ func TestLogin(t *testing.T) {
require.Equal(t, selected, first.OrganizationID.String())
})
}
func TestLoginToken(t *testing.T) {
t.Parallel()
t.Run("PrintsToken", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, nil)
coderdtest.CreateFirstUser(t, client)
inv, root := clitest.New(t, "login", "token", "--url", client.URL.String())
clitest.SetupConfig(t, client, root)
pty := ptytest.New(t).Attach(inv)
ctx := testutil.Context(t, testutil.WaitShort)
err := inv.WithContext(ctx).Run()
require.NoError(t, err)
pty.ExpectMatch(client.SessionToken())
})
t.Run("NoTokenStored", func(t *testing.T) {
t.Parallel()
inv, _ := clitest.New(t, "login", "token")
ctx := testutil.Context(t, testutil.WaitShort)
err := inv.WithContext(ctx).Run()
require.Error(t, err)
require.Contains(t, err.Error(), "no session token found")
})
}
+3
View File
@@ -9,6 +9,9 @@ USAGE:
macOS and Windows and a plain text file on Linux. Use the --use-keyring flag
or CODER_USE_KEYRING environment variable to change the storage mechanism.
SUBCOMMANDS:
token Print the current session token
OPTIONS:
--first-user-email string, $CODER_FIRST_USER_EMAIL
Specifies an email address to use if creating the first user for the
+11
View File
@@ -0,0 +1,11 @@
coder v0.0.0-devel
USAGE:
coder login token
Print the current session token
Print the session token for use in scripts and automation.
———
Run `coder --help` for a list of global options.
+15
View File
@@ -9,6 +9,21 @@ The [Coder CLI](../../install/cli.md) and
token to authenticate. To generate a short-lived session token on behalf of your
account, visit the following URL: `https://coder.example.com/cli-auth`
### Retrieve the current session token
If you're already logged in with the CLI, you can retrieve your current session
token for use in scripts and automation:
```sh
coder login token
```
This is useful for passing your session token to other tools:
```sh
export CODER_SESSION_TOKEN=$(coder login token)
```
### Session Durations
By default, sessions last 24 hours and are automatically refreshed. You can
+10
View File
@@ -22,6 +22,16 @@ Instead of distributing provider-specific API keys (OpenAI/Anthropic keys) to us
Again, the exact environment variable or setting naming may differ from tool to tool; consult your tool's documentation.
### Retrieving your session token
If you're logged in with the Coder CLI, you can retrieve your current session
token using [`coder login token`](../../reference/cli/login_token.md):
```sh
export ANTHROPIC_API_KEY=$(coder login token)
export ANTHROPIC_BASE_URL="https://coder.example.com/api/v2/aibridge/anthropic"
```
## Configuring In-Workspace Tools
AI coding tools running inside a Coder workspace, such as IDE extensions, can be configured to use AI Bridge.
+5
View File
@@ -1487,6 +1487,11 @@
"description": "Authenticate with Coder deployment",
"path": "reference/cli/login.md"
},
{
"title": "login token",
"description": "Print the current session token",
"path": "reference/cli/login_token.md"
},
{
"title": "logout",
"description": "Unauthenticate your local session",
+6
View File
@@ -15,6 +15,12 @@ coder login [flags] [<url>]
By default, the session token is stored in the operating system keyring on macOS and Windows and a plain text file on Linux. Use the --use-keyring flag or CODER_USE_KEYRING environment variable to change the storage mechanism.
```
## Subcommands
| Name | Purpose |
|----------------------------------------|---------------------------------|
| [<code>token</code>](./login_token.md) | Print the current session token |
## Options
### --first-user-email
+16
View File
@@ -0,0 +1,16 @@
<!-- DO NOT EDIT | GENERATED CONTENT -->
# login token
Print the current session token
## Usage
```console
coder login token
```
## Description
```console
Print the session token for use in scripts and automation.
```