@open-matrix/system-auth (1.1.32)
Installation
@open-matrix:registry=npm install @open-matrix/system-auth@1.1.32"@open-matrix/system-auth": "1.1.32"About this package
@open-matrix/system-auth
Bus-addressable Matrix authentication primitives.
Related UX research: signup, provisioning and pairing. The proposals preserve task continuation and distinguish account availability, device approval, saved credentials and local readiness. Starter defaults do not imply native installation or an implemented pack editor. This is interaction guidance for consideration, not a new auth protocol, consent rule or provisioning owner.
Home projections serialize the services account's resolver read, lane merge and
claim publication by its public key across all adapters in the owning system.auth
process. Concurrent homes retain each other's machine-inference and chat-activity
imports and live revocations. The existing per-home barrier still orders credential
issuance and retirement. Deploy shares one offline runtime-credential reconciler:
mint-account receives no resolver connection and preserves an existing sealed
credential. Only system.auth publishes online changes to the services claim; deploy's
birth state cannot replace its signed-up homes. Initial broker rendering still owns
birth claims before the service starts. Run
pnpm exec node --import tsx --test src/__tests__/nats-authority-claim-race.spec.ts src/__tests__/deploy-services-claim.spec.ts
from this package for the merge and deploy regressions. The deploy regression requires
nats-server on PATH, starts an isolated resolver, and checks the live claim and
credential across initial issuance and replay without Docker.
The starter-application writer keeps one services-account NATS session and
renews its scoped credential at four-fifths of the JWT lifetime through the
shared SDK refresh owner. JWT callbacks read the renewed credential on the same
connection, preserving its reply inbox across expiry. A closed connection, or
a reconnecting connection whose current credential is expired, is closed and
replaced before another projection is sent. The issuer's 300-second TTL is not
changed. starter-writer-credential-refresh.spec.ts proves this boundary with
an isolated real nats-server and a seconds-long credential.
profile.update announces profile.changed after saving, with an empty payload.
Recipients come from auth.namespace.list for the authenticated principal, never
from the request. The platform publishes on system.profile.<home>.$events;
the account bridge requires a signed stream activation for that exact home and
imports it as <home>.system.profile.$events. Other accounts cannot import it.
Consumers subscribe before profile.get and reread on invalidation or reconnect.
The existing account reconciliation installs these imports; browser user grants
already allow their own home subtree, so no credential replacement is required.
People management uses the same browser-reachable system.profile boundary.
profile.people.* and profile.homes.invitation.accept resolve the caller only
from the supplied bus token, allow-list their forwarded fields, and invoke the
scope-protected membership operations internally. Browser credentials never gain
direct access to the platform-owned system.auth inbox.
Conversation sharing is a separate per-person PostgreSQL consent record. The
browser reads and changes it only through profile.sharing.get and
profile.sharing.set; each change and each consented builder read is audited.
The record contains only the principal, enabled flag and update time—never a
transcript. The cross-account system.auth.introspect mount admits the verified
owner, or a verified platform.operator while consent is currently enabled.
It refuses a builder read if the audit ledger cannot acknowledge that read.
Application release lifecycle calls use that same browser-reachable profile boundary. The facade resolves the caller from the bus token, allow-lists release, install, update, rollback, uninstall, withdraw and delete fields, and forwards only that verified token to the services-owned release facade. Browser credentials never gain direct access to the Component Store account.
The profile facade similarly exposes profile.tickets.file/list/get/summary while forwarding only
allow-listed ticket fields and the verified bus token to system.tickets. Hosted agent sessions expose
their ticket context only to the session owner, and stamp stored turns with the
request trace used for later ticket evidence. session.replay runs selected user turns in one new
session, in order, with one caller deadline and stops at the first refused prompt.
The operator-only facade also forwards classified transition fixes and bounded profile.tickets.smells
queries; it does not infer fix metadata from commit messages or caller identity.
Discovery follows that boundary through profile.discovery.search. It resolves
the caller from the session bus token, selects only a home projected for that
verified principal, and forwards an allow-listed query to that home's
system.directory registry.search. A caller-supplied authority root cannot
redirect the search into another home.
This package owns Host session tokens, principal state, credential metadata,
the tenant-imported system.auth actor surface, and the platform-account-only
system.auth.controlPlane inventory and bounded operator surface. Host Service
may route HTTP requests to these primitives during the transition, but the state
and bus interface live in this package.
The platform-only control plane includes exact scalar authority-root resolution
without principal inventory disclosure and reversible hosted-probe retirement.
Retirement suspends the principal, disables signup-sourced hosted-service
eligibility, and revokes exact active browser-session NATS users; partial
revocation is a typed, idempotently retryable result.
The retirement receipt does not claim synchronous responder shutdown. The
registry and hosted-application service hosts observe disabled eligibility on
their existing 30-second reconciliation loop; closure must wait beyond one
complete loop and independently prove both responder classes absent for each
retired root while the sanctioned seed remains responsive.
Account deletion records unfinished state owners. WO-2.15 resumes the existing finishing pass at system.auth startup, when an owner's readiness changes to READY, after a new deletion leaves unfinished owners, and periodically while owners remain unfinished, without an operator or a deleted person's session. An empty pass stops polling. The Auth Console's Finish cleaning up remains available. Each pass retains its 3,000 ms budget; an in-flight owner may exceed that budget, so it is a bound on starting another owner, not a cancellation deadline. Passes share one in-flight background operation, and a cursor prevents a slow refusing owner starving later work. A deletion committed during that pass replies successfully with its unfinished owners immediately and requests another pass, so the self-deletion reply never waits behind an older account's owner.
The retry delay is max(3,000 ms, ceil(measured pass duration × 10)), measured afresh with
performance.now() after every pass. The minimum reuses the existing finishing budget;
otherwise at least ten pass-costs separate attempts. The in-process real-owner regression
on 2026-10-03 measured a healthy fresh-home self-deletion at 175 ms and the foreground prefix
at 55 ms (148 ms on the first run), yielding the 3,000 ms minimum locally. Production passes
that take longer automatically reduce the retry rate; no RPC timeout or TTL is increased.
Readiness bursts coalesce and retries do not overlap. Each principal/owner refusal logs its error
once on entry and once on recovery; repeated refusals do not repeat the log. The diagnostic state
is retained only for unfinished owners. Disposal cancels the timer and watches, aborts the pass
before it starts another owner, and waits for its outstanding owner call before disposing the actor.
The regression reproduces the three-owner suffix seen on staging by exhausting the foreground
budget during hosted-application withdrawal: registry, notifications and directory are not
reached on that pass. A subsequent owner-ready transition removes a real directory row while
retaining an unrelated row, after the person's session is already invalid. A healthy no-machine
home completes synchronously. The staging pass timings were not available to this isolated
fixture, so that specific staging cause still requires the coordinator's browser re-walk.
Run pnpm exec node --import tsx --test src/__tests__/account-deletion-convergence.spec.ts src/__tests__/platform-operator-operations.spec.ts from this package for the real-owner boot
and refusal-then-confirmation, startup, periodic, fairness and disposal regressions.
system.notifications is asked before the directory via notification.account.purge {principalId}; the inbox owner independently checks the auth deletion ledger and resolves
its homes. Migration 038 adds this owner to prior deletions, including completed ones.
See docs/platform/accounts.md for the complete ownership order.
Completed device enrollment is a durable notification source. The platform-only
auth.device.notification.get {eventId} operation on system.auth.controlPlane
resolves the recipient from the approved principal's primary home and the device
from its installation association. It returns no credentials. Tenant imports of
system.auth do not expose this operation. Only the first completed enrollment
for a device created within 30 days produces a notification; later enrollment
replays cannot create a new source identity.
Migration 039 adds a delivery watermark to the existing authorization completion row. Finalization, startup and the existing device reconciliation cadence replay up to 100 pending completions from the last 30 days. Refused delivery retains the row and reports a warning. Inbox commits deduplicate by canonical device source; a crash between delivery and its watermark cannot create a second card.
Owned accounts (docs/decisions/0015) notify the same way. A claim, a release
from either side, and an owner's suspend or reactivate queue a row in
account_owner_notices (migration 061). The projection hints
notification.source.reconcile {sourceKind: 'account.owner'}, and
system.notifications reads the recipient's home and text back from the
platform-only auth.account.owner.notification.get {eventId}. A delivered row is
deleted; a refused one stays and is retried.
Durable management audit
PostgreSQL owner transactions enqueue successful account deletion (self/operator), operator grant/revoke, profile update, application selection, device enrollment, label update and revocation outcomes. An intent contains actor, operation, target, result and the home before deletion. Platform-wide operator changes use the configured platform root, not a fabricated home. Audit intents survive account content deletion and are removed only after the ledger acknowledges them.
Replay starts with the actor and uses its existing 60-second maintenance cadence: up to 100 rows per sweep, at most 10,000 pending rows per owner. Capacity refusal rolls back the management mutation instead of dropping an audit event. A lost reply reuses the intent UUID as the ledger idempotency key. These bounds keep outages from growing owner storage indefinitely and let normal work remain cheap. Organization creation, membership add/remove, clean-name activation, service-principal creation and service API-key issue/revoke also enqueue in their owning SQL transactions. Their actor comes from verified bus claims or namespace-administration admission. No-op revocation/name retries add no event; refused transactions add no success record.
Home invitations are PostgreSQL-owned records on the existing Space membership model.
Owners and admins create or withdraw them through namespace-administration admission;
acceptance takes its principal only from a verified bus token. The link contains a random,
single-use code while storage retains only its SHA-256 digest. Invitations expire after seven
days, which bounds the lifetime of a forwarded link without making ordinary handoff timing
fragile. Create, withdraw and accept enqueue their audit event in the same transaction as the
record or membership change. A personal home becomes organization-owned on its first invitation,
preserving its owner as the immutable owner membership. Account deletion follows that ownership
and removes the shared home while leaving invited members' personal homes intact.
Namespace discovery includes each visible home's membership role (owner, admin, or
member), so browser surfaces can distinguish management authority from ordinary entry.
Explicit agent session.create, $sessionDelete, $sessionClearAll and $sessionSeed
mutations enqueue in the same transaction as their session rows. A verified operation
context or signed bus session supplies the audit actor; a payload principalId remains row
owner metadata for owner-scoped listing and audit outcomes, never audit identity. A cheap
existence check first lets idempotent creates and absent deletes avoid an unused authentication
round trip. When validation is needed it completes before opening the mutation transaction;
the subsequent insert/delete and outbox write remain atomic, and a concurrent duplicate create
is harmless and emits no record. An invalid or expired token returns the typed
AUTHENTICATED_PRINCIPAL_REQUIRED refusal, while an authentication transport failure retains
its request/reply code instead of being mislabeled as an authorization refusal. Calls with no
caller proof are labeled actorType: system. Delete records name the caller and retain the
stored owner in the outcome; clear-all records its cleared count. The implicit
session created by a hosted Chat $prompt is conversation persistence, not a management
mutation, and does not enter the capacity-checked management outbox.
Profile updates, device label/revocation and application selections retain the existing trusted internal profile-facade provenance: that facade resolves the account identity before forwarding its principal. The central mutation does not independently verify that forwarded human identity. Application selection requires an explicit actor and never infers the actor from the home's owner.
Installation enrollment-token issuance forwards the already verified browser session
from the profile facade to the API-key owner. The owner validates that proof and records
the person, rather than system, on the single auth.apiKey.issue intent committed with
the short-lived enrollment key.
Principal creation/identity linking, anonymous password signup, password reset,
space creation/default selection, namespace claim, ordinary API-key issue/revoke,
workspace-realm changes and seed application also commit one owner intent. The
PostgreSQL workspace-realm operation now updates the durable principal instead
of the unused legacy file store. Seed application writes one event for its whole
transaction; unchanged seed retries add none. Namespace claim returns its committed
claim immediately; its former best-effort audit append response is no longer returned.
Raw central operations already require the platform broker boundary. Calls without
human proof at that boundary record actorType: system, with the source owner as
subject and no invented principal: this includes anonymous signup, provider-driven
creation and internal credential finalization/compensation. This identifies the
service performing provisioning, not an authenticated signup user. A supplied bus
token, browser headers or API key must validate; invalid proof never falls back to
system. Verified ordinary mutations bind the target to that principal. HTTP key
management forwards browser proof or the API key and rechecks its existing
account:api-keys:manage scope; CLI authorization-code exchange forwards its saved
browser proof. Namespace and workspace-realm HTTP operations forward browser proof.
No credentials, seed contents or password material enter audit intents.
Device approval, denial and cancellation commit one intent with the verified approver, request ID and approved/denied outcome; stale and repeated decisions add none. Failed/refused operations and runtime mutations remain outside this producer; runtime/host-control is separately owned. Credential issuance/session refresh and NATS projection/reconciliation are authentication transport, not account-management mutations in this matrix. File-backed development auth has no PostgreSQL outbox.
The platform-owned service bridge also carries system.notifications and system.audit
requests into the platform account; notification events return through a protected stream
import for hosted-home fanout. These central owner inboxes are never imported by tenants.
Runtime-host registration and pairing
An account-wide key cannot activate a first-seen machine. auth.apiKey.exchangeForRuntimeHost
records it with pending association state and returns DEVICE_PAIRING_REQUIRED before issuing
any broker credential, including when a legacy caller omits installId. Repeated attempts retain
the pending device ID. Browser approval or an installation-bound enrollment token completes pairing
and records installation key and broker credential lineage. Demo provisioning uses that token path.
Existing legacy active rows retain their state and the suspension/deletion lineage refusals;
registration does not relabel an already-issued untracked credential as harmless pending enrollment.
The account-key-pairing.spec.ts regression runs the real auth actor and stores against isolated
PostgreSQL, observes zero issuer calls for pending devices, and exercises the demo provisioner's
identity client with requests dispatched into the real token finalizer and runtime-host exchange.
Machine removal with account deletion
PostgresAccountDeviceStore and PostgresInstallationGrantStore own machine enrollment.
The account device row also owns the machine-to-HiveDock join: authenticated registration records
a supplied HiveDock ID, and the next managed heartbeat reads and backfills it without a manual step.
The account-deletion transaction locks installation grants and snapshots their unretired
NATS public identities into migration 041’s pending_device_credentials ledger column
before removing enrollments and grants. The account-devices finalizer runs first and
asks the credential authority to revoke each identity, including derivatives in another
home. Successful revocations remove only their own public identity; failure keeps the
owner unfinished for the existing retry surface. A replay cannot purge a live account.
No secret is retained. Incomplete legacy lineage refuses deletion before credential cuts;
re-enroll or retire the machine first. Already-deleted lineage cannot be recovered.
auth.platform.accounts.list includes machineCount, the number of active device
associations, including pending enrollment. Auth Console uses it in single and bulk
confirmations; Settings reads its own current device list before opening confirmation.
This disconnects platform access and forgets enrollment, not the physical computer’s OS.
No new retry interval, timeout or TTL is introduced by this finalizer.
Run pnpm --filter @open-matrix/system-auth test. The deletion-store regression checks
retained identities, retries, live-account refusal and incomplete lineage. The real NATS
factory spec deletes an enrolled account, verifies its connected credential is cut and
cannot reconnect, and verifies a bystander credential in the same root still works.
Account suspension and reactivation
auth.platform.account.suspend {principalId, reason, sessionToken} and
auth.platform.account.reactivate {principalId, sessionToken} require a platform operator.
They refuse self, other operators and service principals. Migration 042 records a monotonic
session epoch, current session families, retained service selections and unfinished public
credential revocations. Issuance holds the account row lock; suspension captures credentials
before committing the inactive account. Each completed cut is durable. Retry Suspend finishes
a partial cut; Reactivate refuses until all cuts finish. Enrollment, keys and account data stay.
sessionCount is null for legacy accounts whose old sessions were never inventoried; the console
says unavailable. New sessions share one family across sliding renewal. Older epochs never revive.
The password path checks the password before disclosing suspension and keeps the existing backoff.
The notification uses existing operator-authenticated announcement.post, home-targeted, with
its banner expiry taken from that operator session's existing policy. Failed delivery remains
visible in inventory for an operator retry; no session token is stored. There is no new timer,
retry interval or TTL. A crash after posting but before acknowledgement may duplicate a notice.
The retained-installation refresh seam accepts an omitted profile label only for an authenticated
installation grant: grants and device binding, not that label, determine its credential authority.
Runtime-host-engine and identity-client own sealed-file refresh; host-auth-store owns the signed
session epoch and stable family. Those are the necessary owner changes outside system-auth.
pnpm --filter @open-matrix/system-auth test includes real password/session suspension and
reactivation, durable-cut retry, real NATS old-credential refusal and fresh-credential reconnect.
The account-device store spec runs against an isolated PostgreSQL wire-protocol database in the default test suite. It covers owner-scoped rename, revision fencing, last-seen updates, and retirement retained across a refused reconnect; it does not need a live environment.
Home convergence visibility
auth.platform.home.status and auth.platform.home.retry require the session's
platform.operator capability before reading or changing a home. The profile facade exposes
these as profile.platform.home.status / profile.platform.home.retry. A retry resolves the
active home owner and calls HomeReconciliationCoordinator.retryNow: it bypasses only that
home's backoff, refuses an already-satisfied projection, and still respects the existing durable
lease and concurrency admission. auth.platform.homes.notReady returns every durable receipt
whose state is not ready, oldest change first, including the secret-redacted diagnostic and
last-change time needed during an outage.
auth.platform.principals.count and auth.platform.conversations.count expose owner-computed
inventory to operators; conversations remain grouped by home and target key. The profile facade
also reaches Registry claim and Directory row count operations through their well-known owner
mounts. Every non-operator refusal names platform.operator and its owner, system.auth.
The canonical account.lifecycle notification source alerts every current operator home when an
account deletion remains unfinished for 15 minutes. Normal foreground cleanup has a three-second
budget, so the horizon leaves ample time for transient owner recovery without hiding
a sustained outage. The home.projection source uses the same 15-minute horizon, spanning three
maximum five-minute coordinator backoff windows. It creates one card per home failure episode and
clears that card when the home becomes ready. Both cards direct operators to the Auth Console;
their audience and content come only from the auth owner's durable rows. A founding operator's
grant is still recorded lazily by the first platform.operator capability check; until then that
account is intentionally absent from lifecycle-notification snapshots.
profile.home.status resolves the caller through the normal profile authentication path;
it accepts no principal override and cannot select another home's state. Its central read,
auth.home.status, uses that principal's current primary authority root. All reads go through
PostgresHomeProjectionStatusStore, returning state, attempt, next retry, safe step words,
last error code, failure start and last confirmed convergence. Platform-operator reads also
return the secret-redacted lastErrorMessage persisted by migration 046; person-scoped reads
deliberately omit that diagnostic. Migration 043 preserves the
last convergence across failures and the first failure across retries. History before this
migration is unknown, never inferred from an unrelated row update.
The actor's periodic bounded sweep calls resumeOutstanding every minute. A recovering home
whose next_retry_at is past and whose lease is free is selected again automatically, so a
deployment that restores the failed dependency converges stuck homes without logout, reload,
or an operator retry. The real-Postgres reconciliation suite runs against an isolated database
in the default package gate and covers overdue attempt-one and attempt-two rows directly through
the production selector. Acquiring a retry lease retains the previous operator diagnostic while
the new attempt is in flight; only that attempt's settlement replaces or clears the message.
Removing untracked offline devices
profile.devices.forget {deviceId, expectedAssociationRevision} resolves the caller exactly
like device revocation and delegates to auth.device.forget. Only an owned device with no
installation grant (including historical grants) and a known last-seen older than
DEVICE_OFFLINE_AFTER_MS can be forgotten. Refusals are DEVICE_HAS_GRANT (use Retire),
DEVICE_RECENTLY_SEEN, DEVICE_NOT_FOUND, and ASSOCIATION_REVISION_STALE.
Migration 044 preserves the row as revoked with forgotten_at; the list excludes it and
suspension no longer treats it as active incomplete history. The same transaction writes
one account audit intent. An exact retry returns the completed removal without another audit.
A returning installation receives a new pending device ID, retaining the old history.
Legacy host credential exchange checks inventory before issuance and returns
DEVICE_PAIRING_REQUIRED until pairing grants authority; repeated check-ins stay pending.
The owner schema and package/control declarations are required companion changes outside src.
Run pnpm --filter @open-matrix/system-auth test for store and in-process actor regressions.
Agent session credential redaction
PostgresAgentSessionStore applies the shared @open-matrix/core credential redactor before
writing message content, titles and session state. The SQLite backfill uses the store's same
helpers for titles, message content, tool arguments/results and state. Derived titles redact the
complete first message before the 72-character summary, including for pre-existing messages.
State uses shape-only, span-scoped redaction on decoded JSON string values or plain text.
It has no recursive depth cutoff and never withholds a value merely because its field is named
secret, password or apiKey. Credential-free serialized state retains its exact bytes, including
whitespace, escaped characters and large numeric literals. This covers prompts, seeded transcripts,
direct canvas/harness state writes and failure activity without replacing deep documents.
The home-side AgentsStore.saveSessionState also preserves ordinary state, but stores it verbatim;
the two implementations agree on ordinary documents, not on credential-bearing state at rest.
agent-session-redaction.spec.ts exercises the actor through request/reply and checks the raw
rows in a disposable PGlite database; it requires neither Docker nor a running environment.
agent-session-backfill.live.spec.ts verifies the actual SQLite import on PGlite and checks all
imported content fields. Redaction covers recognized shapes in these content fields, not arbitrary
metadata identifiers or unrecognizable secrets. Existing rows are not scanned or migrated, and
backfill still leaves conflicts untouched. Their cleanup decision is recorded in
2026-10-03-platform-agent-sessions-replay-credentials.
Password signup and Settings share readProfileDisplayName from @open-matrix/contracts: trim,
collapse whitespace, and cap at 120 characters. Registration requires a nonblank displayName;
the password principal stores that name. OAuth retains the provider's name.
Schema initialization
SystemAuthActor.onBootstrap awaits the schema owner before starting account or home
reconciliation. PostgreSQL accessors use the initialized database without process-local
readiness requirements, so the HTTP runtime's shared admission reader remains usable.
The actor fences every declared auth operation until its schema is ready; password sign-in cannot start or
retry migrations. A database outage at boot intentionally fails service startup; supervision
restarts the service instead of running it in a degraded state. Auth requests arriving
before or during initialization, or after a failed startup, immediately receive
{ ok: false, error: "AUTHENTICATION_SERVICE_UNAVAILABLE", retryable: true }.
Only an explicit service start or administrative initialization retries a failed migration.
Standalone seed administration and tools/migration/backfill-agent-sessions.mjs initialize
explicitly. The backfill command leaves report-only discovery read-only and closes its database
pool on exit. Store-only tests must initialize their disposable database with
migrateSystemAuthPostgres before querying it.
password-login-schema.spec.ts counts migration-table statements on an already-migrated
PGlite database and covers cold requests, startup, failed startup and explicit startup retry.
It also drives auth.nats.account.ensure and password login through the subscribed inbox
before bootstrap and during a held migration, then verifies account ensure after startup.
agent-session-backfill.live.spec.ts also runs the standalone command against a fresh database
and checks the copied conversation. These regressions require neither Docker nor a running environment.
Conversation target keys
Platform prompts and Chat share SDK core's canonicalTargetKey:
<authorityRoot>\u001F<logicalMount>, with an optional interface qualifier.
$sessionList reads canonical, legacy dotted, and legacy bare-mount keys in a
single tenant-scoped query, with the existing ordering and result limit. Stored
keys are not rewritten. Interface-qualified sessions remain separate.
agent-session-target-key.spec.ts covers platform-created conversations, legacy
reads, tenant isolation, and preservation of stored keys.
Conversation list pages
$sessionList accepts targetKey or principalId, plus optional cursor and
limit. Pages default to 50, clamp to 1–100, and order by last activity then
session ID descending. Pass the returned nextCursor unchanged to fetch older
conversations; its absence means the end. Cursors retain the ordering values,
so deleting the boundary conversation does not skip the following page. Every
page retains the existing tenant/selection checks. There is no title-search
operation yet; that is tracked in the Chat title-search queue item.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @node-oauth/oauth2-server | 5.3.1 |
| @open-matrix/contracts | 1.1.32 |
| @open-matrix/core | 1.1.32 |
| @open-matrix/host-auth-store | 1.1.32 |
| @open-matrix/nats-auth | 1.1.32 |
| @open-matrix/nats-authority-port | 1.1.32 |
| @open-matrix/package-runtime | 1.1.32 |
| @open-matrix/sqlite-store | 1.1.32 |
| @open-matrix/subjects | 1.1.32 |
| @open-matrix/system-audit | 1.1.32 |
| @open-matrix/system-postgres | 1.1.32 |
| nats | ^2.29.3 |
Development Dependencies
| ID | Version |
|---|---|
| @matrix/test-utils | 1.1.32 |
| @open-matrix/nats-authority-nauth | 1.1.32 |
| @types/node | ^25.0.10 |
| esbuild | ^0.25.0 |
| tsx | ^4.0.0 |
| typescript | ^5.3.0 |
Peer Dependencies
| ID | Version |
|---|---|
| @open-matrix/nats-authority-nauth | 1.1.32 |