Skip to main content

verify

Function verify 

Source
pub async fn verify(
    request: &SignedRequest<'_>,
    config: &VerifierConfig,
    jwks: &IssuerJwks,
    replay_store: &dyn ReplayStore,
) -> Result<DeviceIdentity, VerifyError>
Expand description

Verifies a device-bound signed request against the configured trust policy.

request.signature and request.attestation carry the two credentials (see SignedRequest); this function is deliberately framework-agnostic so it can be called from a tower::Layer (see the optional axum feature), a future authkestra trait-based integration, or a plain test harness — the algorithm itself does not care which.

Order, and why it is load-bearing:

  1. Presence — both credentials must be present. An attestation alone is a bearer token (it is public, travels in every request, and is likely logged); rejecting this case is what keeps the attestation from becoming exactly the weaker-than-normal scheme this design exists to avoid.
  2. Parse + alg check — for both credentials, cheap, before any cryptographic work.
  3. Attestation trust — issuer, kid, signature, expiry, device status.
  4. The binding — recompute the embedded jwk’s RFC 7638 thumbprint and compare it, constant-time, to the attestation’s cnf.jkt. This is the step that cannot be inferred from the other two. An attacker holding a victim’s attestation (public, not secret) and their own genuinely-held keypair passes steps 3 and 5 independently and completely; only this comparison detects that the two credentials describe different keys. Skipping, reordering, or short-circuiting it is a total authentication bypass.
  5. Request-signature verification against that now-bound jwk.
  6. Freshness — skew window, maximum signature lifetime.
  7. Request binding — method, path, audience, query hash, body hash.
  8. Replay — recorded last, and fails closed on any store error, not just “already present”. A replay store that cannot be reached must reject exactly as if the jti had already been seen; falling back to “allow” would silently disable replay protection during an outage, which is worse than rejecting traffic.