Epsitec.Auth.Cli 5.11.3.2629

Prefix Reserved
dotnet tool install --global Epsitec.Auth.Cli --version 5.11.3.2629
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Epsitec.Auth.Cli --version 5.11.3.2629
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Epsitec.Auth.Cli&version=5.11.3.2629
                    
nuke :add-package Epsitec.Auth.Cli --version 5.11.3.2629
                    

auth-cli

Operator command-line tool for the Epsitec auth service. It manages the public key registry end to end — generates hybrid key material (ECDSA P-256, ML-DSA-65, X25519, ML-KEM-1024), registers, reads, and revokes keysets — and covers the token flows: user login (browser or credentials, with optional TOTP), refresh, MFA step-up, audience-bound tokens (RFC 8707), OAuth 2.0 client-credentials service tokens, and service-client administration.

Installation

The tool ships as a .NET tool package (Epsitec.Auth.Cli):

dotnet tool install --global Epsitec.Auth.Cli
auth-cli --help

Quick Start

# Configure the target service and credentials
auth-cli configure authUrl=https://auth.example.com
auth-cli configure password=my-password
auth-cli configure apiKey=my-api-key        # only for service/admin commands

# Login via browser (Passport) — derives UID from JWT sub claim
auth-cli login

# Generate keys for the logged-in user
auth-cli generate --uid uid.a1b2c

# Register the keyset (start + complete in one step)
auth-cli register --uid uid.a1b2c

# Read back
auth-cli get latest --uid uid.a1b2c
auth-cli get by-hkid --uid uid.a1b2c --hkid <hkid>
auth-cli get range --uid uid.a1b2c                                # all time
auth-cli get range --uid uid.a1b2c --from 2024-01-01              # from date
auth-cli get range --uid uid.a1b2c --from 1700000000 --to 1800000000  # Unix seconds

# Service API reads (no user JWT needed — API key or client credentials)
auth-cli service get latest --uid uid.a1b2c
auth-cli service get by-hkid --uid uid.a1b2c --hkid <hkid>
auth-cli service get range --uid uid.a1b2c --from 2024-01-01

# Revoke
auth-cli revoke --uid uid.a1b2c --keyset-id 1

# Inspect local state
auth-cli dump keys --uid uid.a1b2c
auth-cli dump keyset --uid uid.a1b2c
auth-cli dump private-keys --uid uid.a1b2c

# Refresh token manually (by uid, or by stored login)
auth-cli refresh --uid uid.a1b2c
auth-cli refresh --login user@example.com

# Capture just the bare access token for scripting (--jwt)
TOKEN=$(auth-cli login --login user@example.com --pwd s3cr3t --jwt)
TOKEN=$(auth-cli refresh --uid uid.a1b2c --jwt)

# Upgrade a stored 1FA refresh token to a 2FA AT/RT pair
auth-cli mfa step-up --uid uid.a1b2c               # interactive TOTP prompt
auth-cli mfa step-up --uid uid.a1b2c --totp 123456 # non-interactive

Global Options

Option Default Description
--root ./.auth-cli/ Root directory for settings and state
--json false Emit machine-readable JSON output

Partial UID

All commands that accept --uid resolve it against existing keyset files. You may pass a prefix as long as it is unambiguous:

# Full uid
auth-cli get latest --uid uid.a1b2c3d4e5

# Unambiguous prefix — resolves automatically
auth-cli get latest --uid uid.a1b

If the prefix matches no uid, or matches more than one, the command fails with a descriptive error.

Exact matches always win: if uid.a1b and uid.a1b2 both exist, passing uid.a1b resolves unambiguously to uid.a1b.

JSON Output

With --json, every command emits a single JSON object on stdout:

{ "status": "ok",    "command": "get latest", "data": { ... } }
{ "status": "error", "command": "get latest", "error": "<message>" }

The status field is always either "ok" or "error".

Without --json (text mode), commands write human-readable summaries to stdout and errors to stderr.

Commands

Command Description
configure [k=v...] Store or display global settings
login Authenticate via Passport (browser) or with --login/--pwd (credentials, optional TOTP)
generate --uid Generate a fresh random hybrid keyset
refresh Exchange stored refresh token for a new access token (by --uid or --login)
register --uid Full start + complete registration
register start Start keyset registration only
register complete Complete a pending registration
get latest Get latest valid keyset (JWT auth)
get range Get keysets in a time range (JWT auth); --from/--to optional
get by-hkid Get keyset by hkid (JWT auth)
service get latest Get latest valid keyset (API key or client credentials)
service get range Get keysets in a time range (API key or client credentials); --from/--to optional
service get by-hkid Get keyset by hkid (API key or client credentials)
service token Obtain a service access token via the OAuth 2.0 client-credentials grant
service client ... Administer the service-client registry (see Service-Client Administration)
revoke --uid Revoke an existing keyset
dump keys Export public keys as SPKI PEM, with kids and hkid
dump keyset Print the last server keyset
dump private-keys Export private keys as PKCS#8 PEM to stdout
mfa step-up Upgrade a stored 1FA refresh token to a 2FA AT/RT pair

Credential Login

The login command also supports direct credential-based authentication, bypassing the browser. Add --login <email> to enable this path. When --pwd is omitted, the CLI prompts interactively on stderr.

Option Description
--login Email to authenticate with; enables the credential path
--pwd Password; prompted interactively when --login is set but --pwd is omitted
--totp 6-digit TOTP code to verify an existing enrolment (upgrades to ["pwd","otp"])
--totp-setup Runs the interactive 3-step TOTP enrolment flow after credential login
--resource RFC 8707 resource indicator; binds the minted token's aud to this absolute URI (see Audience Binding)
--expected-audience Audience the returned token is validated against; defaults to --resource, else the default audience
--jwt Print only the bare access token to stdout (for scripting); mutually exclusive with --json (see Bare Token Output)

Option rules (all validated before any network call):

  • --pwd, --totp, --totp-setup, and --resource require --login.
  • --totp and --totp-setup are mutually exclusive.
  • --jwt and --json are mutually exclusive.

When --totp or --totp-setup is requested, no tokens are persisted unless the full requested flow succeeds; the existing {uid}.keyset.json file is left untouched on failure.

# Simple credential login (password prompted)
auth-cli login --login user@example.com

# Credential login with inline password
auth-cli login --login user@example.com --pwd s3cr3t

# Credential login + TOTP verification (upgraded ["pwd","otp"] token)
auth-cli login --login user@example.com --pwd s3cr3t --totp 123456

# Credential login + interactive TOTP enrolment
auth-cli login --login user@example.com --pwd s3cr3t --totp-setup

Refresh

refresh exchanges a stored refresh token for a new access token. Identify the target keyset by either --uid or --login (the stored sign-in email) — supplying both, or neither, is a validation error:

auth-cli refresh --uid uid.a1b2c
auth-cli refresh --login user@example.com

--login matches the login value persisted in {uid}.keyset.json at login time, case-insensitively. It resolves for both credential and browser logins, since the email is read from the access token's login claim.

Bare Token Output (--jwt)

Both login and refresh accept --jwt, which prints only the bare access token as a single line on stdout and routes the human-readable status line to stderr. This makes the token trivial to capture in a shell:

TOKEN=$(auth-cli login --login user@example.com --pwd s3cr3t --jwt)
TOKEN=$(auth-cli refresh --login user@example.com --jwt)

--jwt and --json both own stdout, so they are mutually exclusive; combining them fails with a validation error before any network call.

Audience Binding (RFC 8707)

The login, refresh, and mfa step-up commands accept --resource <uri>, an RFC 8707 resource indicator. When supplied, the minted access token's aud claim is bound to that value, so a token issued for one service cannot be replayed against another. Without --resource, the token targets the default audience (unchanged behaviour).

  • The value must be an absolute URI without a fragment (https: URLs and urn: URIs both work); anything else fails with invalid_target and no token.
  • On login, --resource also drives the post-login validation, so a resource-bound token round-trips cleanly. Pass --expected-audience to override that (for example, to assert a deliberate mismatch).
  • On login, --resource requires --login: the browser/Passport path cannot bind an audience (the token is minted by Passport).
# Mint a token bound to a specific service
auth-cli login --login user@example.com --pwd s3cr3t --resource https://briefcase.example

# Bind a fresh access token from a stored refresh session
auth-cli refresh --uid uid.a1b2c --resource https://briefcase.example

# Step up to 2FA, bound to a specific service
auth-cli mfa step-up --uid uid.a1b2c --totp 123456 --resource https://briefcase.example

Service Tokens (Client Credentials)

Machine-to-machine callers authenticate with the OAuth 2.0 client-credentials grant: a registered service client exchanges its client_id/client_secret for a short-lived, scoped, audience-bound access token — the long-lived secret is only ever presented to the token endpoint, never to resource endpoints.

# Obtain a service token (bare token on stdout in text mode, like --jwt)
TOKEN=$(auth-cli service token --client-id bsrv0001 --client-secret <secret>)

# Restrict the requested scope and/or bind an audience
auth-cli service token --client-id bsrv0001 --client-secret <secret> \
    --scope keysets:read --resource https://auth.example.com --json
Option Description
--client-id Registered service-client identifier
--client-secret The client's secret
--scope Requested scopes; must be within the client's allowed set (default: the full allowed set)
--resource RFC 8707 resource indicator; binds the token's aud

The keyset service reads accept client credentials directly and handle the token acquisition internally:

auth-cli service get latest --uid uid.a1b2c --client-id bsrv0001 --client-secret <secret>

Without --client-id/--client-secret, the service get commands fall back to the configured API key (configure apiKey=...).

Service-Client Administration

The service client subcommands administer the service-client registry. They require the operator API key (configure apiKey=...).

Command Description
service client register Register a client; prints the generated secret once
service client secret add Issue a second secret for zero-downtime rotation; prints it once
service client secret retire Retire one secret (--secret-id)
service client disable Disable a client; its next token request fails
service client enable Re-enable a disabled client
service client delete Delete a client entirely; prefer disable for offboarding (keeps the audit witness)
service client list List registered clients (never shows secret material)
service client show Show one client (never shows secret material)
# Onboard a new consumer — the secret is printed ONCE, store it immediately
auth-cli service client register --client-id bsrv0001 \
    --name "Briefcase server 1" --scope keysets:read

# Optional per-client default audience and absolute expiry
auth-cli service client register --client-id bsrv0002 --scope keysets:read \
    --audience https://auth.example.com --expiry 2027-01-01

# Zero-downtime secret rotation
auth-cli service client secret add --client-id bsrv0001
auth-cli service client secret retire --client-id bsrv0001 --secret-id <old-secret-id>

# Offboarding / incident response
auth-cli service client disable --client-id bsrv0001

# Inspect
auth-cli service client list
auth-cli service client show --client-id bsrv0001

Registered secrets are stored server-side as salted hashes only; they cannot be recovered after registration. Losing a secret means rotating: secret add a new one, then secret retire the old.

Time Range Arguments

The --from and --to options on get range and service get range are optional and accept two formats:

Format Example Interpretation
Unix seconds 1700000000 Exact Unix UTC timestamp
Date 2024-01-15 Midnight UTC on that day (yyyy-MM-dd)

Defaults: --from 0 (epoch), --to end of 2199-12-31 UTC.

Terminology

  • kid — key identifier, derived from a key's public SPKI bytes.
  • hkid — hybrid key identifier, derived from the two signing kids (ECDSA + ML-DSA). Uniquely identifies a hybrid keyset.

Storage

All state is stored under the --root directory (default .auth-cli/):

  • settings.json — global settings (authUrl, passportUrl, apiKey, password)
  • {uid}.keyset.json — per-user keys, tokens, stored login, pending registration, last server keyset
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated
5.11.3.2629 86 7/16/2026
5.11.2.2629 73 7/16/2026
5.11.1.2629 74 7/16/2026
5.11.0.2629 90 7/16/2026
5.10.3.2629 118 7/14/2026
5.10.2.2628 106 7/12/2026
5.10.0.2628 107 7/12/2026
5.9.1.2626 120 6/23/2026
5.8.2.2623 123 6/6/2026