Hanzo
Hanzo Skills Reference

Hanzo Sign - Open Source Document Signing

Hanzo Sign is an open-source DocuSign alternative for electronic document signing. Turborepo monorepo with a React Router (Remix) + Hono server frontend, tRPC + ts-rest APIs, Prisma ORM, and PDF si...

Overview

Hanzo Sign is an open-source DocuSign alternative for electronic document signing. Turborepo monorepo with a React Router (Remix) + Hono server frontend, tRPC + ts-rest APIs, Prisma ORM, and PDF signing via P12 certificates or Google Cloud KMS. Live at sign.hanzo.ai. Version 2.7.1. Licensed AGPL-3.0.

Why Hanzo Sign?

  • Self-hostable: Full control over your signing infrastructure
  • Open source: Inspect and audit the entire signing pipeline
  • Multiple signing providers: Local P12 certificates or Google Cloud HSM
  • Swappable storage: Database or S3-compatible object storage
  • API-first: REST (V1) and tRPC (V2) APIs with OpenAPI spec
  • Enterprise features: Teams, custom branding, webhooks, bulk sending
  • i18n: Multi-language via Lingui
  • AI integration: Google Vertex AI (Gemini) for document analysis

Tech Stack

  • Frontend: React 18, React Router v7 (Remix), Tailwind CSS, shadcn/ui, Radix UI
  • Server: Hono (on Node.js)
  • Database: PostgreSQL 15 (Prisma ORM + Kysely)
  • API: tRPC (V2, current), ts-rest (V1, deprecated)
  • Auth: Arctic (OAuth), WebAuthn/Passkeys, Hanzo IAM (hanzo.id)
  • Email: React Email, Nodemailer (SMTP, Resend, MailChannels)
  • PDF: @libpdf/core, pdfjs-dist, PDF-Lib
  • Jobs: Inngest or local database-backed queue
  • Build: Turborepo + npm workspaces, Vite
  • Testing: Playwright (E2E)

OSS Base

Repo: hanzoai/sign (fork of documenso/documenso).

When to use

  • Sending documents for electronic signature
  • Building document signing workflows
  • Self-hosting a DocuSign-like service
  • Creating document templates for recurring signatures
  • Bulk sending documents via API
  • Embedding signing into existing applications

Hard requirements

  1. Node.js v22 or above
  2. PostgreSQL database
  3. SMTP server or email provider (Resend, MailChannels)
  4. P12 signing certificate (or Google Cloud KMS)

Quick reference

ItemValue
UIhttps://sign.hanzo.ai (port 3000)
API V2/api/v2/* (tRPC + OpenAPI)
API V1/api/v1/* (ts-rest, deprecated)
AuthArctic OAuth + WebAuthn + Hanzo IAM
DBPostgreSQL (Prisma + Kysely)
Root package@hanzo/sign-root
Version2.7.1
LicenseAGPL-3.0
Repogithub.com/hanzoai/sign

One-file quickstart

Developer Quickstart (Docker)

# Clone and setup
git clone https://github.com/hanzoai/sign.git
cd sign
cp .env.example .env

# One command: install, start db/mail containers, migrate, seed, dev
npm run d

Manual Setup

npm install
cp .env.example .env

# Set required env vars:
# NEXTAUTH_SECRET, NEXT_PUBLIC_WEBAPP_URL
# NEXT_PRIVATE_DATABASE_URL, NEXT_PRIVATE_DIRECT_DATABASE_URL
# NEXT_PRIVATE_SMTP_FROM_NAME, NEXT_PRIVATE_SMTP_FROM_ADDRESS

npm run prisma:migrate-dev
npm run translate:compile
npm run dev

Docker (Production)

docker run -d --restart=unless-stopped \
  -p 3000:3000 \
  -v hanzo-sign:/app/data \
  --name hanzo-sign \
  hanzo-sign:latest

Core Concepts

Architecture

                         Remix App (Hono Server)
                            apps/remix
  /api/v1/*    /api/v2/*    /api/trpc/*    /api/jobs/*    React Router UI
  (ts-rest)     (tRPC)       (tRPC)       (Jobs API)
       |            |            |             |
  @hanzo/sign-api  @hanzo/sign-trpc  @hanzo/sign-lib  @hanzo/sign-email
                              |
               +--------------+--------------+
               |              |              |
          Storage         Jobs           PDF Signing
          Provider       Provider         Provider
               |              |              |
         DB or S3      Inngest/Local   Local P12 or GCloud HSM

Monorepo Packages

Applications (apps/):

PackageDescriptionPort
@hanzo/sign-remixMain app (React Router + Hono)3000
@hanzo/sign-documentationDocumentation site (Nextra)3002
@hanzo/sign-openpage-apiPublic analytics API3003

Core Packages (packages/):

PackageDescription
@hanzo/sign-libCore business logic (server, client, universal)
@hanzo/sign-trpctRPC API layer with OpenAPI (V2)
@hanzo/sign-apiREST API layer via ts-rest (V1)
@hanzo/sign-prismaDatabase layer (Prisma ORM + Kysely)
@hanzo/sign-uiUI components (shadcn + Radix + Tailwind)
@hanzo/sign-emailEmail templates (React Email)
@hanzo/sign-authAuth (Arctic OAuth, WebAuthn/Passkeys)
@hanzo/sign-signingPDF signing (Local P12, Google Cloud KMS)
@hanzo/sign-eeEnterprise Edition features
@hanzo/sign-assetsStatic assets

Swappable Providers

Storage (NEXT_PUBLIC_UPLOAD_TRANSPORT):

  • database -- Store files as Base64 in PostgreSQL (default)
  • s3 -- S3-compatible storage (AWS, MinIO, etc.)

PDF Signing (NEXT_PRIVATE_SIGNING_TRANSPORT):

  • local -- P12 certificate file (default)
  • gcloud-hsm -- Google Cloud KMS Hardware Security Module

Email (NEXT_PRIVATE_SMTP_TRANSPORT):

  • smtp-auth -- Standard SMTP with credentials (default)
  • smtp-api -- SMTP with API key
  • resend -- Resend API
  • mailchannels -- MailChannels API

Background Jobs (NEXT_PRIVATE_JOBS_PROVIDER):

  • local -- Database-backed queue (default)
  • inngest -- Managed cloud service

Document Signing Flow

  1. Upload document to storage provider (DB or S3)
  2. Add recipients (signers, viewers, approvers)
  3. Add signature fields (positions on PDF)
  4. Send document (triggers email job)
  5. Recipient signs via unique link
  6. seal-document job finalizes the PDF
  7. Signing provider cryptographically signs the PDF
  8. Signed PDF stored back to storage provider

Auth / IAM Integration

Hanzo Sign supports Hanzo IAM (hanzo.id) for production auth:

IAM_URL="https://hanzo.id"
IAM_CLIENT_ID="<your-client-id>"
IAM_CLIENT_SECRET="<your-client-secret>"

Also supports Google OAuth, Microsoft OAuth, and generic OIDC providers.

Signing Certificates

For local signing, generate a P12 certificate:

openssl genrsa -out private.key 2048
openssl req -new -x509 -key private.key -out certificate.crt -days 365
read -s -p "Enter certificate password: " CERT_PASS
openssl pkcs12 -export -out certificate.p12 -inkey private.key -in certificate.crt \
    -password env:CERT_PASS -keypbe PBE-SHA1-3DES -certpbe PBE-SHA1-3DES -macalg sha1

Place at apps/remix/resources/certificate.p12.

Environment Variables

VariablePurposeOptions
NEXTAUTH_SECRETSession encryptionRandom string
NEXT_PUBLIC_WEBAPP_URLPublic URLhttps://sign.hanzo.ai
NEXT_PRIVATE_DATABASE_URLPostgreSQL connectionConnection string
NEXT_PUBLIC_UPLOAD_TRANSPORTStorage providerdatabase, s3
NEXT_PRIVATE_SIGNING_TRANSPORTSigning providerlocal, gcloud-hsm
NEXT_PRIVATE_SMTP_TRANSPORTEmail providersmtp-auth, smtp-api, resend, mailchannels
NEXT_PRIVATE_JOBS_PROVIDERJobs providerlocal, inngest
IAM_URLHanzo IAM endpointhttps://hanzo.id

Development Services (Docker)

ServicePort
PostgreSQL54320
Inbucket (Mail UI)9000
Inbucket (SMTP)2500
MinIO (S3 Dashboard)9001
MinIO (S3 API)9002

Troubleshooting

IssueCauseSolution
No emails receivedUsing dev quickstartCheck Inbucket at http://localhost:9000
"Failed to get private key bags"P12 cert has no passwordRe-create with password (min 4 chars)
Can't see env vars in scriptsEnv not loadedWrap with npm run with:env -- npm run myscript
IPv6 deploymentDefault binds IPv4Pass npm run start -- -H ::
Lingui errorsTranslations not compiledRun npm run translate:compile
  • hanzo/hanzo-id.md - IAM and authentication (hanzo.id)
  • hanzo/hanzo-kms.md - Secret management
  • hanzo/hanzo-platform.md - PaaS deployment
  • hanzo/hanzo-commerce.md - E-commerce (contracts, checkout)

How is this guide?

Last updated on

On this page