Enterprise Identity & Access Management (IAM)
Self-Hosted • Privacy-First • Pure Rust • Single Binary • SQLite & PostgreSQL
nx9-auth is a self-hosted Identity & Access Management (IAM) server built entirely in Rust. It provides centralized authentication, multi-tenancy, fine-grained Role-Based Access Control (RBAC), Personal Access Tokens (PATs), service accounts, application registration credentials, active session management, and append-only audit logging.
The server uses Axum, Tokio, and SQLx, with repository implementations for both embedded SQLite and external PostgreSQL deployments. Its administration interface is built with Dioxus 0.6 and compiled to WebAssembly (WASM), requiring no Node.js or npm runtime/build chain for the application architecture.
The runtime lifecycle and Application Registration Credentials subsystems have completed dedicated production-hardening passes covering deterministic shutdown, live signal escalation, transactional credential operations, secret handling, authorization boundaries, redirect URI validation, and regression testing.
- Deterministic Runtime Lifecycle: Atomic 8-state lifecycle (
Initializing→Starting→Running→Draining→StoppingWorkers→ExecutingHooks→ClosingResources→Stopped) with graph-validated transitions, cancellation propagation, supervised worker shutdown, HTTP draining, prioritized shutdown hooks, and live forced escalation on a second Unix termination signal. - SQLite & PostgreSQL Support: Shared repository abstraction with backend-specific migrations and repository implementations for embedded SQLite and external PostgreSQL deployments.
- Security-Oriented Authentication: Argon2id password hashing, BLAKE3 credential/token digests, constant-time credential comparison, rate limiting, non-enumerating authentication failures, secret redaction, and security response headers.
- Multi-Tenant RBAC: Tenant-aware identities, fine-grained permissions, role assignments, and organizational user groups.
- Personal Access Tokens & Service Accounts: Credentials for API and machine-to-machine access with hashed-at-rest secrets and revocation support.
- Application Registration Credentials: Immutable server-generated Client IDs, one-time Client Secret disclosure, BLAKE3 secret hashing, constant-time verification, secret rotation, redirect URI metadata, scopes, and dedicated
applications:manageauthorization. - Transactional Credential Integrity: Application creation and Client Secret rotation are committed atomically with their audit records; audit failure rolls back the associated credential operation.
- Strict Application Identity: Application authentication uses
client_idonly; editable application slugs are never accepted as credential identities. - Redirect URI Policy: Registered redirect URIs are structurally validated. HTTPS is supported generally; HTTP is restricted to localhost/loopback development destinations. Fragments, userinfo credentials, unsupported schemes, excessive URI counts, and oversized entries are rejected.
- Embedded WebAssembly Administration UI: Dioxus-powered administration interface compiled to WASM without a Node.js/React frontend stack.
- Structured Auditability: Security-sensitive lifecycle and identity operations are audit logged while plaintext passwords, Client Secrets, tokens, and stored credential hashes are excluded from audit metadata.
- CLI Tooling: Command-line workflows for initialization, diagnostics, migration, backup/restore, server operation, and identity administration.
Applications are registered with a stable public identity and a high-entropy secret:
Client ID: nx9_app_<32 lowercase hex characters>
Client Secret: nx9_secret_<64 lowercase hex characters>
The Client ID is immutable and safe to identify an application. The Client Secret is disclosed only when the application is created or its secret is explicitly rotated.
Plaintext Client Secrets are never persisted. NX9-Auth stores a BLAKE3 digest and performs credential comparison using constant-time byte comparison. Creation and secret rotation responses are treated as one-time secret disclosure operations and use Cache-Control: no-store.
Existing applications upgraded from earlier schemas receive a stable Client ID. Applications without previously configured credentials can establish credentials through explicit secret rotation.
Protocol boundary: Application credentials, redirect URIs, and scopes form the application registration layer. Redirect URIs are registration metadata intended to become security-enforced redirect destinations when OAuth2/OIDC protocol handlers are implemented. This registration subsystem does not by itself claim complete OAuth2/OIDC grant-flow support.
Registered applications can be assigned existing NX9-Auth users (same-tenant only). Membership is independent of application client credentials and of global RBAC:
| Concern | Role |
|---|---|
| Application credentials | Authenticate the registered application itself (client_id + client_secret) |
| Application membership | Assign existing human users to an application (owner / admin / member metadata) |
| Global RBAC | Authoritative admin authorization (applications:manage, roles, permissions) |
Membership APIs (all require applications:manage):
GET/POST /api/v1/applications/:id/membersPATCH/DELETE /api/v1/applications/:id/members/:user_idGET /api/v1/users/:id/applications
Membership roles do not grant applications:manage or any other global permission. Removing membership revokes application assignment only; it does not delete the user account.
NX9-Auth uses an explicit lifecycle graph:
stateDiagram-v2
[*] --> Initializing
Initializing --> Starting: Build Runtime
Starting --> Running: Start Services
Running --> Draining: Begin Shutdown
Draining --> StoppingWorkers: HTTP Drain Completes or Is Force-Aborted
StoppingWorkers --> ExecutingHooks: Workers Terminated
ExecutingHooks --> ClosingResources: Hooks Complete
ClosingResources --> Stopped: Resources Closed
Stopped --> [*]
The first SIGINT or SIGTERM initiates graceful shutdown, transitions the runtime into Draining, and begins HTTP request draining. Signal monitoring remains active throughout shutdown. A second termination signal escalates shutdown immediately, allowing HTTP draining and blocked worker waits to be curtailed rather than consuming the remaining graceful deadline.
Worker groups receive cancellation concurrently and operate under a shared global shutdown budget. Shutdown hooks execute deterministically by priority, with hooks at the same priority retaining registration order.
# Initialize application directory, configuration, and default administrator
nx9-auth init
# Verify installation and system health
nx9-auth doctor
# Start server
nx9-auth serveConfigure config.toml or use the supported environment-variable configuration:
[server]
host = "127.0.0.1"
port = 8655
production = false
cookie_secure = false
[database]
# SQLite URL or file path:
url = "sqlite://./data/auth.db?mode=rwc"
# Or PostgreSQL:
# url = "postgres://user:password@localhost:5432/nx9auth"
max_connections = 20
min_connections = 5
connect_timeout_secs = 10
idle_timeout_secs = 600
max_lifetime_secs = 1800
[shutdown]
graceful_timeout_secs = 30
force_timeout_secs = 35For production deployments, terminate TLS appropriately, use secure cookies, protect configuration and database credentials, and apply deployment-specific filesystem and network permissions.
NX9-Auth applies layered controls rather than relying on any single authentication mechanism:
| Area | Control |
|---|---|
| Passwords | Argon2id password hashing |
| Application secrets | BLAKE3 digest at rest |
| Credential comparison | subtle::ConstantTimeEq |
| Authentication failures | Non-enumerating unauthorized responses |
| Application mutations | Dedicated applications:manage permission |
| Application creation | Transactional application + audit insertion |
| Secret rotation | Transactional secret update + audit insertion |
| Secret disclosure | One-time response; never returned by list/GET operations |
| Redirect URIs | Structural and scheme-policy validation |
| HTTP responses | Security headers and no-store handling for secret responses |
| Audit metadata | Secret and credential-hash redaction |
Security controls documented here describe implemented mechanisms and should not be interpreted as a substitute for deployment-specific threat modelling, security review, or external audit.
The runtime lifecycle and Application Registration Credentials hardening scopes are covered by workspace unit, integration, migration, security, and acceptance tests.
The verification gates used for these scopes are:
cargo fmt --all -- --check
cargo check --workspace --all-targets --all-features
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
cargo build --release
cargo check --manifest-path ui/Cargo.toml --target wasm32-unknown-unknownAt the documented hardening checkpoint, the workspace test suite completed with 97 tests passed and 0 failed. Test counts and execution times are verification-run observations rather than performance guarantees.
- System Architecture
- Runtime Lifecycle & Graceful Shutdown
- Security Architecture
- Release Notes
- Authentication Model
- Backup & Disaster Recovery
- Docker Deployment Guide
- Linux Deployment Guide
- Integration Guide
- Performance Benchmarks
- Changelog
- License
The Runtime Lifecycle and Application Registration Credentials hardening scopes documented for the current release are complete.
Future OAuth2/OIDC protocol handlers, additional authentication protocols, deployment hardening, or architectural changes should be introduced as separately scoped work with corresponding migrations, security review, and regression tests.
Dual-licensed under either of:
- Apache License, Version 2.0 (LICENSE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT License (LICENSE or http://opensource.org/licenses/MIT)
at your option.