Trust
GrayPass threat model
Version 1. Owner: GrayPass Labs engineering. Reviewed with every change to the authorization path.
GrayPass is designed to help an application assess one question: does the available evidence support that the enrolled operator remains in control for this specific action? The current behavioral claims are experimental. If a threat is not addressed here, assume it is not addressed by GrayPass.
What GrayPass is
Additive human-authority evidence at the moment of a consequential action. Your identity provider, passkeys, MFA, device management, and fraud systems stay exactly where they are. GrayPass supplies a fresh, typed Assurance Profile and a signed Proof of Agency so those systems can allow, challenge, hold, or stop execution.
Assets
| Asset | Where it lives | Why an attacker wants it |
|---|---|---|
| Brainprint template | Encrypted at rest, tenant- and environment-scoped | Impersonation, cross-context tracking |
| Evidence windows | In flight from the browser, transient in the engine | Forge behavior, replay a genuine session |
| Assurance Profile | Canonical server response; a relying party may deliberately render it | Learn what the detector sees, then evade it |
| Proof of Agency | Short-lived JWS held by the relying party | Authorize an action the human never approved |
| Proof signing key | AWS KMS in the production design; local test key in development | Forge unlimited authority |
| Decision traces | Database, tenant- and environment-scoped | Learn a customer's risk posture |
Trust boundaries
- Browser to API. The browser is untrusted. It submits derived features over TLS with a per-session HMAC, and receives a coverage summary and a human-readable status. A canonical browser credential never receives a score, similarity, threshold, Assurance Profile, or proof, and it cannot request authorization. A relying-party backend may deliberately display its own profile, as the local demo does. The HMAC binds bytes to a session; it does not prove that a human produced them. Script running in the page holds the same key.
- Customer backend to API. Trusted for the action request only. It states subject, action, resource, context, audience, nonce, and idempotency key. It cannot set a threshold, choose a decision, or read another tenant's data.
- API to engine. The engine is in-process. The canonical API converts its internal scores into typed claims and does not return those scores to a browser credential.
- API to relying party. Only through a Proof of Agency: signed with ES256, bound to one audience, one action hash, and a short lifetime.
Attacks in scope
| Attack | Defense | Residual risk |
|---|---|---|
| Session-cookie theft after login | Experimental continuity evidence, freshness, and action-bound challenge policy | Real-world containment is unverified pending recorded-human evaluation |
| Unattended-device takeover (walk-away) | Experimental within-session change indicator and freshness window | Handoff detection is not validated on recorded humans |
| Replay of captured evidence | Per-frame HMAC over exact body bytes, frame-id memory, monotonic client timestamps, window-overlap rejection | A live proxy that re-signs each window with the session key is limited by the key's session scope |
| Scripted or synthetic input | Narrow automation indicators on timing regularity, jitter absence, and replay; a firing hard signal holds by default and may be configured to deny | General bot detection is unsupported |
| Proof theft in transit | Audience binding, action-hash binding, short TTL, single-use consumption available | A relying party that ignores audience or hash checks defeats its own protection |
| Proof forgery | ES256; non-development configuration requires a KMS-held private key | KMS key policy and IAM configuration are verified by operators, outside the application |
| Sandbox proof used in production | Separate signing keys and an env claim; verifiers reject an environment mismatch |
A relying party that skips the environment check |
| Action substitution | The canonical action hash covers action, resource, context, subject, actor, audience, and nonce | A relying party that does not recompute the hash |
| Cross-tenant data access | tenant_id and environment_id are predicates on every query; uniform 404 for foreign rows |
None known; enforced by tests |
| Threshold tampering | Thresholds live in immutable policy versions server-side; the API rejects client thresholds | A customer admin can weaken their own policy, which is audited |
| Non-finite / overflow feature forgery | Boundary sanitizer neutralizes non-finite values, forged modalities are forced to anti-match, and every clamp is NaN-safe fail-closed | None known; enforced by tests |
| Challenge replay | The WebAuthn challenge is the request-bound digest; one challenge, one request, single use | None known |
| Decision looping | A request chain escalates to hold after the policy's max_challenges |
None |
Attacks explicitly out of scope
- A fully compromised endpoint. Malware with code execution in the page
can fabricate plausible evidence and drive the UI. GrayPass raises the
cost, it does not eliminate this. Every Assurance Profile carries
limitation.compromised_endpoint_not_detectable. - Who the enrollee was. GrayPass proves continuity with the enrolled operator, not that the enrolled operator is the account's rightful owner. See enrollment.md.
- Physical coercion. A person acting under duress produces genuine behavior. GrayPass cannot detect coercion.
- Malicious relying party. A customer that ignores a
denyand executes anyway is outside our control; outcome reporting makes it visible. - Malicious insider at GrayPass with KMS authority. Mitigated by key policy, audit logging, and separation of duties, not by cryptography.
- Personhood or uniqueness. GrayPass does not attest that a subject is a unique human being.
- Device integrity. No attestation evidence is accepted today; the claim
is reported as
unsupported.
What a determined attacker should do to break us
Stated plainly, so it can be tested rather than argued about:
- Compromise the endpoint after enrollment and drive the real UI with synthesized-but-humanlike input inside a live, signed session.
- Enroll as the victim in the first place, by taking over the account before enrollment (this is why the enrollment anchor is a first-class, reported property).
- Get a relying party to skip audience, action-hash, or environment verification on the proof.
- Persuade a customer admin to lower a policy or set an action to
test.
Every one of these is a defensible engineering target with a test. None of them is fixed by a marketing claim.
Generated from the API contract in contracts/ and the source in docs/. The build fails if this page disagrees with the running API.