Command line
Every command of the nexus binary, every flag, and what each one defaults to.
$ nexus --help$ nexus --versionState lives under ~/.nexus/. Each command opens the file it needs and creates the directory if
it is missing:
| Command | Default database |
|---|---|
validate, compile |
none — they never touch storage |
deploy, keys, proto, seed |
~/.nexus/registry.db |
serve |
~/.nexus/registry.db, plus nexus-audit.db, nexus-log.db, nexus-ui.db and queues/ beside it |
audit |
~/.nexus/nexus-audit.db |
dlq |
~/.nexus/queues/ — derived from the registry path, not opened as a database |
state, tenant, cert, simulate |
~/.nexus/registry.db |
Every command that reads a database accepts --db <path> to point elsewhere. For dlq, --db
is only used to locate the queue directory: the queues live in a queues/ folder next to the
file you name.
Before anything else runs, nexus reads a .env file from the working directory if one exists.
Diagnostics go to stderr, results to stdout, so nexus compile flow.md > artifact.json is safe.
Set RUST_LOG to change the verbosity; the default is info.
nexus validate
Parses a flow file and resolves names. Exits 0 when clean, 1 with the errors on stderr otherwise.
| Flag | Default | Meaning |
|---|---|---|
<path> |
— | The .flow.md file. Positional, required |
--libs <dir> |
none | Directory of shared .flow.md files that this flow may include or call_flow |
$ nexus validate forward-order.flow.mdok forward-order.flow.md flow: forward-order tenant: acme steps: 3validate runs fewer checks than compile. It parses and resolves, but it does not lower
expressions or check step configuration, so a file that validates can still fail to compile. Use
compile when you need certainty.
nexus compile
Compiles a flow to its intermediate representation and prints it. Nothing is stored.
| Flag | Default | Meaning |
|---|---|---|
<path> |
— | The .flow.md file. Positional, required |
-o, --output <path> |
stdout | Write the IR to a file instead |
-p, --pretty |
off | Indent the JSON |
--libs <dir> |
none | Directory of shared .flow.md files |
$ nexus compile forward-order.flow.md --pretty | head -20{ "meta": { "name": "forward-order", "tenant": "acme", "version": { "major": 0, "minor": 1 }, "effects": [ "http_egress" ], ...With --output, the hash is printed instead of the document:
$ nexus compile forward-order.flow.md --output forward-order.ir.jsonok forward-order.flow.md → forward-order.ir.json hash: 9f2b7c4d1ae05836b1c0d4f7a83e2916d5b0c7314ea9f6d8b2c5107e43ab9d02nexus deploy
Compiles a flow and publishes it to the registry under a version, then points latest at it.
| Flag | Default | Meaning |
|---|---|---|
<path> |
— | The .flow.md file. Positional, required |
-v, --version <ver> |
— | Version string, required |
--db <path> |
~/.nexus/registry.db |
Registry database |
--libs <dir> |
none | Directory of shared .flow.md files, resolved at compile time |
$ nexus deploy forward-order.flow.md --version 1.2.0deployed forward-order.flow.md flow: forward-order tenant: acme version: 1.2.0 hash: 9f2b7c4d1ae05836b1c0d4f7a83e2916d5b0c7314ea9f6d8b2c5107e43ab9d02 db: /home/you/.nexus/registry.dbThe tenant and the flow name come from the file’s front matter, not from a flag. Deploying a version that already exists is an error — a published version is fixed, so publish a new one.
The tenant must already be registered with nexus tenant create. Deploying into
an unknown tenant fails, naming the command that fixes it; the platform will not create one for
you, because then a typo in tenant: would become a real tenant that nothing distinguishes from a
new customer. A disabled tenant is refused for the same reason, with a different message.
nexus serve
Starts the HTTP server. Flows must be deployed first.
| Flag | Default | Meaning |
|---|---|---|
--host <h> |
0.0.0.0 |
Bind address |
-p, --port <p> |
9090 |
Bind port |
--db <path> |
~/.nexus/registry.db |
Registry database; the audit, log, UI databases and the queue directory are created beside it |
--grpc-port <p> |
off | Open the gRPC door on a separate port, h2c (plaintext). Without it nothing listens; a flow deployed with inbound: leaves a WARN naming it. 0 asks the system for a port and announces it: NexusFabric gRPC ingress listening on <addr> |
--secret <key> |
none | Enable X-Nexus-Signature verification with this HMAC-SHA256 secret |
--no-auth |
off | Serve without API key authentication. Local development only; the server warns on every boot |
API key authentication is on unless you pass --no-auth: POST .../run, POST .../enqueue,
POST /connector/events/... and GET /flows/{tenant}/{name} answer 401 without a valid
Authorization: Bearer <nxk_...>. Issue one with nexus keys create before the
first call. GET /health and GET .../wsdl stay public.
$ nexus serve --port 9090NexusFabric server starting on 0.0.0.0:9090 db: /home/you/.nexus/registry.db ui db: /home/you/.nexus/nexus-ui.db audit db: /home/you/.nexus/nexus-audit.db log db: /home/you/.nexus/nexus-log.db queue dir: /home/you/.nexus/queues webhook signature verification: disabled API key authentication: enabledStarted with --no-auth, the last line reads DISABLED (--no-auth) and a warning is written to the
log — an open server should never be a quiet one.
The same process serves the HTTP API, the management UI at /ui, the cron scheduler
for flows with a schedule: key, and the queue workers. See Server and
configuration.
A flow that declares config: needs its
values in the environment before the server will start. If one is missing, the server refuses to
boot and names the tenant, the flow, the key and the variable:
$ nexus serveerror: acme/submit-reading declares config key `BILLING_URL`, but NEXUS_CONFIG_BILLING_URL is not set. Set the variables and start again, run `nexus config check` to see the whole pictureThe values are captured once, at start-up, so changing configuration means restarting.
nexus config check
The same verdict nexus serve reaches at boot, without starting anything. It lists what every
deployed flow requires — not only what is missing, because the question an operator asks when
preparing an installation is “what does this platform need from me”.
| Flag | Default | Meaning |
|---|---|---|
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus config checkConfiguration required by deployed flows: acme/submit-reading BILLING_URL (NEXUS_CONFIG_BILLING_URL) — set acme/submit-reading PARTNER_ENDPOINT (NEXUS_CONFIG_PARTNER_ENDPOINT) — MISSINGerror: 1 declared key(s) have no value: PARTNER_ENDPOINT (NEXUS_CONFIG_PARTNER_ENDPOINT). `nexus serve` will refuse to startExits non-zero when anything is missing, so it gates a deployment script the same way it gates a boot. Three details worth knowing:
- The value is never printed, only whether it is present. Configuration is not masked in the log — an endpoint is not a secret — but this command answers a question about presence, and printing values would put them into terminal scrollback and CI output.
- Set-but-empty is reported as
set, empty, distinct fromMISSING. An empty prefix is a legitimate value, so it starts the server; an absent one does not. - An artifact that cannot be read is reported and the exit stays non-zero. The command cannot say what such a flow requires, and a clean exit would claim more than was checked.
- A registry that cannot be listed is a refusal, not an empty answer. If the command cannot read the list of deployed flows at all, it says so and exits non-zero. It used to report that nothing required configuration — the opposite answer, said with confidence, to the one question this command exists to answer.
nexus audit
Prints the most recent entries of the tamper-evident audit trail for one tenant.
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Tenant to query, required |
-l, --limit <n> |
20 |
How many of the most recent entries to show |
--db <path> |
~/.nexus/nexus-audit.db |
Audit database |
--verify |
off | Also check the hash chain and fail if it is broken |
$ nexus audit --tenant acme --limit 3 --verifyseq event_type created_at correlation_id------------------------------------------------------------------------------------------1187 queue.message.processed 2026-08-06T09:14:22Z 7f3a1c02-9b6e-4f11-8a2d-0d55c3b41e901186 queue.message.failed 2026-08-06T09:14:19Z 7f3a1c02-9b6e-4f11-8a2d-0d55c3b41e901185 queue.message.enqueued 2026-08-06T09:14:18Z 7f3a1c02-9b6e-4f11-8a2d-0d55c3b41e90
chain integrity: OK (1187 entries checked)With --verify, a broken chain prints the offending entries and exits 1, which makes it usable
as a scheduled check.
nexus dlq
Manages the dead-letter queue: messages that used up every retry. All three subcommands read the
queue directory derived from --db.
nexus dlq list
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
all tenants | Show only this tenant |
--flow <f> |
all flows | Show only this flow |
--db <path> |
~/.nexus/registry.db |
Used to locate queues/ |
$ nexus dlq list --tenant acmeDLQ: 1 pending message(s)
id=17 tenant=acme flow=order-processor enqueued_at: 2026-08-06T09:14:18Z failed_at: 2026-08-06T09:15:04Z attempts: 3 last_error: effect failed at step 'forward': connect timed outWith no filters it scans every tenant and flow and prints DLQ is empty. when there is nothing.
nexus dlq replay
Copies the message back into the main queue and marks the dead-letter entry handled. The flow
runs again from the beginning, with a fresh attempt counter, against whatever version is
currently latest.
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Required |
--flow <f> |
— | Required |
--id <n> |
— | Message ID from dlq list, required |
--db <path> |
~/.nexus/registry.db |
Used to locate queues/ |
$ nexus dlq replay --tenant acme --flow order-processor --id 17replayed id=17 tenant=acme flow=order-processornexus dlq discard
Marks the entry handled without re-enqueuing it. The entry leaves dlq list immediately; its body
leaves the disk at the flow’s next queue drain, when the worker rewrites dlq.log without the
marked rows. There is no command to bring it back.
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Required |
--flow <f> |
— | Required |
--id <n> |
— | Message ID from dlq list, required |
--db <path> |
~/.nexus/registry.db |
Used to locate queues/ |
$ nexus dlq discard --tenant acme --flow order-processor --id 17discarded id=17 tenant=acme flow=order-processor the body leaves the disk at this flow's next queue drain; until then it is only hidden from listingsnexus state
Shows what the platform is still holding on behalf of a message, and — when a process died holding a lease — the one way out of it. Both belong to flow state: the deduplication table and the open correlations.
nexus state list
Two sections, one command. An operator asking “what is this installation still carrying?” has one question, not two.
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
all tenants | Show only this tenant |
--flow <f> |
all flows | Show only this flow |
--status <s> |
in_flight for deduplication, open + timed_out for correlations |
Deduplication: in_flight, done, failed. Correlations: open, timed_out, closed, closed_late. Or all, for both tables unfiltered |
--limit <n> |
50 | Maximum rows printed |
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus state list --tenant acme== deduplication (flow_inbox) ==
nothing in flow_inbox for this scope
== correlations (flow_correlations) ==acme/submit-claim (step ask-assessor) status: timed_out opened: 2026-09-09T15:03:53Z deadline: 2026-09-09T15:18:53Z on timeout: escalate-claim corr-id: bfcc484b-761b-43c8-8fd2-a56e5e6b0f69 state: present key-hash: 6b09b1aa127867866185426a05f22592f65f5863f8f66a7c10e1fa3ef6fbbc0b
acme/submit-claim (step ask-assessor) status: open opened: 2026-09-09T15:31:10Z deadline: 2026-09-09T15:46:10Z past due (not yet reconciled) on timeout: escalate-claim corr-id: f235209b-838a-4aa1-b89a-b456d56ab8e1 state: present key-hash: 47944a0b00571c60a949dfbbd144431f98519b8dd2ead062c1a55a1566e38d6b
in this scope — open: 1, timed_out: 2The first line of each block is the flow, not the fingerprint: key-hash is the handle
nexus state release takes, not what you scan the page for, so it comes
last. deadline carries a verdict only when it adds one — past due (not yet reconciled) means
the once-a-minute reconcile pass has not reached the row yet, which is not timed_out.
state is present or none: the row says whether a correlation_state was declared, never
what it holds.
--status is checked against the union of the two vocabularies, which have no value in common,
so one flag filters both sections without ambiguity.
This command needs no NEXUS_SECRET_NEXUS_STATE_KEY, deliberately: a server whose state key is
missing refuses to start, and that is exactly the moment you most need to see the table. It also
means the business keys are not shown — the table stores fingerprints, and without the key
nothing here could reverse one.
dedup_key state diagram
The three values --status accepts on the deduplication side are also the row’s life cycle:
(no row) │ │ claim — new key, or the previous row's window/lease has expired ▼ in_flight │ ├── the flow succeeds ─────────▶ done │ └── the flow errors or faults ──▶ failed
done / failed, once dedup_window_hours has passed ──▶ (no row)A row only ever holds one of these three. What a duplicate delivery of the same key gets while a row is in each of them:
in_flight— held back, not run. The caller (or the retry) waits for this one to finish.done— replayed, not run. With or without the recorded body, depending ondedup_memoize_response:.failed— replayed underdedup_on_failure: absorb; runs again, as a fresh attempt, under the defaultretry.
in_flight is the only state nexus state release can act on — done and failed are already
holding an answer, so releasing them has nothing to do. And it only has anything to do while the
lease is still held: if the lease has already expired, the next delivery reclaims the row on its
own, the same way it would after release, without needing the command at all.
nexus state release
Clears the lease on one row so the next delivery of that key may run.
This authorises a second concurrent execution. Nothing stops the process holding the lease —
cancellation does not exist — and the platform cannot tell you whether it is still alive. If it
is, the message runs twice, effects included. Hence the flag: without
--accept-double-execution the command refuses and prints the row it would have released.
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Required |
--flow <f> |
— | Required |
--key-hash <h> |
— | The fingerprint, as state list prints it. Mutually exclusive with --key |
--key <k> |
— | The business key as the flow author wrote it. Needs the state key in the environment |
--accept-double-execution |
off | Required to actually release |
--db <path> |
~/.nexus/registry.db |
Registry database |
Prefer --key-hash when the key is personal data: a command-line argument is visible in ps and
lands in shell history, which is the exposure the fingerprinting exists to close.
nexus tenant
Registers and manages tenants. A tenant is a real row, not just a path segment: nexus deploy and
nexus keys create both refuse one that was never registered, and api_keys.tenant_id carries a
foreign key to it.
nexus tenant create
| Flag | Default | Meaning |
|---|---|---|
--id <t> |
— | The identifier that appears in route paths. Required |
--display-name <n> |
— | Human-readable name. Required |
--auth-methods <list> |
api_key |
Ordered, comma-separated. See below |
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus tenant create --id acme --display-name "Acme Ltd"registered tenant acme display name: Acme Ltd auth methods: api_key
Next: nexus keys create --tenant acme --label <label>--auth-methods is the ordered list of ways a caller may authenticate as this tenant, and the
first method that produces a result decides — there is no retry after a failure. api_key is
the only method this build can perform, so anything else is refused at registration rather than
stored for later: a tenant carrying a method nobody implements is a tenant nobody can enter, and
the failure would surface as a 401 that no configuration explains.
nexus tenant list
$ nexus tenant listid display name status auth methods created_at----------------------------------------------------------------------------------------------------acme Acme Ltd active api_key 2026-08-13T09:14:02Zglobex Globex disabled api_key 2026-07-02T11:40:55Znexus tenant disable
Marks a tenant as disabled. It does not delete anything — the row, its keys and its artifacts stay, and the listing keeps showing it, marked. An operator has to be able to see what they turned off.
$ nexus tenant disable --id globexdisabled tenant globex its API keys stop working immediately; nothing was deleted.Callers of a disabled tenant get 404, byte-for-byte the same answer as a flow that does not exist — a disabled tenant and one that never existed must be indistinguishable from outside.
nexus tenant enable
Puts a disabled tenant back into service.
$ nexus tenant enable --id globexenabled tenant globex its existing API keys authenticate again; none were reissued.Read that second line carefully. disable never touched the keys, so re-enabling makes every
key of the tenant authenticate again, at once, including any you had forgotten about. If disabling
was a response to a leaked credential, revoke the key before you enable the tenant — re-enabling is
not a review.
Both acts are written to the tenant’s audit chain (tenant.disabled, tenant.enabled), which is the
only place either is legible: from outside, a tenant going down and coming back looks like nothing
at all. Running the command on a tenant that is already active succeeds and records nothing — there
was no act to record.
nexus keys
Creates and manages API keys for a tenant. The tenant must exist first
(nexus tenant create).
nexus keys create
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Tenant the key belongs to, required |
--label <l> |
— | Human-readable label, required |
--scopes <list> |
* |
Comma-separated scopes; * grants all |
--expires-at <ts> |
never | 2027-01-01 (the whole of that day, UTC) or 2027-01-01T00:00:00Z (an instant). A timezone offset is refused — convert to UTC first |
--rate-limit <rps> |
unlimited | Sustained requests per second; burst is twice that |
--flows <list> |
all flows | Comma-separated flow names this key may call |
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus keys create --tenant acme --label 'CI pipeline key' \ --scopes 'run:orders,run:invoices' --rate-limit 20 \ --flows 'order-processor,invoice-generator'
created API key id=4 tenant: acme label: CI pipeline key scopes: run:orders, run:invoices flows: order-processor, invoice-generator rate limit: 20 req/s (burst 40)
key (copy now — not stored): nxk_4f19c0b27ad3489e93f5c1e6a70d2b84
Usage: Authorization: Bearer nxk_4f19c0b27ad3489e93f5c1e6a70d2b84Only a hash of the key is stored. The line above is the one and only time the key is printed — lose it and you create a new one.
nexus keys list
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Required |
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus keys list --tenant acmeid label status flows scopes created_at--------------------------------------------------------------------------------------------------------------4 CI pipeline key active order-processor,inv run:orders,run:invoices 2026-08-06T09:02:11Z3 legacy integration revoked * * 2026-05-14T08:33:57Zstatus is active, revoked, or expired.
nexus keys revoke
| Flag | Default | Meaning |
|---|---|---|
--id <n> |
— | Row ID from keys list, required |
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus keys revoke --id 4revoked API key id=4Revoking a key that does not exist, or is already revoked, exits 1.
nexus proto
Publishes and inspects the protobuf descriptors that gRPC steps compile against. See gRPC and protobuf descriptors.
nexus proto deploy
| Flag | Default | Meaning |
|---|---|---|
<path> |
— | A FileDescriptorSet file. Positional, required |
--tenant <t> |
— | Tenant the descriptor belongs to, required |
--name <n> |
— | The name flows refer to, required |
--version <v> |
— | Contract version, required |
--latest |
off | Also point latest at this version |
--db <path> |
~/.nexus/registry.db |
Registry database |
Produce the descriptor with your own protoc. --include_imports is required: without it the
type references cannot be linked and the descriptor is rejected here rather than failing on
every call.
$ protoc --include_imports -o orders.binpb orders.proto
$ nexus proto deploy orders.binpb --tenant acme --name orders --version 2.1.0 --latestdeployed acme/orders@2.1.0 hash: 4c8a1e07b93d25f6 size: 8412 bytes latest -> 2.1.0Publishing a version twice is an error. Moving latest is a separate act on purpose: it changes
what every flow of that tenant puts on the wire, all at once. Without --latest the command says
latest unchanged (pass --latest to move it).
nexus proto list
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Required |
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus proto list --tenant acmeNAME VERSION HASH LATEST DEPLOYEDorders 2.1.0 4c8a1e07b93d25f6 yes 2026-08-06T09:20:44Zorders 2.0.0 b70f3d92c1a84e56 2026-06-19T14:07:02Znexus proto show
Lists the services and methods a descriptor declares, with the streaming kind of each method.
| Flag | Default | Meaning |
|---|---|---|
--tenant <t> |
— | Required |
--name <n> |
— | Required |
--version <v> |
latest |
Version to inspect |
--db <path> |
~/.nexus/registry.db |
Registry database |
$ nexus proto show --tenant acme --name ordersacme/orders@2.1.0 hash: 4c8a1e07b93d25f6a2b0417de95c38f0b1ad672e94c53b8017fe2a6d4c9081bb deployed: 2026-08-06T09:20:44Z
service acme.orders.v2.OrderService GetOrder (unary) — acme.orders.v2.GetOrderRequest -> acme.orders.v2.Order ListOrders (server streaming) — acme.orders.v2.ListOrdersRequest -> acme.orders.v2.Order UploadBatch (client streaming) — acme.orders.v2.OrderBatch -> acme.orders.v2.BatchAckRead the kind before you write the flow: only unary and server streaming methods can be
called.
nexus cert
Registers certificates and tells you when they expire. The registry holds the public half:
a private key is never stored — a flow points at it by path with tls_client_key:, and rotating
it means replacing that file.
Registering is separate from using. A flow reads its certificate from the path you give it; the registry exists so that you find out about an expiry with enough notice to renew, which at an external authority takes weeks.
nexus cert add
$ nexus cert add /etc/nexus/pki/partner-client.crt \ --tenant acme --name partner-client --kind client_cert
registered id=1 acme/partner-client (client_cert) subject CN=acme-integration,O=Acme Ltd issuer CN=Partner Issuing CA serial 4A040B7020DAC022AA759496C3C712CD1605DC1E valid 2026-03-01T00:00:00Z .. 2028-02-29T23:59:59Z sha256 13889615aee5ceb5ea3ee8af4bc0282f767f028015c6cae3457091f9eb125b8e| Flag | Required | Default | Meaning |
|---|---|---|---|
<path> |
yes | PEM certificate | |
--tenant |
yes | ||
--name |
yes | What you will refer to it by | |
--kind |
no | client_cert |
client_cert, server_cert or ca_cert |
--db |
no | ~/.nexus/registry.db |
Everything shown is read out of the certificate; nothing is supplied alongside it. A registry fed by hand would eventually report an expiry date that is not the certificate’s.
The file is parsed at registration, so pointing at the private key by mistake fails here:
$ nexus cert add /etc/nexus/pki/partner-client.key --tenant acme --name partnererror: the first PEM block is `PRIVATE KEY`, not `CERTIFICATE` — point at the certificate, not at the key or the chainA name that already exists is refused. Rotating is replace.
nexus cert list
$ nexus cert list --tenant acmeNAME KIND EXPIRES STATUSpartner-client client_cert 2027-01-14T00:00:00Z expires in 22 daysregistry-ca ca_cert 2028-02-29T23:59:59Z valid, 690 days left| Flag | Required | Meaning |
|---|---|---|
--tenant |
yes | |
--expiring-in <days> |
no | Only what expires within this many days |
--db |
no |
Soonest expiry first. Already-expired entries are always shown, including under
--expiring-in: they are the urgent case, and a window that only looked forward would go quiet
exactly when the integration breaks.
$ nexus cert list --tenant acme --expiring-in 30That is the line to put in a scheduled job.
nexus cert replace
$ nexus cert replace /etc/nexus/pki/partner-client-2028.crt \ --tenant acme --name partner-client
replaced id=7 acme/partner-client (client_cert) …The previous entry is kept, marked replaced.Same flags as add. The old entry is retired rather than deleted — it is still the answer to
what was being presented on a given date.
Note that this updates the registry, not the flow. The flow reads whatever file
tls_client_key: and tls_client_cert: point at, so the rotation itself is replacing those
files.
nexus cert reconcile
Compares what the deployed flows ask for against what the registry knows. Read-only — it never registers anything.
$ nexus cert reconcile --tenant acmeScanned the `latest` version of each deployed flow.Paths resolve on THIS node's filesystem — another node may hold different files.
UNREADABLE — these flows will fail at their next call: acme/partner-query step 'call' tls_ca_cert: /etc/nexus/pki/partner-ca.pem No such file or directory (os error 2)
NOT REGISTERED — in use, but the registry does not track their expiry: acme/order-push step 'send' tls_client_cert: /etc/nexus/pki/our-client.crt sha256 1388…5b8e register with: nexus cert add /etc/nexus/pki/our-client.crt --tenant acme --name <name>
3 reference(s) in use and registered.
REGISTERED BUT NOT REFERENCED — spare material, or a leftover: acme/old-client (client_cert) expires 2027-01-14T00:00:00Z| Flag | Required | Meaning |
|---|---|---|
--tenant |
no | Narrow to one tenant. Omit to cover all |
--db |
no |
Four verdicts, in the order they matter:
Unreadable is the one worth running this for. The flow is deployed and its TLS material is not there, so its next call fails — with an error that deliberately does not name the path. Finding that out before the call is worth more than any expiry warning.
Not registered means the certificate is in use but nothing tracks when it expires. The
fingerprint and the exact nexus cert add line are printed so registering is a copy and a paste.
Registered but not referenced is not an error. It may be spare material staged for a rotation, or it may be left over from one — the difference is yours to make.
Could not be scanned appears when a flow’s artifact cannot be read at all. It is listed separately rather than skipped: a shorter list would look exactly like a clean result.
Two limits, both stated in the output rather than assumed:
- Only the
latestversion of each flow is scanned. Older versions may legitimately reference paths that no longer exist. - Paths resolve on the filesystem of the node you run this on. The registry is shared between
nodes;
/etc/nexus/pkiis not.
nexus cert show
$ nexus cert show --tenant acme --name partner-clientThe current entry followed by every retired one, newest first, each with its facts, when it was registered, and its status.
nexus seed
Deploys a directory of demo flows, creates demo API keys and UI users, and runs each flow once. Useful for getting a populated instance to look at.
| Flag | Default | Meaning |
|---|---|---|
--db <path> |
~/.nexus/registry.db |
Registry database; the UI database is created beside it |
--demo-dir <dir> |
./examples/demo |
Directory of .flow.md files to deploy |
--no-run |
off | Deploy and create keys and users, but do not execute the flows |
$ nexus seed --no-runNexusFabric seed registry db: /home/you/.nexus/registry.db ui db: /home/you/.nexus/nexus-ui.db demo dir: /home/you/examples/demo
── Deploying flows ───────────────────────────────── deployed acme/order-processor v1.0.0 ...Flows are deployed at version 1.0.0 and latest is moved, so running it twice is harmless.
UI users are skipped if the username already exists. API keys are created fresh every time, and
each one is printed once.
The command fails if the demo directory does not exist.
nexus simulate
Generates mixed synchronous and asynchronous traffic against a running server, so the logs,
statistics and audit trail have something in them. It calls the flows that nexus seed deploys,
so run seed and serve first.
| Flag | Default | Meaning |
|---|---|---|
--url <base> |
http://localhost:9090 |
Base URL of the server |
--duration <secs> |
run until interrupted | Stop after this many seconds |
--api-key <tenant>=<key> |
none | An API key for one tenant. Repeatable, once per tenant. Also read from NEXUS_SIMULATE_API_KEYS as a comma-separated list |
A key is issued to one tenant, and the simulation drives three (acme, demo, test), so the
tenant is part of the flag: a bare key is refused, because it could only authenticate a third of the
traffic. Tenants you give no key for are skipped, and the run says so at start and in the summary.
nexus seed prints a ready-to-paste line with the three keys it created.
Without any key the run still starts — a server on --no-auth needs none — and stops at the first
401 with the command that issues one. Requests refused with 403 (missing scope, or a flow outside
the key’s allowlist) or 404 (flow not deployed) withdraw that flow from the rotation instead of
ending the run, and the final line breaks errors down by class.
$ nexus simulate --duration 120 --api-key acme=nxk_... --api-key demo=nxk_... --api-key test=nxk_...Roughly a third of the requests go through /enqueue so that queue workers run and write audit
events; the rest go through /run. The rate varies between quiet, steady, burst and spike
phases rather than holding one constant rate.