Skip to content

Pre-release. v0.1 is not out yet, so there is nothing to install and no public source to clone — the quickstart builds from a checkout.

Command line

One binary. With no command it is the server; with one it is the operator tool for the thing the server needs. Onbe.Server below is the server binary — from a checkout, dotnet run --project src/Onbe.Server -- <command>; in the published image, the container’s arguments.

Command Reads configuration What it does
(none) all of it Runs the control plane
keys generate nothing Writes a new signing key
keys all of it, then the signing keys Prints the public JWKS and the active key id
keys rotate all of it, then the signing keys Writes the next key and prints the three-deploy rollout
agent init nothing Writes a registration, a key pair and a public key set
agent apply nothing Reconciles registration files against a running control plane
migrate all of it, then the database Applies the schema
doctor all of it Checks everything the server would fail on, and says which
audit-verify all of it, then the database Verifies every audit chain

Which ones read no configuration is not an accident: a key and an agent registration are made before there is a deployment to configure, so those commands work on a laptop with nothing set. Every other command loads and validates the whole configuration first, and doctor runs whether or not it loaded.

Terminal window
Onbe.Server keys generate --out /run/secrets/onbe/active.pem [--kid <name>]

Writes an owner-readable PKCS#8 PEM holding a new P-256 key, refuses to overwrite a file that already exists, and prints the key id with the setting that configures it. Nothing private is printed; the PEM exists only in the file. The key id defaults to the RFC 7638 thumbprint, which changes when the key does, so two keys can never share one.

Prints what a running instance would publish: the public JWKS, then the active key id. Useful for confirming a rotation reached the process you think it did.

Terminal window
Onbe.Server keys rotate --out /run/secrets/onbe/next.pem

Loads the configured keys exactly as the server would, writes a new key beside them, and prints the rollout: which setting to add, when to move ActiveKid, and how long to wait before removing the retired key. The wait is computed from the largest max_token_ttl of any registered agent, disabled ones included; when the registry cannot be read it falls back to Onbe:Tokens:DefaultTokenTtl and says so. It changes nothing but the new key file.

Terminal window
Onbe.Server agent init <agent-id> --out agents/

Writes three files: the registration as YAML, its public key set as JSON, and the private key, owner-readable. The first two are meant to be committed; the third belongs in a secret store. It refuses to overwrite anything it would have written, and never prints the private key.

The defaults are deliberately useless — sponsor_required: true, a thirty-minute task, a five-minute token, depth 1, and empty scope and audience lists — so the file cannot become dangerous by being applied before somebody decides what the agent may do.

Terminal window
ONBE_ADMIN_KEY= Onbe.Server agent apply agents/*.yaml --server https://onbe.example.com [--dry-run]

Reconciles each file against the control plane: creates what is missing, patches what differs, and does nothing at all when the file already matches — a second run makes one call, the read. --dry-run prints what it would change and writes nothing. Every change goes through the admin API, so it lands in the audit ledger exactly as a hand-made request would.

The key comes from ONBE_ADMIN_KEY or standard input; there is no flag for it. --dry-run needs no key, which is what runs on a pull request. It never deletes a registration and never changes enabled: both are decisions for the admin API.

Output is one line per file, then a summary:

Terminal window
created jira-triage
1 file(s), 1 changed.

Applies the schema for the configured provider and prints what it applied. Migrations are never applied at startup: a rolling deploy that migrates on boot is a race between instances and a schema change nobody approved. For the embedded provider it also creates the file and its directory, and puts the database in write-ahead logging mode.

Terminal window
Onbe.Server doctor [--subject-token -]

Runs the checks the server would otherwise fail on, in the order that matters — configuration, signing key, identity provider, database, admin API — and prints a line each, with a likely cause and what to check for anything that failed:

Terminal window
ok configuration Loaded.
ok signing key Active kid '9Fy-qRMxKnbHaNBF9nwF68GQVxzhgz3miPA15FHHv38', 1 key(s) published.
FAIL upstream The discovery document could not be fetched.
Likely cause: nothing is serving http://127.0.0.1:8080/realms/main from here, or the request timed out.
Check the host is resolvable and reachable from this pod, and that Onbe__UpstreamIdp__Issuer is the realm URL.
ok database Reachable (sqlite), schema up to date.
ok admin API Enabled; /admin requires the configured key.
5 check(s), 1 failed.

Give it a real user’s access token on standard input — printf '%s' "$TOKEN" | Onbe.Server doctor --subject-token - — and it also checks that token the way an exchange would. Reading it from standard input keeps it out of the process list, and it is never printed.

Terminal window
Onbe.Server audit-verify [<seq>:<hash>,...]

Walks every chain of the ledger, recomputes every link, and prints one head per chain as a comma-separated seq:hash list. Pass that list back and it proves each chain still reaches its head unchanged — the only way to detect a cut tail — so keep the list somewhere the database cannot reach and run this on a schedule.

Code Meaning
0 It worked
1 It failed: a check failed, a file could not be written or was refused by the server, there was no key to rotate, or the ledger could not be read
2 The command line was wrong, or a required argument was malformed
3 audit-verify only: a chain is broken

The server itself exits 1 on invalid configuration, having printed every problem with it.

OnbePre-release. v0.1 is not out yet.

© 2026 Onbe