πͺͺ Identity Verification
How Soulprint proves you're human β 100% locally, zero biometric data uploaded.
The Verification Pipeline
Document capture
The user photographs or uploads their government-issued ID. Soulprint supports MRZ (Machine Readable Zone) on passports and national IDs, plus structured OCR for cards without MRZ (e.g. Colombian CΓ©dula).
OCR extraction
Tesseract OCR reads the document. Extracted fields: full name, document number, date of birth, nationality, expiry. Raw images are never stored β only the extracted text is kept temporarily in memory.
Face matching
InsightFace (Buffalo_L model) compares the ID photo with a live selfie. Match threshold: cosine similarity β₯ 0.35 for document vs selfie (PROTOCOL.FACE_SIM_DOC_SELFIE β immutable). The face embedding is computed on-device and immediately discarded after matching.
Privacy proof generation
A unique identity hash is derived from the document data and face embedding. This hash is deterministic β the same person always produces the same hash β which enables anti-replay protection without storing identity data.
Token issuance
An SPT (Soulprint Token) is issued and signed with an Ed25519 key generated on-device. The token contains: DID, credential list, identity score, expiry (6 months), and the proof hash. It is stored locally and never transmitted in full.
Privacy Guarantees
| Data | Stays on device? | Notes |
|---|---|---|
| ID photos / selfies | β Yes | Processed and discarded immediately |
| Name, DOB, document number | β Yes | Never included in any network call |
| Face biometric embedding | β Yes | Computed locally, used once for matching, then discarded |
| Identity proof hash | π Shared | Sent to validator nodes for anti-replay only β not reversible to identity data |
| DID + score + credentials | π Shared | Included in SPT token headers when calling protected services |
Credential Types
Each verification step adds a credential to the token:
| Credential | Score | How obtained |
|---|---|---|
email | +8 | Email OTP verification during setup |
phone | +12 | SMS OTP verification |
github | +16 | GitHub OAuth (verifies developer identity) |
document | +20 | Government ID OCR successful |
face_match | +16 | Selfie matches ID photo (cosine β₯ 0.6) |
biometric | +8 | Privacy proof generated and registered |
Token Structure
{
"did": "did:soulprint:abc123...",
"score": 72,
"identity": 62,
"reputation": 10,
"country": "CO",
"credentials": ["email", "document", "face_match"],
"issuedAt": "2026-02-24T10:00:00Z",
"expiresAt": "2026-08-24T10:00:00Z",
"signature": "<Ed25519 signature over all fields>",
"issuer": "soulprint-cli/0.1.3"
}
Renewal
Tokens expire after 6 months. Renewal re-runs only the face matching step (OCR is cached):
npx soulprint renew
soulprint-mcp or soulprint-express will return a 403 with "token expired" message. Always handle this gracefully in your UI.
Anti-Replay Protection
Each person produces a unique identity hash. Validator nodes keep a registry of seen hashes. If two different devices try to register with the same identity data (Sybil attack), the second registration is rejected. This guarantees one identity per real person across all devices.