Cryptographic attorney attestation protocol for AI-generated legal output.
100,000+ lawyers use legal AI tools daily. Bar associations mandate human verification of AI output, but no technical infrastructure exists to prove it happened. LegalSeal fills that gap.
A law firm using Harvey or another legal AI tool generates a draft contract, memo, or brief. Before that document leaves the firm, a licensed attorney reviews it and triggers LegalSeal through the firm’s document management system. LegalSeal hashes the final document, builds a structured attestation containing the attorney’s name, bar number, and jurisdiction, and signs it with the attorney’s private key. The signed attestation is registered in the verification registry — creating a permanent, cryptographic record that a specific attorney reviewed that exact document at a specific point in time. Opposing counsel, regulators, or clients can later verify the attestation by looking up the document hash, confirming the signature is valid, and checking that the attesting attorney is a member in good standing. The document itself is never stored or transmitted — only its hash — preserving attorney-client privilege while still proving human review occurred.
npm install
node examples/basic-verification.js
This demonstrates the full flow: hashing a document, signing an attestation, verifying the signature, and detecting tampering.
# Set up your environment variables
cp .env.example .env
# Edit .env with your Supabase credentials
node src/verify.js
POST /attestationsRegister a signed attestation.
curl -X POST http://localhost:3000/attestations \
-H "Content-Type: application/json" \
-d '{
"document_hash": "abc123...",
"attorney_name": "Sarah Chen",
"bar_number": "CA-298371",
"jurisdiction": "California",
"signature": "base64-signature...",
"public_key": "-----BEGIN PUBLIC KEY-----..."
}'
GET /attestations/:hashLook up all attestations for a document hash.
curl http://localhost:3000/attestations/abc123...
GET /attestations/attorney/:barNumberLook up all attestations by a specific attorney.
curl http://localhost:3000/attestations/attorney/CA-298371
GET /healthcurl http://localhost:3000/health
src/
hash.js — SHA-256 document hashing
sign.js — RSA key generation, attestation building, signing & verification
verify.js — Express API server with Supabase registry
protocol/
SPEC.md — Full protocol specification
examples/
basic-verification.js — End-to-end working example
Create a verifications table with this schema:
CREATE TABLE verifications (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
document_hash TEXT NOT NULL,
attorney_name TEXT NOT NULL,
bar_number TEXT NOT NULL,
jurisdiction TEXT NOT NULL,
review_date TIMESTAMPTZ DEFAULT now(),
attestation_statement TEXT,
signature TEXT NOT NULL,
public_key TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_verifications_hash ON verifications (document_hash);
CREATE INDEX idx_verifications_bar ON verifications (bar_number);
| Variable | Description |
|---|---|
SUPABASE_URL |
Your Supabase project URL |
SUPABASE_KEY |
Your Supabase anon key |
PORT |
API server port (default: 3000) |
MIT