Skip to main content

Token Caching

Tokens are stored in the operating system keyring, not in config.toml.

PlatformStore
macOSKeychain
WindowsCredential Manager
LinuxSecret Service-compatible keyring

On Windows the token is split across several Credential Manager entries. Credential Manager caps a single credential at 2560 bytes and a Microsoft Graph token bundle is routinely larger — the access token alone can exceed it — so the CLI writes a <profile>:token header holding the chunk count and <profile>:token:0, <profile>:token:1 and so on holding the bytes. Seeing several entries per profile is expected; teams auth logout removes all of them. macOS and Linux keep a single item per profile.

Token size is a property of the tenant's consent grant rather than of the scopes the CLI asks for, so requesting fewer scopes does not reliably shrink it.

File token store​

Some processes cannot use the keyring. A daemon on macOS cannot answer the Keychain prompt, and macOS asks again for every new or upgraded binary, so an unattended process waits on a dialog nobody sees. A Linux server or container often has no Secret Service at all. For these, set TEAMS_CLI_TOKEN_STORE=file and sign in once with it set:

export TEAMS_CLI_TOKEN_STORE=file
teams auth login --device-code

Tokens then live in files under the config directory's tokens/: one file per profile (<profile>.token), plus profile-index. On Unix the directory is 0700 and each file 0600. Each write goes to a temporary file that is flushed to disk and renamed into place, so a reader never sees a partial token.

  • The files hold the refresh token unencrypted, protected only by file permissions. Prefer the keyring wherever a process can use it; on Windows the file store relies on the profile directory's ACL. A token file readable by other users draws a warning on stderr.
  • The two stores do not share sessions. After switching, run teams auth login again.
  • keyring (the default, also accepted as keychain) and file are the only values. Anything else is refused before the command runs, with INVALID_INPUT and exit code 2.
  • Keep the tokens/ directory out of backups, images and support bundles.

Access tokens are refreshed automatically when the stored token is expired or close to expiry and a refresh token is available.

Use auth refresh when you need to pick up newly consented scopes without a browser prompt:

teams auth refresh
teams auth refresh --scopes "User.Read People.Read Files.Read.All offline_access"

Scope selection for an explicit refresh is intentionally non-destructive:

  • --scopes or TEAMS_CLI_SCOPES wins when supplied.
  • Otherwise, a scopes value on the selected profile is requested.
  • If neither is configured, auth refresh reuses the stored token's granted scopes instead of falling back to the built-in defaults and potentially narrowing the session.

The CLI adds offline_access to delegated scope overrides automatically.

If refresh fails because the token is too old, revoked, or was created without offline_access, sign in again with teams auth login --device-code.

Use teams auth logout or teams auth logout --all to remove stored credentials.

TEAMS_CLI_ACCESS_TOKEN bypasses the keyring for one process and cannot be refreshed by the CLI. It must contain a Microsoft Graph access token. Captured Teams client tokens, including fossteams/teams-token JWT files, are not compatible with Graph commands.