pub enum AuthOp {
Import {
provider: Option<ImportProvider>,
dir: Option<String>,
all: bool,
if_absent: bool,
force: bool,
follow: bool,
snapshot: bool,
json: bool,
resume: Option<String>,
target: AuthTarget,
},
Clear {
provider: Option<String>,
all: bool,
yes: bool,
target: AuthTarget,
},
Claude {
code: Option<String>,
flow: AuthFlow,
mode: Option<String>,
from_claude_home: Option<String>,
clear: bool,
target: AuthTarget,
},
Codex {
flow: AuthFlow,
port: u16,
from_codex_home: Option<String>,
clear: bool,
target: AuthTarget,
},
Gh {
from_gh_config: Option<String>,
token_stdin: bool,
status: bool,
clear: bool,
target: AuthTarget,
},
Status {
clear_all: bool,
yes: bool,
target: AuthTarget,
},
}Expand description
Provider authorization operations.
Variants§
Import
Adopt a login this machine already has, without a browser.
Authorizing means “go get a new credential, interactively”; importing means “adopt one that already exists”. They differ in prerequisites, in side effects, and in whether a human has to be present — which decides whether a headless deployment can be provisioned at all (issue #278).
Runs on the deployment being provisioned: it installs into the
credential home of the machine executing it, and no router accepts a
credential over HTTP. With another router selected this refuses and
names it, rather than answering about the local home (issue #291); use
auth claude or auth codex to authorize a remote deployment.
The per-provider flags on the authorize commands keep working.
Fields
provider: Option<ImportProvider>Which login to adopt. Omit with --all.
dir: Option<String>Where to read it from. A named directory is read exactly as given.
Omitted, it defaults to the vendor client’s conventional directory —
~/.claude, ~/.codex, ~/.config/gh — and there, on macOS for
Claude, the login Keychain is consulted too and wins when it holds
the newer credential. Naming a directory says this credential from
there, so the machine-wide store is left out of it (issue #285).
$CLAUDE_CODE_HOME and $CODEX_HOME are deliberately not the
source: in a deployment they name this router’s own credential
directory — the destination — so reading the source through them
would make every unqualified import refuse itself (issue #307). Pass
the directory to read from another location.
all: boolAdopt every login this machine has.
The case that motivates a verb: provisioning a deployment from a machine already logged in to several providers, without knowing each flag name and default path. Run it on that deployment — import writes the executing machine’s credential home (issue #291).
if_absent: boolInstall only if no recognized credential exists after taking the shared refresh/login lock.
force: boolAssert support for non-destructive access-token validation and an atomic reference to one writable vendor-owned credential file. Older Router versions reject this spelling, allowing deployment tooling to fail closed before importing a credential.
The internal field keeps its historical name for source compatibility; this flag never bypasses positive validation.
follow: boolRequire that the credential be followed rather than copied.
A refresh token is a rotating series, not a value: whoever redeems a
link invalidates it for every other holder. So a deployment holding
its own copy and the vendor CLI beside it are two refreshers of one
chain, and whichever loses the race is left with invalid_grant —
which looks exactly like a revocation from the losing side (issue
#574). Following installs a reference to the vendor client’s own
credential file instead, so both advance one chain: a rotation by
either is seen by the other, with no re-import and no restart.
This is already what an import does when it can. The flag makes it a requirement: if a reference cannot be established — the credential lives only in the platform keychain, names no writable source, or its directory cannot be written atomically — the import refuses and says which, rather than silently falling back to a copy that will drift.
snapshot: boolTake a one-time copy instead of following the source.
The historical behaviour for callers that want a credential frozen at import time, and a deployment that must not write to the source’s directory at all. A copy drifts: the vendor client will rotate past it, so this is the shape that eventually needs a re-import.
json: boolEmit one stable JSON result envelope instead of human-readable progress. Operational failures are represented in the envelope and still produce a non-zero exit status.
resume: Option<String>Retry one retained refresh-chain transaction by its opaque ID.
Router resolves the private candidate directory; callers never need to discover or construct an internal filesystem path.
target: AuthTargetClear
Remove a stored login from this deployment.
Withdrawal is the most destructive thing this tool does and had no
name: it was four flags, the widest of them attached to a command
called status, so auth --help said nothing about it at all. The
per-command --clear flags keep working (issue #305).
Removes credentials on the machine it runs on. No router accepts a withdrawal over HTTP, so with another router selected this refuses and names it — silently rewriting “there” as “here” is unrecoverable for an OAuth credential, which then needs a fresh browser login on a machine that may not have a browser.
Fields
provider: Option<String>Which login to remove: claude, codex, gemini, qwen, gh, or
the name of a provider added through providers add. Omit with
--all.
A free-form name rather than a fixed enum: an API key stored by
providers add authorizes this deployment against an upstream
vendor exactly as an OAuth login does, and refusing to name one here
left auth unable to withdraw a credential it reports (issue #561).
target: AuthTargetClaude
Authorize an Anthropic Claude subscription.
Fields
mode: Option<String>Scope set to request: full (Claude Code /login equivalent) or
setup-token for user:inference only. Defaults to what
LOGIN_CLI_ARGS selects, then full.
from_claude_home: Option<String>Adopt an existing Claude login instead of authorizing.
Reads the credential a vendor client already holds and installs it as
this deployment’s (issue #274). Default: ~/.claude, where on macOS
the login Keychain is consulted as well and wins when it is the live
one. A directory named explicitly is read as given (issue #285).
target: AuthTargetCodex
Authorize an OpenAI Codex / ChatGPT subscription.
Fields
from_codex_home: Option<String>Adopt an existing Codex login instead of authorizing.
Default: ~/.codex (issue #274).
target: AuthTargetGh
Store the GitHub credential the proxy presents upstream.
The router mediates GitHub traffic on behalf of callers, so it needs an
operator credential of its own. Reading it from a mounted gh config
means a deployment can reuse an existing login instead of minting a
separate token (issue #263).
Fields
from_gh_config: Option<String>Read the credential from a mounted gh configuration directory
(default: $GH_CONFIG_DIR, else ~/.config/gh).
target: AuthTargetStatus
Report whether each provider credential is usable, expired, or absent.
Fields
clear_all: boolRemove every stored credential, for decommissioning a deployment.
Withdraws each provider’s credential and the GitHub one in a single
step, so an operator tearing down a test deployment does not have to
know three separate paths (issue #268).
router auth clear --all is the same operation with a name.
yes: boolConfirm removing more than one credential without a prompt.
An OAuth login cannot be put back without a browser, and this is
the widest blast radius in the tool — five credentials in one call,
on a command called status (issue #305).
target: AuthTargetImplementations§
Source§impl AuthOp
impl AuthOp
Sourcepub const fn import_target(&self) -> Option<ImportTarget>
pub const fn import_target(&self) -> Option<ImportTarget>
Whether this auth import may install into the local credential home.
Answers from the flags alone. A bare invocation is Self::may_be_remote
because a persisted selection also counts as naming a target, which
only resolution can determine.
Sourcepub const fn may_be_remote(&self) -> bool
pub const fn may_be_remote(&self) -> bool
Whether this invocation must resolve a target before importing.
false short-circuits resolution entirely, so --local never contacts
a server and never fails because one is unreachable.
Trait Implementations§
Source§impl FromArgMatches for AuthOp
impl FromArgMatches for AuthOp
Source§fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>
Source§fn from_arg_matches_mut(
__clap_arg_matches: &mut ArgMatches,
) -> Result<Self, Error>
fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>
Source§fn update_from_arg_matches(
&mut self,
__clap_arg_matches: &ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§fn update_from_arg_matches_mut<'b>(
&mut self,
__clap_arg_matches: &mut ArgMatches,
) -> Result<(), Error>
fn update_from_arg_matches_mut<'b>( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>
ArgMatches to self.Source§impl Subcommand for AuthOp
impl Subcommand for AuthOp
Source§fn augment_subcommands<'b>(__clap_app: Command) -> Command
fn augment_subcommands<'b>(__clap_app: Command) -> Command
Source§fn augment_subcommands_for_update<'b>(__clap_app: Command) -> Command
fn augment_subcommands_for_update<'b>(__clap_app: Command) -> Command
Command so it can instantiate self via
FromArgMatches::update_from_arg_matches_mut Read moreSource§fn has_subcommand(__clap_name: &str) -> bool
fn has_subcommand(__clap_name: &str) -> bool
Self can parse a specific subcommandAuto Trait Implementations§
impl Freeze for AuthOp
impl RefUnwindSafe for AuthOp
impl Send for AuthOp
impl Sync for AuthOp
impl Unpin for AuthOp
impl UnsafeUnpin for AuthOp
impl UnwindSafe for AuthOp
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more