Back to tools

N3X Vault

A self-hosted password manager with browser-side end-to-end encryption, YubiKey/FIDO2 and no server access to plaintext secrets.

SELF-HOSTED · E2EESECURITY ALPHAv0.1.0-alpha.1

Your secrets. Your server. Keys stay on your side.

N3X Vault is an independent password manager with its own protocol and browser-side end-to-end encryption. The server never receives the master password or an unwrapped account key.

Release status: the security alpha is suitable for protocol review, development and controlled testing. Do not store production secrets yet.

Application interface

A real product interface — open any preview to inspect it at full size.

Encrypted vault

Logins, secure notes and TOTP secrets are encrypted in the browser before reaching your own server.

Managed hosting by N3X

Want to use it without maintaining the server?

N3X can deploy and maintain this application, from initial setup and SSL to updates, monitoring and backups.

Ask about N3X hosting

Explicitly designed security boundaries

Client-side encryption

Argon2id, HKDF and XChaCha20-Poly1305 protect data before it reaches the API.

YubiKey / FIDO2

WebAuthn PRF unlock, hardware-key inventory and a two-device readiness policy.

Recovery kit

Encrypted export and resumable restore into an empty installation without a hidden universal key.

Data-blind API

The Rust API and PostgreSQL store ciphertext, protocol parameters and minimal operational metadata.

Short sessions

Fifteen-minute browser sessions remain memory-only and are revocable server-side.

Hardened Compose

A private database network, dropped capabilities, read-only filesystems and volume-backed runtime secrets.

DOCKER CONFIGURATOR

Compose bound to the correct WebAuthn domain

Set the final hostname before enrolling a YubiKey. Changing the RP ID later invalidates existing hardware credentials.

Use the final reverse-proxy domain, for example vault.company.com.

Security alpha: use for controlled testing only. An independent cryptographic review and penetration test are required before production secrets.
Public address
https://vault.example.com
WebAuthn RP ID
vault.example.com
Reverse proxy target
http://127.0.0.1:8793
Health check
http://127.0.0.1:8793/api/health

Ready docker-compose.yml

name: n3xvault

x-api-security: &api-security
  read_only: true
  security_opt:
    - no-new-privileges:true
  cap_drop:
    - ALL
  tmpfs:
    - /tmp:size=32m,mode=1777

x-web-security: &web-security
  read_only: true
  security_opt:
    - no-new-privileges:true
  cap_drop:
    - ALL
  tmpfs:
    - /tmp:size=32m,mode=1777
    - /app/.next/cache:size=64m,mode=0700,uid=1001,gid=1001

services:
  bootstrap:
    image: alpine:3.22
    restart: "no"
    command:
      - /bin/sh
      - -ec
      - |
        umask 077
        if [ ! -s /run/n3xvault/database_password ]; then
          od -An -N32 -tx1 /dev/urandom | tr -d ' \n' > /run/n3xvault/database_password
        fi
        if [ ! -s /run/n3xvault/bootstrap_token ]; then
          od -An -N32 -tx1 /dev/urandom | tr -d ' \n' > /run/n3xvault/bootstrap_token
        fi
        chmod 0444 /run/n3xvault/database_password /run/n3xvault/bootstrap_token
    volumes:
      - runtime_secrets:/run/n3xvault
    networks:
      - backend
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL

  postgres:
    image: postgres:17-alpine
    restart: unless-stopped
    depends_on:
      bootstrap:
        condition: service_completed_successfully
    environment:
      POSTGRES_DB: n3xvault
      POSTGRES_USER: n3xvault
      POSTGRES_PASSWORD_FILE: /run/n3xvault/database_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - runtime_secrets:/run/n3xvault:ro
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n3xvault -d n3xvault"]
      interval: 5s
      timeout: 5s
      retries: 12
    networks:
      - backend

  api:
    image: ghcr.io/nexitpl/n3xvault-api:alpha
    restart: unless-stopped
    depends_on:
      bootstrap:
        condition: service_completed_successfully
      postgres:
        condition: service_healthy
    environment:
      N3XVAULT_BIND: 0.0.0.0:8080
      N3XVAULT_DATABASE_HOST: postgres
      N3XVAULT_DATABASE_NAME: n3xvault
      N3XVAULT_DATABASE_USER: n3xvault
      N3XVAULT_DATABASE_PASSWORD_FILE: /run/n3xvault/database_password
      N3XVAULT_BOOTSTRAP_TOKEN_FILE: /run/n3xvault/bootstrap_token
      N3XVAULT_PUBLIC_ORIGIN: https://vault.example.com
      N3XVAULT_WEBAUTHN_RP_ID: vault.example.com
      N3XVAULT_SESSION_TTL_SECONDS: ${N3XVAULT_SESSION_TTL_SECONDS:-900}
      N3XVAULT_WEBAUTHN_FLOW_TTL_SECONDS: ${N3XVAULT_WEBAUTHN_FLOW_TTL_SECONDS:-300}
      N3XVAULT_DEVICE_PAIRING_TTL_SECONDS: ${N3XVAULT_DEVICE_PAIRING_TTL_SECONDS:-300}
      RUST_LOG: ${N3XVAULT_LOG_LEVEL:-n3xvault_api=info,tower_http=info}
    volumes:
      - runtime_secrets:/run/n3xvault:ro
    healthcheck:
      test: ["CMD", "curl", "--fail", "--silent", "http://127.0.0.1:8080/health/ready"]
      interval: 15s
      timeout: 3s
      retries: 5
      start_period: 15s
    networks:
      - backend
    <<: *api-security

  web:
    image: ghcr.io/nexitpl/n3xvault-web:alpha
    restart: unless-stopped
    depends_on:
      api:
        condition: service_healthy
    environment:
      N3XVAULT_API_INTERNAL_URL: http://api:8080
    ports:
      - "127.0.0.1:8793:3000"
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000/api/health"]
      interval: 20s
      timeout: 5s
      retries: 5
      start_period: 20s
    networks:
      - frontend
      - backend
    <<: *web-security

networks:
  frontend:
  backend:
    internal: true

volumes:
  postgres_data:
  runtime_secrets:

Startup and bootstrap token

mkdir -p n3xvault
cd n3xvault
# Save the configuration as docker-compose.yml
docker compose up -d
docker compose ps
docker compose run --rm api print-bootstrap-token
curl -fsS http://127.0.0.1:8793/api/health

Changelog

    • ReleaseFirst security-alpha release for controlled testing and protocol review — not yet intended for production secrets.
    • NewBrowser-side end-to-end encryption with Argon2id, HKDF and XChaCha20-Poly1305; the server stores encrypted envelopes only.
    • NewSign-in and unlock with a master password or YubiKey/FIDO2 WebAuthn PRF, including a two-hardware-key readiness policy.
    • NewEncrypted recovery kit and safe resumable restore into an empty instance without a universal recovery key.