Credential Resolver
Every cmdop connect call (and every connecttool agent operation)
needs a credential to reach the relay. There is exactly one source for
that credential: the OAuth access token you obtain by running
cmdop login.
This page covers how that single source is resolved, what happens when no credential is available, and how to fix a “not signed in” error.
The resolution
workspace.Resolver.ResolveCtx() (in
internal/connect/workspace/resolve.go) is short by design — there is
no chain of flags, env vars, or config files to walk:
- An already-resolved token passed by the caller. Some internal
call sites (for example the agent-to-agent
remoteagentfunnel) already hold a token and hand it in directly. This is an internal override, not a user-facing flag or env var. - OAuth access token from
cmdop login(AuthMgr.GetAccessToken). This is the source for everything you do from the CLI.
If neither yields a credential, the resolver returns “no source” and
the caller decides whether to treat that as an error — for cmdop connect it surfaces as a “run cmdop login” prompt.
Sources are tagged with a Source constant so the result can record
where the credential came from:
const (
SourceOAuth Source = "oauth" // resolved from cmdop login
SourceNone Source = "none" // nothing available
)There is no --api-key flag, no CMDOP_API_KEY environment
variable, no named-fleet credential file (ssh_workspaces.json), and
no legacy cfg.Chat.GrpcAPIKey path. Earlier builds had a multi-source
resolver chain; it was removed. OAuth via cmdop login is the only way
to authenticate the CLI today.
Why OAuth-only
Collapsing to a single OAuth source removes the surprise of a stale key on disk silently winning over the identity you just signed in with. Short-lived OAuth tokens (with refresh) also expire on their own — there is no long-lived API key to leak from a config file or CI env.
Getting authenticated
cmdop login # browser device flow, stores the OAuth token
cmdop connect --list # uses the stored token automaticallyThe token is stored in the OS keyring (macOS Keychain, Linux Secret
Service, Windows Credential Manager), with an encrypted-file fallback on
headless hosts. Every later cmdop connect call resolves it
transparently.
When no credential is available
If you run a connect command without signing in, the resolver returns the “no source” tag and the CLI rewrites the server error into an actionable remedy:
auth_error: not signed in — run `cmdop login`friendlyAuthError (in cmd/cmdop/cmds/connect/connect_auth.go) is the
helper that turns a generic unauthenticated from the relay into this
guidance.
What the resolver does not do
- It does not fetch tokens from the server.
cmdop logindoes that, on demand, and stores the result. - It does not validate the token. An expired token resolves cleanly,
carries to the relay, and fails there with
unauthenticated— at which point the auth manager attempts a refresh. - It does not care which machine you are targeting. The OAuth token gates the relay; per-machine identity is enforced separately.
Server override
A call can carry an optional gRPC Server address override (used by
on-prem deployments and test environments). When set, the resolver
returns it alongside the token and the dial uses that endpoint instead
of the default cloud relay. Most users never touch this.