Stop API abuse at the edge.

Verify that every request comes from a legitimate installation of your app running on a genuine Apple device. Perfect for Supabase Edge Functions.

attestation.ts
import { verifyAttestation } from '@bradford-tech/supabase-integrity-attest'
const result = await verifyAttestation(
{ appId: 'TEAMID1234.com.example.app' },
keyId,
challenge,
attestation,
)

supabase-integrity-attest

Server-side Apple App Attest verification for Supabase Edge Functions, built entirely on WebCrypto.

New to App Attest?

Understand the problem this library solves and get set up in minutes.

Ready to integrate?

Jump straight to setting up verification in your Supabase Edge Functions.

API reference

Full function signatures, parameter details, and error code reference.

Design & architecture

Understand the implementation: why WebCrypto, why not pkijs, and the verification pipeline.


What this library does

Mobile apps embed API keys that are trivially extractable via MITM tools like mitmproxy. IP-based rate limiting is just as easily bypassed with rotating proxies. Apple's App Attest solves this by leveraging the Secure Enclave to create hardware-backed cryptographic proof that requests originate from a genuine app on a real device.

This library verifies those proofs server-side. It handles the full attestation verification pipeline (CBOR decoding, X.509 certificate chain validation, nonce verification, key extraction) and the per-request assertion signature check — all using the WebCrypto API so it runs natively in Deno and Supabase Edge Functions without any Node.js compatibility issues.

  • WebCrypto only — zero dependency on node:crypto. Runs in Deno Deploy, Supabase Edge Functions, and any runtime with crypto.subtle.
  • Full verification pipeline — CBOR decode, X.509 certificate chain validation, nonce check, key extraction, ECDSA signature verify. Nothing is skipped or stubbed.
  • Supabase-native — designed for Supabase Edge Functions from day one, but works with any Deno or Node.js server.
  • No compatibility hacks — no pkijs (crashes in Supabase's edge runtime), no @peculiar/x509 (global side effects from tsyringe). Just standards-based crypto.

Assertion middleware

Once a device is attested, use withAssertion() to verify every subsequent request with a single wrapper:

import { withAssertion } from '@bradford-tech/supabase-integrity-attest/assertion'

Deno.serve(
  withAssertion(
    async (req, ctx) => {
      // ctx.deviceKey is verified — the request is from a genuine device
      return new Response('OK')
    },
    {
      getDeviceKey: async (keyId) => {
        /* look up public key + sign count from your database */
      },
      updateSignCount: async (keyId, counter) => {
        /* persist the new counter value */
      },
    },
  ),
)

withAssertion() extracts the assertion from the request, verifies the signature against the stored public key, checks the counter to prevent replay attacks, and hands you a verified ctx.deviceKey. See the assertion verification guide and API reference for the full details.


Install

# Deno / JSR
deno add jsr:@bradford-tech/supabase-integrity-attest
# Node.js / npm
npm install @bradford-tech/supabase-integrity-attest