Skip to content

Command line

Every command of the nexus binary, every flag, and what each one defaults to.

Terminal window
$ nexus --help
$ nexus --version

State 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
Terminal window
$ nexus validate forward-order.flow.md
ok forward-order.flow.md
flow: forward-order
tenant: acme
steps: 3

validate 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
Terminal window
$ 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:

Terminal window
$ nexus compile forward-order.flow.md --output forward-order.ir.json
ok forward-order.flow.md → forward-order.ir.json
hash: 9f2b7c4d1ae05836b1c0d4f7a83e2916d5b0c7314ea9f6d8b2c5107e43ab9d02

nexus 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
Terminal window
$ nexus deploy forward-order.flow.md --version 1.2.0
deployed forward-order.flow.md
flow: forward-order
tenant: acme
version: 1.2.0
hash: 9f2b7c4d1ae05836b1c0d4f7a83e2916d5b0c7314ea9f6d8b2c5107e43ab9d02
db: /home/you/.nexus/registry.db

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

Terminal window
$ nexus serve --port 9090
NexusFabric 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: enabled

Started 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:

Terminal window
$ nexus serve
error: 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 picture

The 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
Terminal window
$ nexus config check
Configuration required by deployed flows:
acme/submit-reading BILLING_URL (NEXUS_CONFIG_BILLING_URL) — set
acme/submit-reading PARTNER_ENDPOINT (NEXUS_CONFIG_PARTNER_ENDPOINT) — MISSING
error: 1 declared key(s) have no value: PARTNER_ENDPOINT (NEXUS_CONFIG_PARTNER_ENDPOINT). `nexus serve` will refuse to start

Exits 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 from MISSING. 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
Terminal window
$ nexus audit --tenant acme --limit 3 --verify
seq event_type created_at correlation_id
------------------------------------------------------------------------------------------
1187 queue.message.processed 2026-08-06T09:14:22Z 7f3a1c02-9b6e-4f11-8a2d-0d55c3b41e90
1186 queue.message.failed 2026-08-06T09:14:19Z 7f3a1c02-9b6e-4f11-8a2d-0d55c3b41e90
1185 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/
Terminal window
$ nexus dlq list --tenant acme
DLQ: 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 out

With 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/
Terminal window
$ nexus dlq replay --tenant acme --flow order-processor --id 17
replayed id=17 tenant=acme flow=order-processor

nexus 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/
Terminal window
$ nexus dlq discard --tenant acme --flow order-processor --id 17
discarded 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 listings

nexus 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
Terminal window
$ 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: 2

The 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 on dedup_memoize_response:.
  • failed — replayed under dedup_on_failure: absorb; runs again, as a fresh attempt, under the default retry.

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
Terminal window
$ 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

Terminal window
$ nexus tenant list
id display name status auth methods created_at
----------------------------------------------------------------------------------------------------
acme Acme Ltd active api_key 2026-08-13T09:14:02Z
globex Globex disabled api_key 2026-07-02T11:40:55Z

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

Terminal window
$ nexus tenant disable --id globex
disabled 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.

Terminal window
$ nexus tenant enable --id globex
enabled 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
Terminal window
$ 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_4f19c0b27ad3489e93f5c1e6a70d2b84

Only 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
Terminal window
$ nexus keys list --tenant acme
id label status flows scopes created_at
--------------------------------------------------------------------------------------------------------------
4 CI pipeline key active order-processor,inv run:orders,run:invoices 2026-08-06T09:02:11Z
3 legacy integration revoked * * 2026-05-14T08:33:57Z

status 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
Terminal window
$ nexus keys revoke --id 4
revoked API key id=4

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

Terminal window
$ protoc --include_imports -o orders.binpb orders.proto
$ nexus proto deploy orders.binpb --tenant acme --name orders --version 2.1.0 --latest
deployed acme/[email protected]
hash: 4c8a1e07b93d25f6
size: 8412 bytes
latest -> 2.1.0

Publishing 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
Terminal window
$ nexus proto list --tenant acme
NAME VERSION HASH LATEST DEPLOYED
orders 2.1.0 4c8a1e07b93d25f6 yes 2026-08-06T09:20:44Z
orders 2.0.0 b70f3d92c1a84e56 2026-06-19T14:07:02Z

nexus 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
Terminal window
$ nexus proto show --tenant acme --name orders
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.BatchAck

Read 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

Terminal window
$ 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:

Terminal window
$ nexus cert add /etc/nexus/pki/partner-client.key --tenant acme --name partner
error: the first PEM block is `PRIVATE KEY`, not `CERTIFICATE` — point at the certificate, not at the key or the chain

A name that already exists is refused. Rotating is replace.

nexus cert list

Terminal window
$ nexus cert list --tenant acme
NAME KIND EXPIRES STATUS
partner-client client_cert 2027-01-14T00:00:00Z expires in 22 days
registry-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.

Terminal window
$ nexus cert list --tenant acme --expiring-in 30

That is the line to put in a scheduled job.

nexus cert replace

Terminal window
$ 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.

Terminal window
$ nexus cert reconcile --tenant acme
Scanned 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 latest version 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/pki is not.

nexus cert show

Terminal window
$ nexus cert show --tenant acme --name partner-client

The 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
Terminal window
$ nexus seed --no-run
NexusFabric 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.

Terminal window
$ 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.