Skip to main content

Self-Hosting Steward

Steward is designed to be self-hosted. This guide covers deploying Steward on your own infrastructure.

Requirements

  • Runtime: Bun v1.0+
  • Database: PostgreSQL 15+ (or Neon for serverless)
  • Node.js: 18+ (for build tooling)
  • OS: Linux (Ubuntu 22.04+ recommended), macOS, or Windows WSL2

Quick Start

Environment Variables

Core (Required)

API Server

Generate a dedicated JWT signing secret and store the output in your secret manager or .env file:
For new non-embedded production deployments, configure the canonical STEWARD_JWT_SECRET with at least 32 high-entropy characters and keep it separate from STEWARD_MASTER_PASSWORD. During migration, the runtime temporarily accepts a 32+ character STEWARD_SESSION_SECRET when the canonical variable is absent, but that name is deprecated and should be replaced with STEWARD_JWT_SECRET. Without either sufficiently long signing secret, non-embedded production fails closed. Derivation from the master password is available only in embedded/local mode.

Blockchain

Authentication

Database Setup

Run the Drizzle migrations to set up the database schema:

Running the API

Verify it’s running:

Creating Your First Tenant

If you pass a non-hash string as apiKeyHash, Steward will SHA-256 hash it for you. The raw API key is returned once on creation.

Production Deployment

Systemd Service

Reverse Proxy (Nginx)

Production Checklist

  • Set a unique STEWARD_MASTER_PASSWORD (32+ chars, random)
  • Set a separate, high-entropy STEWARD_JWT_SECRET (32+ characters)
  • Use TLS for all connections (API + database)
  • Restrict database access to the Steward server only
  • Set STEWARD_PLATFORM_KEY for admin operations
  • Configure PASSKEY_RP_ID and PASSKEY_ORIGIN to match your domain
  • Set up email provider (Resend) for magic link auth
  • Run as non-root user
  • Enable firewall (only expose ports 443 and SSH)
  • Back up the database regularly