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

  1. 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.
  2. 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.
  3. 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.
  4. 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

What a determined attacker should do to break us

Stated plainly, so it can be tested rather than argued about:

  1. Compromise the endpoint after enrollment and drive the real UI with synthesized-but-humanlike input inside a live, signed session.
  2. 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).
  3. Get a relying party to skip audience, action-hash, or environment verification on the proof.
  4. 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.