Claims, not uploads
You get facts and a few fields, never ID images. Nothing sensitive to breach.
For sites and developers
Verify with FFN gives your site a signed yes or no for exactly the claims you need, with the source, method and date behind each one. No ID images to store, secure or delete.
{
"provider": "ffn",
"subjectId": "per-site id for this person",
"claims": [
{ "name": "identity.ageOver21",
"label": "Over 21", "value": true,
"issuerName": "FFN",
"evidence": { "method": "vendor-document",
"assurance": "substantial", "checkedAt": "…" } }
],
"notChecked": ["address"],
"verifiedAt": "…"
}
Why sites use it
You get facts and a few fields, never ID images. Nothing sensitive to breach.
Each claim says how it was checked, by which source, when, and at what assurance. Set the lowest assurance you accept.
You keep your own verification record. If FFN is unreachable, you carry on with what you stored and when it was checked.
What you can ask for
Mark a claim optional and the person can choose whether to share it. The SDK refuses to request a claim no listed issuer can provide.
| Credential | Claims | Issued by |
|---|---|---|
| FFN Identity |
personVerified, ageOver18, ageOver21,
birthDate, legalName,
holdsValidLicense with issuingState
|
FFN, after an ID check |
| FFN Link | Account type (email, phone, GitHub, Google, LinkedIn), handle, account age when the provider shares it, and whether the name matches the verified name | FFN, after a code or sign-in |
| Site attestation |
videoCallCompleted, referencesChecked,
tripCompleted
|
Your site, under its own name |
| Travel vouch | Tags and an optional note, carrying the voucher's own signature | Your site |
Get started
The Door SDK wires the Verify with FFN button's server side, your own attestations, re-checks and reissue after recovery from one config. Your accounts and data model stay yours.
In this first version the FFN team adds sites to the registry, and the SDK is shared as a vendored package. Self-serve onboarding comes later.
Talk to the FoFo Network teamimport { createSite, networkFromEnv } from '@fofonet/door-site';
const site = createSite({
origin: 'https://example.com',
network: networkFromEnv(process.env),
store, // e.g. FirestoreKvStore
claims: [
'identity.personVerified',
'identity.ageOver21',
'identity.legalName',
'videoCallCompleted?', // optional
],
purpose: 'Check members before the trip',
display: { name: 'Example Co' },
});
// site.handler serves the button's API,
// site.attest() issues your own credentials,
// site.recheck() checks status before you rely on it.
What happens
Your server builds an OpenID4VP request: the claims you want, which are required, and a fresh nonce.
The person unlocks their pass, sees your verified name and purpose, and chooses what to share.
An SD-JWT presentation with only the chosen claims, bound to your request by a key-binding signature.
Issuer signature, the trust registry, expiry, the status list and key binding. Then you keep the record.
Issue your own
Some facts only you know: the video call happened, references were checked, the trip was
completed. Issue them as your own credentials, signed with your own key under your own
did:web.
Standards
Any OpenID4VP and SD-JWT VC library that trusts FFN's registry key can verify an FFN credential, with or without our SDK.
How your site asks, and how the pass answers.
Credentials with each claim disclosed separately, plus key binding.
How credentials, including yours, reach the pass.
One static file per issuer, so revocation checks are cheap and private.
Issuers publish their keys on their own domains.
The holder's vault is unlocked by a passkey, with PRF where available.
Pricing
$0.99 per FFN Pass check
For outside sites asking a person to share verified claims.
FFN Pass launches with FoFo Adventures. Your site can be next.