Skip to main content

AuthOp

Enum AuthOp 

Source
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: bool

Adopt 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: bool

Install only if no recognized credential exists after taking the shared refresh/login lock.

§force: bool

Assert 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: bool

Require 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: bool

Take 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: bool

Emit 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: AuthTarget
§

Clear

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).

§all: bool

Remove every login this deployment holds.

§yes: bool

Confirm removing more than one credential without a prompt.

§target: AuthTarget
§

Claude

Authorize an Anthropic Claude subscription.

Fields

§code: Option<String>

Supply the copied code without prompting on stdin.

§flow: AuthFlow

Force an OAuth flow instead of automatic selection.

§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).

§clear: bool

Remove the stored credential instead of authorizing.

§target: AuthTarget
§

Codex

Authorize an OpenAI Codex / ChatGPT subscription.

Fields

§flow: AuthFlow

Force an OAuth flow instead of automatic selection.

§port: u16

Local callback port registered for the Codex OAuth client.

§from_codex_home: Option<String>

Adopt an existing Codex login instead of authorizing.

Default: ~/.codex (issue #274).

§clear: bool

Remove the stored credential instead of authorizing.

§target: AuthTarget
§

Gh

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).

§token_stdin: bool

Read the credential as one line from standard input instead.

§status: bool

Report what is currently stored without changing it.

§clear: bool

Remove the stored credential instead of storing one.

§target: AuthTarget
§

Status

Report whether each provider credential is usable, expired, or absent.

Fields

§clear_all: bool

Remove 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: bool

Confirm 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: AuthTarget

Implementations§

Source§

impl AuthOp

Source

pub const fn remote_gh(&self) -> Option<RemoteGh>

What this auth gh invocation may do against a selected router.

None for anything that is not auth gh.

Source§

impl AuthOp

Source

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.

Source

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 Debug for AuthOp

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl FromArgMatches for AuthOp

Source§

fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>

Instantiate Self from ArgMatches, parsing the arguments as needed. Read more
Source§

fn from_arg_matches_mut( __clap_arg_matches: &mut ArgMatches, ) -> Result<Self, Error>

Instantiate Self from ArgMatches, parsing the arguments as needed. Read more
Source§

fn update_from_arg_matches( &mut self, __clap_arg_matches: &ArgMatches, ) -> Result<(), Error>

Assign values from ArgMatches to self.
Source§

fn update_from_arg_matches_mut<'b>( &mut self, __clap_arg_matches: &mut ArgMatches, ) -> Result<(), Error>

Assign values from ArgMatches to self.
Source§

impl Subcommand for AuthOp

Source§

fn augment_subcommands<'b>(__clap_app: Command) -> Command

Append to Command so it can instantiate Self via FromArgMatches::from_arg_matches_mut Read more
Source§

fn augment_subcommands_for_update<'b>(__clap_app: Command) -> Command

Append to Command so it can instantiate self via FromArgMatches::update_from_arg_matches_mut Read more
Source§

fn has_subcommand(__clap_name: &str) -> bool

Test whether Self can parse a specific subcommand

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &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
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more