API: Human auth
Capability state:
humanAuth.challengeis staging-durable;humanAuth.verifyPasskeyis fixture-rehearsed;humanAuth.faceMatchFallbackis shape-only. Real WebAuthn, real biometric pipelines, and real session-binding are not operational (see 022 gap report item 15).
The human-auth operations cover Gestalt’s human presence model. Two lanes:
- Private passkey lane — WebAuthn-style passkey assertion. No biometric material seen by Gestalt.
- CPU face-match fallback — explicit-consent 1:1 fallback proofing with ephemeral embeddings only. No template storage. No 1:N search.
A successful presence flow produces a human presence receipt. Presence does not create standing on its own — see authority.md for how presence is bound to actor/vessel for sensitive approvals.
See concepts: glossary — HumanAuth.
humanAuth.challenge
Section titled “humanAuth.challenge”Request a privacy-preserving passkey challenge for human presence.
POST /v1/human-auth/challengestate: staging-durablesdk_role: request a privacy-preserving passkey challenge for human presencerequest_record: CloudHumanAuthChallengeRequestresponses: human_auth_challenge | receiptRequest
Section titled “Request”interface HumanAuthChallengeRequest { tenant?: GestaltRef; subject?: GestaltRef; // e.g. "human_person:anna" relying_party_id?: string; // e.g. "gestalt.local" scopes?: string[]; // e.g. ["sensitive_approval"]}Response
Section titled “Response”{ "operation": "humanAuth.challenge", "outcome": "verified", "body": { "challenge": "human_auth_challenge:fixture_private_human_auth", "biometricMaterialSeenByGestalt": false }, "receipt": {...}}biometricMaterialSeenByGestalt: false is asserted explicitly because
the privacy guarantee is part of the contract.
SDK example
Section titled “SDK example”const challenge = await client.humanAuthChallenge({ tenant: "tenant_node:rheinwerk_calibration", subject: "human_person:anna", relying_party_id: "gestalt.local", scopes: ["sensitive_approval"],});humanAuth.verifyPasskey
Section titled “humanAuth.verifyPasskey”Verify signed passkey challenge and receive human presence receipt without biometric material.
POST /v1/human-auth/passkey/verifystate: fixture-rehearsedsdk_role: verify signed passkey challenge and receive human presence receipt without biometric materialrequest_record: CloudHumanAuthPasskeyVerifyRequestresponses: human_presence_receipt | refusal | receiptRequest
Section titled “Request”interface HumanAuthPasskeyVerifyRequest { tenant?: GestaltRef; challenge: GestaltRef; passkey_binding?: GestaltRef; relying_party_id?: string; user_verified?: boolean; credential_id_hash?: string;}Response
Section titled “Response”{ "operation": "humanAuth.verifyPasskey", "outcome": "admitted", "body": { "humanPresenceReceipt": "human_presence_receipt:fixture_private_presence", "standingCreated": false, "biometricMaterialSeenByGestalt": false }, "receipt": {...}}standingCreated: false is asserted: a successful passkey verify
proves presence; it does not grant standing.
SDK example
Section titled “SDK example”const verified = await client.humanAuthVerifyPasskey({ tenant: "tenant_node:rheinwerk_calibration", challenge: challenge.body.challenge, passkey_binding: "passkey_binding:anna_platform_passkey_fixture", relying_party_id: "gestalt.local", user_verified: true, credential_id_hash: "sha256:fixture_credential_id_hash_private",});
// verified.body.humanPresenceReceipthumanAuth.passkeyRevoke
Section titled “humanAuth.passkeyRevoke”Record staging passkey revocation through hash-only lifecycle state after same-passkey HumanAuth presence, without raw credential or biometric material.
POST /v1/human-auth/passkey/revokestate: staging-durablesdk_role: record staging passkey revocation through hash-only lifecycle state after same-passkey HumanAuth presence without raw credential or biometric materialrequest_record: CloudHumanAuthPasskeyRevokeRequestresponses: passkey_lifecycle | passkey_binding | human_presence_receipt | refusal | receiptRequest
Section titled “Request”interface HumanAuthPasskeyRevokeRequest { tenant?: GestaltRef; subject?: GestaltRef; passkey_binding: GestaltRef; human_presence_receipt: GestaltRef; revocation_ref?: GestaltRef; reason_hash: string; // sha256:... required fixture?: boolean; // must be true contains_customer_data?: boolean; // refused if true contains_biometric_material?: boolean; // refused if true raw_credential_id?: string; // refused if present raw_attestation_object?: string; // refused if present raw_client_data_json?: string; // refused if present create_identity_binding_from_passkey?: boolean; // refused if true create_standing_from_passkey?: boolean; // refused if true create_company_authority_from_passkey?: boolean; // refused if true enforce_runtime_overlay?: boolean;}The human_presence_receipt must be a same-passkey HumanAuth
presence (scope passkey_revoke or passkey_lifecycle) over the
target passkey_binding after local user verification, with no
biometric data seen by Gestalt.
Response
Section titled “Response”{ "operation": "humanAuth.passkeyRevoke", "outcome": "admitted", "body": { "human_auth_passkey_lifecycle": "human_auth_passkey_lifecycle:...", "passkey_binding": "passkey_binding:...", "human_presence_receipt": "human_presence_receipt:...", "status": "revoked", "enforced_in_runtime_overlay": true, "raw_credential_id_stored": false, "raw_attestation_object_stored": false, "raw_client_data_json_stored": false, "raw_private_key_material_stored": false, "raw_biometric_material_stored": false, "identity_binding_created": false, "standing_created": false, "company_authority_created": false, "durable_state": {...}, "production_admission": false }, "receipt": {...}}When enforce_runtime_overlay: true, the runtime adds the
revoked binding to its in-memory overlay so subsequent
humanAuth.verifyPasskey and lifecycle calls against it refuse.
Refusal codes:
human_auth_passkey_lifecycle_fixture_only,
human_auth_passkey_lifecycle_raw_material_refused,
human_auth_passkey_lifecycle_cannot_create_authority,
human_auth_passkey_lifecycle_subject_mismatch,
human_auth_passkey_lifecycle_hash_required,
human_auth_passkey_binding_unknown,
human_auth_passkey_lifecycle_presence_missing,
human_auth_passkey_lifecycle_presence_invalid.
SDK example
Section titled “SDK example”const revoked = await client.humanAuthPasskeyRevoke({ tenant: "tenant_node:rheinwerk_calibration", subject: "human_person:anna", passkey_binding: "passkey_binding:anna_platform_passkey_fixture", human_presence_receipt: "human_presence_receipt:fixture_private_presence", revocation_ref: "human_auth_passkey_lifecycle:fixture_revoke", reason_hash: "sha256:fixture_passkey_revocation_reason", fixture: true,});humanAuth.passkeyRotate
Section titled “humanAuth.passkeyRotate”Record staging passkey rotation to a known replacement binding after replacement-passkey HumanAuth presence, without creating identity or standing.
POST /v1/human-auth/passkey/rotatestate: staging-durablesdk_role: record staging passkey rotation to a known replacement binding after replacement-passkey HumanAuth presence without creating identity or standingrequest_record: CloudHumanAuthPasskeyRotateRequestresponses: passkey_lifecycle | old_passkey_binding | replacement_passkey_binding | human_presence_receipt | refusal | receiptRequest
Section titled “Request”interface HumanAuthPasskeyRotateRequest { tenant?: GestaltRef; subject?: GestaltRef; old_passkey_binding: GestaltRef; replacement_passkey_binding: GestaltRef; // must differ from old human_presence_receipt: GestaltRef; rotation_ref?: GestaltRef; reason_hash: string; // sha256:... required fixture?: boolean; // must be true contains_customer_data?: boolean; // refused if true contains_biometric_material?: boolean; // refused if true raw_credential_id?: string; // refused if present raw_attestation_object?: string; // refused if present raw_client_data_json?: string; // refused if present create_identity_binding_from_passkey?: boolean; // refused if true create_standing_from_passkey?: boolean; // refused if true create_company_authority_from_passkey?: boolean; // refused if true enforce_runtime_overlay?: boolean;}The human_presence_receipt must cover the replacement passkey
(scope passkey_rotate or passkey_lifecycle) with local user
verification and no biometric material.
Response
Section titled “Response”{ "operation": "humanAuth.passkeyRotate", "outcome": "admitted", "body": { "human_auth_passkey_lifecycle": "human_auth_passkey_lifecycle:...", "old_passkey_binding": "passkey_binding:...", "replacement_passkey_binding": "passkey_binding:...", "human_presence_receipt": "human_presence_receipt:...", "status": "rotated", "enforced_in_runtime_overlay": true, "raw_credential_id_stored": false, "...": "..." }, "receipt": {...}}When enforce_runtime_overlay: true, the runtime overlays the
rotation so verify/lifecycle calls against the old binding map to
the replacement.
Refusal codes:
human_auth_passkey_lifecycle_fixture_only,
human_auth_passkey_lifecycle_raw_material_refused,
human_auth_passkey_lifecycle_cannot_create_authority,
human_auth_passkey_lifecycle_subject_mismatch,
human_auth_passkey_lifecycle_same_binding,
human_auth_passkey_lifecycle_hash_required,
human_auth_passkey_lifecycle_replayed,
human_auth_passkey_lifecycle_presence_missing,
human_auth_passkey_lifecycle_presence_invalid.
SDK example
Section titled “SDK example”const rotated = await client.humanAuthPasskeyRotate({ tenant: "tenant_node:rheinwerk_calibration", subject: "human_person:anna", old_passkey_binding: "passkey_binding:anna_platform_passkey_fixture", replacement_passkey_binding: "passkey_binding:fixture_passkey_replacement", human_presence_receipt: "human_presence_receipt:fixture_private_presence", rotation_ref: "human_auth_passkey_lifecycle:fixture_rotate", reason_hash: "sha256:fixture_passkey_rotation_reason", fixture: true,});humanAuth.faceMatchFallback
Section titled “humanAuth.faceMatchFallback”Submit explicit-consent 1:1 fallback proofing fixture and receive receipt/hash/score/caveat artifact only.
POST /v1/human-auth/face-matchstate: shape-onlysdk_role: submit explicit-consent 1:1 fallback proofing fixture and receive receipt/hash/score/caveat artifact onlyrequest_record: CloudHumanAuthFaceMatchRequestresponses: cpu_face_match_receipt | refusal | receiptRequest
Section titled “Request”interface HumanAuthFaceMatchRequest { tenant?: GestaltRef; subject?: GestaltRef; consent_ref?: GestaltRef; // explicit consent required scenario?: "same-person" | "different-person" | "low-quality" | "spoof";}Response
Section titled “Response”{ "operation": "humanAuth.faceMatchFallback", "outcome": "admitted", "body": { "cpuFaceMatchReceipt": "cpu_face_match_receipt:fixture_cpu_face_match", "standingCreated": false, "rawImagesStored": false, "biometricTemplatesStored": false, "oneToManySearch": false }, "receipt": {...}}The body asserts the privacy invariants explicitly:
rawImagesStored: falsebiometricTemplatesStored: falseoneToManySearch: falsestandingCreated: false
Refused with human_auth_face_match_consent_missing if no
consent_ref is supplied. Consent is structurally required — not a
configuration toggle.
SDK example
Section titled “SDK example”const fallback = await client.humanAuthFaceMatch({ tenant: "tenant_node:rheinwerk_calibration", subject: "human_person:anna", consent_ref: "consent:fixture_cpu_face_match", scenario: "same-person",});Using a presence receipt
Section titled “Using a presence receipt”A human_presence_receipt:* (from passkey verify) or
cpu_face_match_receipt:* (from face-match fallback) is consumed by
two follow-on operations:
authority.presenceApproval— bind presence to actor/vessel for sensitive approval.effect.intent— sensitive effect intents require a presence receipt.
A presence receipt never by itself creates standing or delegation. That separation is constitutional.
Refusal codes
Section titled “Refusal codes”human_auth_face_match_consent_missinghuman_auth_passkey_user_not_verifiedhuman_auth_passkey_binding_unknownhuman_auth_challenge_expiredhuman_auth_challenge_replayedm13_human_presence_cannot_create_standing (returned by authority.presenceApproval)Where to read next
Section titled “Where to read next”- API: authority —
authority.presenceApproval,authority.sessionRevoke,authority.keyRotate - API: effects — sensitive effect intents
- Guide: human-auth flows
- Glossary: HumanAuth