Skip to content

The v1 docs follow nauthera-server's main branch and its 0.x releases on the way to 1.0, so fields and APIs can still change.

v1

nauthera-cli Reference

Docs version v1 (main)Nauthera is pre-1.0, in a design-partner programUpdated

nauthera-cli drives the gRPC AdminService from a terminal. For clients and identity providers, it uses the same idempotent upserts the operator drives. It is a local development tool; in a cluster the operator manages clients. It connects in one of two ways:

  • Without TLS, the default. Only a server with server.grpc.allow_insecure: true answers, and the server accepts that setting only on a loopback server.grpc.address, as in config.dev.yaml and the chart's kind profiles.
  • With mutual TLS, when you pass --tls-ca-file, --tls-cert-file and --tls-key-file together. The Compose stack runs the control plane this way: just certs writes a CA, the server's key pair and a nauthera-cli client certificate to .certs/grpc/, and the server admits only that client certificate.

Run it from a checkout of nauthera-server:

go run ./cmd/nauthera-cli <command> [flags]

Against the Compose stack:

go run ./cmd/nauthera-cli get org \
  --tls-ca-file .certs/grpc/ca.pem \
  --tls-cert-file .certs/grpc/client.pem \
  --tls-key-file .certs/grpc/client-key.pem

To reach a server in a kind cluster, where the AdminService listens on 127.0.0.1 inside the pod, port-forward the deployment first:

kubectl -n nauthera port-forward deploy/nauthera-nauthera-server 9091:9091

Global flags

FlagDefaultMeaning
--addrlocalhost:9091Address of the gRPC AdminService
--namespacedefaultNamespace of the client and identity provider resources the command reads or writes. They are addressed by namespace and resource name, not by client ID or slug.
--timeout15sLimit for dialing plus the call
-o, --outputtabletable, json or yaml
--tls-ca-filenonePEM CA bundle the server's certificate must chain to
--tls-cert-filenonePEM client certificate to present
--tls-key-filenonePEM private key of the client certificate
--confignoneA YAML file with any of the keys above. A path that does not exist is an error.

Each setting can also come from an environment variable, NAUTHERA_CLI_ followed by the upper-cased flag name with dashes as underscores, for example NAUTHERA_CLI_ADDR or NAUTHERA_CLI_TLS_CA_FILE. The three TLS settings go together: setting only some of them is an error. A flag on the command line wins, then the environment, then the config file.

Organizations

create org <slug>

Creates an organization. It refuses a slug that already exists. It returns no secret for the organization's {slug}-admin-m2m client, so nobody holds that secret and the client cannot be used. An organization created through the admin API gets that secret once, as admin_m2m_secret.

FlagMeaning
--display-nameHuman-readable name. Defaults to the slug.
--fapi-modeApply the FAPI 2.0 subset: PAR required, PKCE S256 only, ES256 only
--fips-modePut the organization under the FIPS policy. The server must run the Go FIPS 140-3 module, on and pinned to a frozen version. On any other process the create fails with FAILED_PRECONDITION, and an existing FIPS organization is not served.
--require-email-verificationKeep an account with an unverified address out of a session until it follows an emailed link. The organization needs an email relay to send one.
--second-factor-fileA YAML or JSON file holding the organization's second-factor policy, in the control plane's field names: methods, required, passwordless, remember_for_seconds, spare_zones, always_challenge, rules.
--zoneA network zone as name=cidr[,cidr...]. Repeat the flag for more zones.

FIPS mode can be set only when the organization is created. FAPI mode, email verification, the second-factor policy and the zones can be changed later with update org. An organization's policy can only tighten the deployment's; see Configuration. See also Organizations.

# policy.yaml
methods: [passkey, totp]
required: true
rules:
  - name: passkey-off-site
    outside_zones: [office]
    methods: [passkey]

spare_zones names zones of the deployment's security.network_zones only, because no level spares a sign-in the deployment would not.

go run ./cmd/nauthera-cli create org acme --display-name "Acme" \
  --zone office=203.0.113.0/24 --second-factor-file policy.yaml

update org <slug>

Changes an existing organization. Only the flags given are changed; pass --fapi-mode=false or --require-email-verification=false to lift one. It refuses a call that changes nothing, and answers an unknown slug with an error.

FlagMeaning
--display-nameHuman-readable name
--fapi-modeHold the organization to FAPI 2.0, or with =false release it
--require-email-verificationRequire a verified address before sign-in completes, or with =false stop requiring it
--second-factor-fileReplace the whole second-factor policy
--zoneReplace every network zone; repeatable
--clear-zonesRemove every network zone. Cannot be combined with --zone.

The slug and FIPS mode are fixed at creation. The main organization's settings come from orgs.main in the server's configuration, not from here; the control plane never changes the main organization.

get org [slug]

Reads one organization, or lists all of them when the slug is omitted.

delete org <slug>

Deletes an organization's record. Its users, clients and sessions stay in the database, and its reserved admin clients keep the slug taken, so create org with the same slug then fails with an internal error (#283). Deleting an organization that does not exist succeeds. The main organization cannot be deleted. See Deleting an org.

Clients

create client <client-id>

Creates the client, or replaces its configuration if it exists. A secret is generated and printed once, by the run that mints it: the run that creates the client, or a later run that switches a client without a secret, such as a public one, to client_secret_basic. Store it then. Running the command again never rotates the secret: to get a new one, delete the client and create it again.

FlagDefaultMeaning
--namethe client IDResource name the client is stored under
--display-nameName shown on the consent screen
--orgHome the client in this organization. Cannot be combined with --issuer.
--issuerthe main orgHome the client at this issuer URL
--redirect-uriExact redirect URI. Repeat the flag or separate with commas. Required with the authorization_code grant.
--post-logout-redirect-uriAllowed post-logout redirect URI. Repeatable.
--frontchannel-logout-uriFront-channel logout URI
--frontchannel-logout-session-requiredfalseThe client needs iss and sid on the front-channel logout request. It is skipped when no sid is available.
--scopesopenid,profile,email,offline_accessScopes the client may request
--grant-typesauthorization_code,refresh_tokenGrants the client may use
--response-typescode
--pkcerequired_s256required_s256, optional or disabled
--allow-refreshtrueAllow refresh tokens
--publicfalsePublic client: no secret, PKCE required, authenticates with none
--jwks-uriMake it a private_key_jwt client verified against the keys at this https URL. No secret is generated. Cannot be combined with --public.
--token-auth-signing-algeitherES256 or RS256 for the client's assertions. Needs --jwks-uri.
--identity-providerOffer an identity provider of the client's organization on its sign-in page: <slug> for sign-in and sign-up, <slug>:sign-in or <slug>:sign-up for one of them. Repeat the flag or separate with commas. The organization's own sign-up setting still applies.
--second-factor-fileThe client's second-factor policy, in the same format as for create org. It can only tighten its organization's.

Without --public or --jwks-uri, the client authenticates with client_secret_basic.

go run ./cmd/nauthera-cli create client my-app \
  --org acme \
  --redirect-uri https://app.example.com/callback \
  --post-logout-redirect-uri https://app.example.com/

get client [name]

Reads one client by resource name, or lists the clients in --namespace when the name is omitted. Add -A (--all-namespaces) to list every namespace.

delete client <name>

Deletes a client by resource name. Deleting one that does not exist succeeds.

Identity providers

create identity-provider <slug>

Creates or replaces an external OpenID Connect provider, or GitHub (--provider-issuer https://github.com/login/oauth), that an organization's users can sign in with (see Social sign-in). Like create client, it is an idempotent upsert, stored under --namespace and the resource name. It prints the redirect URI to register at the provider. A client offers the provider with create client --identity-provider <slug>.

FlagDefaultMeaning
--namethe slugResource name the provider is stored under
--display-namethe slugThe name on the provider's sign-in button
--orgThe organization the provider belongs to. Cannot be combined with --issuer.
--issuerthe main orgThe issuer URL of the organization the provider belongs to
--provider-issuerRequired. The provider's own issuer, whose discovery document is read (https, public host), or https://github.com/login/oauth for GitHub
--client-idRequired. The client ID this server is registered under at the provider
--client-secret-fileFile holding the client secret the provider issued; /dev/stdin reads it from a pipe. Required on create; on an update, leaving it out keeps the stored secret. An empty file is refused.
--scopesopenid email profile (GitHub: read:user user:email)Scopes requested from the provider
--trust-emailfalseTrust the provider's email_verified claim, which lets an upstream account link to an existing account with that address
--allowed-email-domainAdmit only verified addresses in these domains. Repeatable. Needs --trust-email.
--trust-mfafalseLet the provider's own multi-factor sign-in stand in for this server's second factor
--mfa-acr-valueThe acr values the provider issues for a multi-factor sign-in. Repeatable. Needs --trust-mfa.
--spare-second-factorfalseLet a sign-in through the provider that it did not vouch for skip this server's second factor, as a single-factor sign-in
printf '%s' "$GOOGLE_CLIENT_SECRET" | go run ./cmd/nauthera-cli create identity-provider google \
  --org acme --display-name Google \
  --provider-issuer https://accounts.google.com \
  --client-id 1234.apps.googleusercontent.com \
  --client-secret-file /dev/stdin --trust-email

There is no get or delete command for identity providers yet; use the admin API, the dashboard or an IdentityProvider resource.

What it cannot do

There are no commands for branding, users, roles or client labels, and no get or delete for identity providers. Write branding with the gRPC UpsertBranding call directly or a Branding resource. Users and their roles are managed through the admin API and the admin dashboard.