Safety Number Verification Blueprint

Contact identity verification via cryptographic fingerprints that detects when a contact’s identity key has changed, alerting users to potential key-change events

   
Feature safety-number-verification
Category Auth
Version 1.0.0
Tags identity, key-verification, fingerprint, trust, end-to-end-encryption, key-transparency
YAML Source View on GitHub
JSON API safety-number-verification.json

Fields

Name Type Required Label Description
service_identifier text Yes Service Identifier  
identity_key token Yes Identity Key  
fingerprint token Yes Identity Key Fingerprint  
identity_type select Yes Identity Type  
sender_certificate token No Sender Certificate  

Rules

  • identity_keys: Each account holds one public identity key per identity type; these keys are set at registration and may change only when explicitly rotated by the user, The server must store and return the full 33-byte serialised identity key so that clients can compute the safety number independently, When an identity key changes the server must not silently reuse the old fingerprint; clients must re-verify after any key rotation, Signed pre-key signatures must be validated against the account’s identity key when keys are uploaded or a new device is linked, preventing key substitution attacks
  • fingerprint_checks: Batch identity key checks accept up to 1000 entries per request; each entry carries a service identifier and a 4-byte fingerprint, The server computes the SHA-256 hash of each stored identity key, extracts the 4 most-significant bytes, and compares them to the client-supplied fingerprint using a constant-time comparison, Only entries where the fingerprint does not match are returned in the response; a match means the client’s view is consistent with the server’s view
  • sender_certificates: Sender certificates are short-lived (configurable expiry, typically 24 hours) and signed by a server-held private key; they embed the account UUID, device ID, and public identity key, Clients verify the sender certificate signature against the known server public key to confirm messages originate from the claimed sender, Key transparency proofs may supplement fingerprint checks by providing a publicly auditable, append-only log of identity key bindings

Outcomes

Invalid_request (Priority: 2) — Error: IDENTITY_CHECK_INVALID_REQUEST

Given:

  • ANY: request contains more than 1000 elements OR fingerprint (input) not_exists OR a service identifier field is malformed

Result: HTTP 422 is returned; client must correct the request before retrying

Signed_prekey_invalid (Priority: 3) — Error: IDENTITY_PREKEY_INVALID_SIGNATURE

Given:

  • a signed pre-key or last-resort key is uploaded
  • the signature on the key does not verify against the account’s stored identity key

Then:

  • emit_event event: identity.prekey_validation_failed

Result: HTTP 422 is returned; the key upload is rejected to prevent key substitution

Identity_key_not_found (Priority: 4)

Given:

  • the service identifier in the request does not correspond to any registered account

Then:

  • emit_event event: identity.lookup_failed

Result: The entry is omitted from the mismatch response; clients treat absent entries as unknown contacts rather than mismatches

Fingerprint_mismatch (Priority: 5)

Given:

  • batch identity check request contains at least one element
  • at least one submitted fingerprint does not match the server-stored identity key for its service identifier

Then:

  • emit_event event: identity.key_mismatch

Result: HTTP 200 is returned; the response body contains only the mismatched entries with their current server-side identity keys so the client can detect key changes

Fingerprint_match (Priority: 10)

Given:

  • batch identity check request contains at least one element
  • every submitted fingerprint matches the server-stored identity key fingerprint for that service identifier

Then:

  • emit_event event: identity.verified

Result: HTTP 200 is returned with an empty elements array; the client’s view is consistent with the server’s view

Sender_certificate_issued (Priority: 10)

Given:

  • authenticated device requests a sender certificate
  • device has a valid registered identity key

Then:

  • create_record target: sender_certificate_cache
  • emit_event event: identity.certificate_issued

Result: A signed certificate binding the account UUID, device ID, and identity key is returned; the certificate is valid for the configured TTL

Errors

Code Status Message Retry
IDENTITY_CHECK_INVALID_REQUEST 422 Identity check request is malformed; check fingerprint sizes and identifier formats No
IDENTITY_PREKEY_INVALID_SIGNATURE 422 Pre-key signature does not match the account identity key No

Events

Event Description Payload
identity.verified A batch identity check confirmed all submitted fingerprints match the server-stored keys service_identifier, identity_type
identity.key_mismatch At least one submitted fingerprint did not match the stored identity key, indicating a possible key change service_identifier, identity_key, identity_type
identity.lookup_failed The requested service identifier was not found in the account store during a batch identity check service_identifier
identity.certificate_issued A short-lived sender certificate was issued to an authenticated device service_identifier, device_id, expires_at
identity.prekey_validation_failed A signed pre-key upload was rejected because its signature was invalid service_identifier, device_id
Feature Relationship Reason
e2e-key-exchange required Identity keys established during key exchange are the source of truth that safety number verification checks
phone-number-registration required Identity keys are created and stored at registration; the registered account must exist for verification to operate
sealed-sender-delivery recommended Sender certificates produced by this feature are embedded in sealed-sender messages so recipients can verify sender identity
multi-device-linking recommended Each linked device registers its own pre-keys but shares the account identity key; key verification spans all devices on the account

AGI Readiness

Goals

Reliable Safety Number Verification

Contact identity verification via cryptographic fingerprints that detects when a contact’s identity key has changed, alerting users to potential key-change events

Success Metrics:

Metric Target Measurement
unauthorized_access_rate 0% Failed authorization attempts that succeed
response_time_p95 < 500ms 95th percentile response time

Constraints:

  • security (non-negotiable): Follow OWASP security recommendations
  • security (non-negotiable): Sensitive fields must be encrypted at rest and never logged in plaintext

Autonomy

Level: supervised

Human Checkpoints:

  • before modifying sensitive data fields

Escalation Triggers:

  • error_rate > 5
  • consecutive_failures > 3

Verification

Invariants:

  • sensitive fields are never logged in plaintext
  • all data access is authenticated and authorized
  • error messages never expose internal system details

Tradeoffs

Prefer Over Reason
security performance authentication must prioritize preventing unauthorized access

Coordination

Protocol: request_response

Consumes:

Capability From Fallback
e2e_key_exchange e2e-key-exchange fail
phone_number_registration phone-number-registration fail

Safety

Action Permission Cooldown Max Auto
fingerprint_match autonomous - -
fingerprint_mismatch autonomous - -
identity_key_not_found autonomous - -
invalid_request autonomous - -
sender_certificate_issued autonomous - -
signed_prekey_invalid autonomous - -