FaceCard Docs

Security and privacy

What FaceCard stores, how long, the consent requirement, and how deletion works.

What is stored

FaceCard stores embeddings, not images.

  • No face images. The browser computes a 128-number descriptor on the user's device. Images and video frames are never uploaded and never stored.
  • Face templates. Descriptors are L2-normalized and stored in Postgres (vector(128)), scoped to one app.
  • Profile. Email and name, per app.
  • Consent record. Policy version, time, IP address and user agent.
  • Auth events. A log of enrolls and matches. It holds no descriptors.
  • Challenges. Single-use nonces, short lived.

Data is held in AWS in the us-east-2 region. Secret keys and publishable keys are stored only as SHA-256 hashes.

Retention schedule

DataKept until
A user's biometric data (templates)The user or the app deletes the account, the app is deleted, or 3 years pass with no sign in, whichever comes first
Auth eventsDeleted after 400 days
Expired challengesDeleted hourly

A daily purge job enforces these rules. The public schedule is at https://facecard.dev/privacy#retention.

FaceCard processes biometric data, so enrollment requires explicit consent. POST /v1/enroll fails with 400 consent_required unless consent.accepted is true. Your app must show the user a privacy notice that explains what is collected before you send that value. FaceCard stores the policy version, time, IP address and user agent with the user.

Consent law differs by place. Some jurisdictions have specific biometric privacy rules. Read the rules that apply to your users and consult your own counsel. These docs are not legal advice.

Deletion

  • A user can delete themselves with DELETE /v1/me using their token.
  • Your server can delete any user of the app with DELETE /v1/users/{id}.
  • Deleting an app removes its users and revokes all its keys.

A deletion removes the profile, every face template, the consent record and challenge rows for that user. FaceCard keeps a tombstone auth event that contains no personal data. Deletion cannot be undone.

Isolation

Every query is scoped by app. A credential belongs to one app, and the app is always derived from the credential, never from the request body. Face search is filtered by app_id, so a face enrolled in one app can never match in another.

Protections on the API

  • Single-use challenges stop replay of recorded requests.
  • Publishable keys only work from the origins you allow.
  • Rate limits apply per IP and per secret key.
  • User tokens are ES256 JWTs that last one hour.
  • Error responses for failed matches carry no candidate data.

What FaceCard does not protect against

Liveness is computed in the browser and is advisory, so FaceCard is not a defense against a determined spoofing attack. See Liveness is advisory.

Report a problem

Security issues: security@facecard.dev. Privacy requests: privacy@facecard.dev.

On this page