{"_id":"@bradford-tech/supabase-integrity-attest","_rev":"24-513654c33bc2748be6322e97faa895e0","name":"@bradford-tech/supabase-integrity-attest","dist-tags":{"latest":"0.9.1"},"versions":{"0.2.1":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.2.1","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.2.1","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://github.com/bradford-tech/supabase-integrity-attest#readme","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"e341fe44b00d4432487ec9cef59e2e1596ae82bc","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.2.1.tgz","fileCount":89,"integrity":"sha512-NUoGM2zO+yH723aSmgxywjFTlf5VqmGm1TKJ9fVQL4ePvfNGuNkpl2xzoPOVMDgpajpXZVr9KnViNJ4h7rnPnA==","signatures":[{"sig":"MEYCIQDQ90Guy61+Fs+ZYUTqbu4vw6Bc3V58YA4S/ChBrqKtTgIhAJmrfmtAdc70dS3CV5ZRtayJmjHTbR/rCg9okKvj5/Zy","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":70841},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"}},"gitHead":"c73caf8a9ddd482a640455cc22c8ae89bf215873","scripts":{"test":"node test_runner.js"},"_npmUser":{"name":"sbs44","email":"focal-flusher.0g@icloud.com"},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.9.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cborg":"^4.5.8","pkijs":"^3.3.3","asn1js":"^3.0.7"},"_hasShrinkwrap":false,"devDependencies":{"picocolors":"^1.0.0","@types/node":"^20.9.0","@deno/shim-deno-test":"~0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.2.1_1772939414278_0.1978084021780555","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.2.2","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.2.2","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://github.com/bradford-tech/supabase-integrity-attest#readme","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"65acd57164a8a7032d5e072f48fa50b2f5683b8c","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.2.2.tgz","fileCount":89,"integrity":"sha512-nrvf9Nshb899R+FA33cuXWqUs6jsHp1y75FR83oElSojz8M8Fcn4EDXhmBE6nwyq6ZTSWA3qGglmXW6NC33m5w==","signatures":[{"sig":"MEUCIQCzJT6Z9cSAfsZ+GWfXck+5PFWlyIw8AIKVZryp2Lv7CgIgeWtBrTUHADR4+HWdOwA1Q09XX5ad3FrApE8Y3VwMH0U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":81947},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"}},"gitHead":"6c7aadb14ae2511a3c68d57532c0ae5805f10ba9","scripts":{"test":"node test_runner.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.9.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"picocolors":"^1.0.0","@types/node":"^20.9.0","@deno/shim-deno-test":"~0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.2.2_1772951857624_0.23751594204670123","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.2.3","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.2.3","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://github.com/bradford-tech/supabase-integrity-attest#readme","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"e362fa69ddcd5345cb43f12636a8f9ae6c97e4f9","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.2.3.tgz","fileCount":89,"integrity":"sha512-KEn9GyMrM05//qK9Ib5SMs1X/ciMMMzW6CkN7552rCI6CYOBdRqWkjVYs2sbek0jIqW4LGHyXEKZuNPDVgQLfQ==","signatures":[{"sig":"MEUCIQCKtdcf318s1bj5y0gWksAKiOiTtM8ugRmOtMT9kaG1igIgEoLHVdeN/+PqDB8+7YEufA93aWTI66kLC94FxiqYGZg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.2.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":82096},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"}},"gitHead":"9e4b53be7e68916067f56a266bdcd5b1d2a1c48a","scripts":{"test":"node test_runner.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.9.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"picocolors":"^1.0.0","@types/node":"^20.9.0","@deno/shim-deno-test":"~0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.2.3_1772953020017_0.25432428636494375","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.2.4","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.2.4","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://github.com/bradford-tech/supabase-integrity-attest#readme","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"0545e286bb6788ef3fe49759a8e0bcf065755448","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.2.4.tgz","fileCount":89,"integrity":"sha512-P8cc0t7i2SqF0wRdgPEa7tE9ApLEDdYFraNsAV+2Lvots8eDAsj1vq/6AXXCo8TtEEb4JYokv6hBCcx6VwfDuA==","signatures":[{"sig":"MEUCIHaohnpHLvZlMIkbW/FBGd8yZ4XPsAyfX/9R38eR8uVsAiEA0jVJXoFIzpJwTAGo7DZHb1qVYYfm9NeJk24W951YtcU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.2.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":82263},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"}},"gitHead":"5e6144b663ab92192b06cf148b7b12f8f071ab61","scripts":{"test":"node test_runner.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.9.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"picocolors":"^1.0.0","@types/node":"^20.9.0","@deno/shim-deno-test":"~0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.2.4_1772955804884_0.5858154564170803","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.3.0","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.3.0","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://github.com/bradford-tech/supabase-integrity-attest#readme","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"223d1f607cffe0d2fc5e49332c6094500be75e45","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.3.0.tgz","fileCount":97,"integrity":"sha512-zQk7OUP3CksCD5mOJEpADpOKl+kM7Yzp/tmzsaHqzwzTe4pzioKAiQplr1UMJheixcy4CKYaBulUOE5Cnnjq4w==","signatures":[{"sig":"MEYCIQDTO/pNUro6sgQl3FWyzU5/TITp3p67HO/FUjfJs9qBQwIhAM8bSdRQU5gm3xTey7Qp8lIcl5+HotqRLDQaJkKwx6NH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":84142},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"3d9988d47f3ef8f99c2b6e9bf20d23709af5782c","scripts":{"test":"node test_runner.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.9.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"picocolors":"^1.0.0","@types/node":"^20.9.0","@deno/shim-deno-test":"~0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.3.0_1772959955508_0.5661287708474267","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.3.1","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.3.1","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://github.com/bradford-tech/supabase-integrity-attest#readme","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"b6c2d0d655cdb7cc1729cc5679bda282b8b13a0c","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.3.1.tgz","fileCount":102,"integrity":"sha512-Xea9gILFALLHTZ3ossQVsXj2vnWOl+k1puFXy85d5eb1imo+qDCFtvijAxJDac4wKDTbmYdzWvBotZlKBs7FIg==","signatures":[{"sig":"MEUCIQDA8OazdLy01XOZbUCohhJC2xTE4MPspH3ibbt8b0fsBwIgBASsGT7DLFrCjlDBlBmmUQmZR0XLkxlpdS3spkATUow=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":94832},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"e80c0f7094a29854c9a7d31b25a115d3ee222c0a","scripts":{"test":"node test_runner.js"},"_npmUser":{"name":"sbs44","email":"focal-flusher.0g@icloud.com"},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.9.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"picocolors":"^1.0.0","@types/node":"^20.9.0","@deno/shim-deno-test":"~0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.3.1_1773270451289_0.9533396336034095","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.3.2","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.3.2","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://github.com/bradford-tech/supabase-integrity-attest#readme","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"b3beef62dc91342651980b65504d6f73e09bd0a1","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.3.2.tgz","fileCount":102,"integrity":"sha512-GbDBPV7kNIbrGwJejB0N20ikqmbxC1KOuFVYdFGIPzEbmeV8hwJW+o4PmQBLqZXbc+nNRBEuuHk9IKGGC3xSMw==","signatures":[{"sig":"MEYCIQDBFqPb/dnqtBNHV9AGexTeSoiHh+LxIzU1VVSIv8p3jgIhAPWkv/APkiv2CU4kNXqXkdQjaXcl+84CYiwmwyHDOSDY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.3.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":104611},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"d47895691f11789917913af9c7102846bb5b6c08","scripts":{"test":"node test_runner.js"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.9.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.0","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"picocolors":"^1.0.0","@types/node":"^20.9.0","@deno/shim-deno-test":"~0.5.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.3.2_1773330517119_0.115491806403478","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.4.1","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.4.1","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://integrity-attest.bradford.tech","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"9f64fd1f3de79d63e8adefc983250d5ff7aa6ef2","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.4.1.tgz","fileCount":55,"integrity":"sha512-lUMmimM4gf5lrFzEpaWXxdOgH50XM6A1FMOBsK/TWIjRNaHgH5KgLN8lXNplerLJw9ImcCnfz7jQEypeXk7hyQ==","signatures":[{"sig":"MEQCIFrDFMI4Rz73swPcGGh2P80flJuRKNnk4V2zrju5xR+MAiAHdE1dzm24/Z31dHUaUlmPsNz0tsyA/yvKMnURx/BqHg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":109319},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"3eaf90477aad7bc9666a70d01cb1d590b811e573","scripts":{},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.11.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.9.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.4.1_1776027524594_0.8119602765724367","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.5.0","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.5.0","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://integrity-attest.bradford.tech","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"17641b17cf752c058ec2ec99c1817bc59b7fdd57","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.5.0.tgz","fileCount":55,"integrity":"sha512-B1KVEgtAJI7YpUk8ovoz1A9QOmt/W5POOQTZ9U+3Yf4uKXFWPaiyL3ACf3hpMpJn0XBSiHE+/3nbfo8Sb/MyAQ==","signatures":[{"sig":"MEQCIFlcyOcZ/7MagfSulQea2ZnPDF4zOp564FuKgyAXb1yUAiBf1M/OZQwQMYhMdNPIJHrOj4SmB/KNY0RPUxn97RVKbg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.5.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":111797},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"ace64edc806f37ba9fca5a830241ea7f161b5522","scripts":{},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"deprecated":"This version is deprecated. Please upgrade to v0.7.0 or later.","repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.11.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.9.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.5.0_1776061833666_0.3133450942726661","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.7.0","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.7.0","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://integrity-attest.bradford.tech","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"ba99984bc1d6722b6af9baf4bd7fb48bd758a427","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.7.0.tgz","fileCount":55,"integrity":"sha512-10uy2unwGSwfLw7IqxsDY/2d13xkTnY2bpPt4S+z7sOvCuHHujtjEVM8x8xe5y5zN3hi+ADt0TbUYVRFmc04hw==","signatures":[{"sig":"MEYCIQD3N8ow2QoG1QRwzhq5jJcyS33hhFYMu+pvphvJI4HxGQIhANF0pIgY07XoHX2NdF0WAvVSb0WdHnSMYVBwjU3gxhVb","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.7.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":112994},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"3d671f69126a0dc9127f816f56f02bedaa2f2ca3","scripts":{},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.11.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"cborg":"^4.5.8","asn1js":"^3.0.7","@noble/curves":"^2.0.1"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.9.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.7.0_1776069181789_0.7729575849845467","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.8.0","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.8.0","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://integrity-attest.bradford.tech","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"1357aa40fb4cb10e68388c9a185cc3ce0f51ba49","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.8.0.tgz","fileCount":55,"integrity":"sha512-xditOfY6bzrooQHwG5wAxF5Wclj2pZWWJKUuhaKgHe2eDtspHyuz14usQoCEQXYyNyxAmZc0wQ1eoRRiPxE45Q==","signatures":[{"sig":"MEUCIQD1GASfxc3f5Gi2EY2jFQfO4LX41BC1HpbHKKSu83T1dgIgWhERWy5lAfltQHFg4HRoZjCjMXXDLYb6vqm3spkwXnk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.8.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":114231},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"e651a3a71a11d54ab2af5dd352e9b88963e17692","scripts":{},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.11.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"cborg":"^5.1.0","asn1js":"^3.0.10","@noble/curves":"^2.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.9.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.8.0_1776760646820_0.7477778265134334","host":"s3://npm-registry-packages-npm-production"}},"0.8.1":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.8.1","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.8.1","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://integrity-attest.bradford.tech","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"6bc0046f5594dccd68ef78c9075238b7a988dd09","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.8.1.tgz","fileCount":55,"integrity":"sha512-HHyGmoQfnpUPekHzH/Abf3Z91TP70vf5EP0YyWYZ7MHnbGZwktumW7tP0RuNeLkmE6XwmpeNTU6xhFONRSc0nw==","signatures":[{"sig":"MEUCIBq11FQhYKTNkavq4LDCPl5guInhiDWKKdYIHalydqktAiEA0LPM8bI9RzZNhz15OoqGXPIc0OnF2g+pyh8vFHsHqRA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.8.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":115036},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"e7ce714f73ffad41a6e05e4e56aeddb4e32c00b1","scripts":{},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.11.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"cborg":"^5.1.0","asn1js":"^3.0.10","@noble/curves":"^2.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.9.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.8.1_1777022880737_0.7151141337210982","host":"s3://npm-registry-packages-npm-production"}},"0.8.2":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.8.2","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.8.2","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://integrity-attest.bradford.tech","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"31d4388abc5358bc191a1317b5e5538ee43e1d6b","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.8.2.tgz","fileCount":55,"integrity":"sha512-XJsRRipw6k+0ScCCep1FKH1ejEjgGZ+h5JOv2rxaxQxXxuL5zpbSdK41PRsS514Nj5xnM7C2ErDewFK70WlTjQ==","signatures":[{"sig":"MEYCIQDL4qqhZ6XExt5EcSSvuQ2Dxm+q9crLAtMj6qb7wcmvqAIhAMM7Yq1w72CUjT3T0TGJOh/NI6PFaWAAdOCbKd/BZig4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.8.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":119879},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"b6244153e14d344a0c89509f3a416d7371449f66","scripts":{},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.11.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.14.1","dependencies":{"cborg":"^5.1.0","asn1js":"^3.0.10","@noble/curves":"^2.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.9.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.8.2_1777047411980_0.7534332210412125","host":"s3://npm-registry-packages-npm-production"}},"0.9.0":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.9.0","license":"MIT","_id":"@bradford-tech/supabase-integrity-attest@0.9.0","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"homepage":"https://integrity-attest.bradford.tech","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"dist":{"shasum":"5fd6d856c9dde31e3ffe0e739a2d3a1c35e3ce32","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.9.0.tgz","fileCount":43,"integrity":"sha512-aN0k0pp1ugvYd+gnzk4/+2ahsC2xcUG2oQBjFa4Zvf6L2kf/BKu9jQ3eK4WoUQlMzhQ2WU77SqDTyFa1D2u0mA==","signatures":[{"sig":"MEYCIQCZ1xipy/RC8aLeRRcQZPWcXRMtnmezLGXjUInKHtzNkwIhALdCqyqR7/fuESdUo3BMRgsBE2Lrdj6x5Rl0KcGe8aVg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.9.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":125637},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./supabase":{"import":"./esm/supabase.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"}},"gitHead":"3a69708bdc3a2dcaed0a88f4c2b7445acdfba056","scripts":{},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"repository":{"url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git","type":"git"},"_npmVersion":"11.16.0","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","directories":{},"_nodeVersion":"24.18.0","dependencies":{"cborg":"^6.1.1","asn1js":"^3.0.10","@noble/curves":"^2.2.0"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.9.0"},"_npmOperationalInternal":{"tmp":"tmp/supabase-integrity-attest_0.9.0_1785539453218_0.9894169038102658","host":"s3://npm-registry-packages-npm-production"}},"0.9.1":{"name":"@bradford-tech/supabase-integrity-attest","version":"0.9.1","description":"Verify Apple App Attest attestations and assertions using WebCrypto.","homepage":"https://integrity-attest.bradford.tech","repository":{"type":"git","url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git"},"license":"MIT","bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"module":"./esm/mod.js","exports":{".":{"import":"./esm/mod.js"},"./assertion":{"import":"./esm/assertion.js"},"./attestation":{"import":"./esm/attestation.js"},"./supabase":{"import":"./esm/supabase.js"}},"scripts":{},"dependencies":{"@noble/curves":"^2.2.0","asn1js":"^3.0.10","cborg":"^6.1.1"},"devDependencies":{"@types/node":"^20.9.0"},"gitHead":"e1a60af7d6a7488a182e0a799f0c4c8842f5b4c9","_id":"@bradford-tech/supabase-integrity-attest@0.9.1","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-JgqWxHPNLx1KPQAfs4b+ag4sl86czv6brA0kuD2wvEb6cIjlTNXCUuThHjAqoN6snMBTqXj0iVNhV0F3FfJvww==","shasum":"71ee82e277161aa8387f79034715cef92f2ce623","tarball":"https://registry.npmjs.org/@bradford-tech/supabase-integrity-attest/-/supabase-integrity-attest-0.9.1.tgz","fileCount":43,"unpackedSize":129516,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bradford-tech%2fsupabase-integrity-attest@0.9.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCd6WZ0+j+mKqyIYQt3cpN7qDLPHCirGmnEB/8+IHfrzwIhAJGeYsME7nNEVD2x3ENBGPvCjvQoNzKh1Q6nKszxmrKL"}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:84b7bc72-e77b-4b90-b8cd-d1f256e5b38c"}},"directories":{},"maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/supabase-integrity-attest_0.9.1_1785571059503_0.004935984514598424"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-08T03:10:14.222Z","modified":"2026-08-01T07:57:40.066Z","0.2.1":"2026-03-08T03:10:14.463Z","0.2.2":"2026-03-08T06:37:37.770Z","0.2.3":"2026-03-08T06:57:00.187Z","0.2.4":"2026-03-08T07:43:25.115Z","0.3.0":"2026-03-08T08:52:35.669Z","0.3.1":"2026-03-11T23:07:31.480Z","0.3.2":"2026-03-12T15:48:37.319Z","0.4.1":"2026-04-12T20:58:44.738Z","0.5.0":"2026-04-13T06:30:33.795Z","0.7.0":"2026-04-13T08:33:01.953Z","0.8.0":"2026-04-21T08:37:26.964Z","0.8.1":"2026-04-24T09:28:00.848Z","0.8.2":"2026-04-24T16:16:52.119Z","0.9.0":"2026-07-31T23:10:53.358Z","0.9.1":"2026-08-01T07:57:39.731Z"},"bugs":{"url":"https://github.com/bradford-tech/supabase-integrity-attest/issues"},"license":"MIT","homepage":"https://integrity-attest.bradford.tech","repository":{"type":"git","url":"git+https://github.com/bradford-tech/supabase-integrity-attest.git"},"description":"Verify Apple App Attest attestations and assertions using WebCrypto.","maintainers":[{"name":"sbs44","email":"focal-flusher.0g@icloud.com"}],"readme":"# supabase-integrity-attest\n\nApple App Attest server-side verification for edge runtimes, using only WebCrypto.\n\n## Install\n\n```bash\n# Deno\ndeno add jsr:@bradford-tech/supabase-integrity-attest\n\n# npm\nnpm install @bradford-tech/supabase-integrity-attest\n```\n\n## Quick start\n\nVerify a device attestation and extract its public key:\n\n```ts\nimport { verifyAttestation } from \"@bradford-tech/supabase-integrity-attest\";\n\nconst clientDataHash = new Uint8Array(\n  await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(challenge)),\n);\n\nconst { publicKeyPem, signCount } = await verifyAttestation(\n  { appId: \"TEAMID.com.example.app\" },\n  keyId,          // base64 key identifier from client\n  clientDataHash, // SHA-256 of the challenge you issued\n  attestation,    // base64 CBOR attestation from client\n);\n// publicKeyPem: \"-----BEGIN PUBLIC KEY-----\\nMFkw...\"\n// signCount: 0\n```\n\nStore `publicKeyPem` and `signCount` for this device. Use them to verify future assertions.\n\n## Why this library\n\nExisting App Attest verification libraries depend on `node:crypto` or packages that crash in edge runtimes. `appattest-checker-node` uses `X509Certificate.verify()`, which throws `ERR_NOT_IMPLEMENTED` in Deno. `pkijs` crashes at module load in Supabase Edge Functions because `self.crypto.name` is undefined. `@peculiar/x509` pulls in `tsyringe` and `reflect-metadata`, which rely on global side effects during module initialization.\n\nThis library uses only `crypto.subtle` for cryptographic operations, with `asn1js` for X.509 parsing and `@noble/curves` for one operation Deno's WebCrypto doesn't support (P-384 signature verification on Apple's intermediate certificate).\n\n## Middleware\n\nBoth middleware wrappers below use a Supabase service-role client for database access:\n\n```ts\nimport { createClient } from \"jsr:@supabase/supabase-js@2\";\n\nconst supabase = createClient(\n  Deno.env.get(\"SUPABASE_URL\")!,\n  Deno.env.get(\"SUPABASE_SERVICE_ROLE_KEY\")!,\n);\n```\n\n### `withAttestation` -- device registration\n\n`withAttestation` wraps a one-time device registration endpoint with automatic challenge consumption, attestation verification, and device key storage:\n\n```ts\nimport { withAttestation } from \"@bradford-tech/supabase-integrity-attest\";\n\nDeno.serve(withAttestation({\n  appId: Deno.env.get(\"APP_ATTEST_APP_ID\")!,\n  consumeChallenge: async (challenge) => {\n    const id = new TextDecoder().decode(challenge);\n    const { data } = await supabase\n      .from(\"attestation_challenges\")\n      .delete()\n      .eq(\"id\", id)\n      .select(\"id\");\n    return (data?.length ?? 0) > 0;\n  },\n  storeDeviceKey: async ({ deviceId, publicKeyPem, signCount }) => {\n    await supabase\n      .from(\"device_attestations\")\n      .upsert({ key_id: deviceId, public_key_pem: publicKeyPem, sign_count: signCount });\n  },\n}, (_req, ctx) => {\n  // ctx.deviceId, ctx.publicKeyPem, ctx.signCount, ctx.receipt, ctx.timings\n  return Response.json({ deviceId: ctx.deviceId });\n}));\n```\n\n`consumeChallenge` must be atomic: return `true` if the challenge was valid, unused, and unexpired (and is now consumed), `false` otherwise. Use `DELETE ... RETURNING` to guarantee single-use semantics.\n\nThe default extractor reads a JSON body:\n\n```\nPOST /functions/v1/attest\nContent-Type: application/json\n\n{\"keyId\": \"<base64>\", \"challenge\": \"<base64>\", \"attestation\": \"<base64>\"}\n```\n\n### `withAssertion` -- protected requests\n\n`withAssertion` wraps any protected endpoint with automatic assertion verification, device key lookup, and sign count commit:\n\n```ts\nimport { withAssertion } from \"@bradford-tech/supabase-integrity-attest\";\n\nDeno.serve(withAssertion({\n  appId: Deno.env.get(\"APP_ATTEST_APP_ID\")!,\n  getDeviceKey: async (deviceId) => {\n    const { data } = await supabase\n      .from(\"device_attestations\")\n      .select(\"public_key_pem, sign_count\")\n      .eq(\"key_id\", deviceId)\n      .single();\n    return data\n      ? { publicKeyPem: data.public_key_pem, signCount: data.sign_count }\n      : null;\n  },\n  commitSignCount: async (deviceId, newSignCount) => {\n    const { data } = await supabase\n      .from(\"device_attestations\")\n      .update({ sign_count: newSignCount })\n      .eq(\"key_id\", deviceId)\n      .lt(\"sign_count\", newSignCount)\n      .select(\"key_id\");\n    return (data?.length ?? 0) > 0;\n  },\n}, async (_req, { rawBody }) => {\n  const payload = JSON.parse(new TextDecoder().decode(rawBody));\n  return Response.json({ ok: true });\n}));\n```\n\nThe client sends the assertion and device ID in headers. The request body is the signed client data:\n\n```\nPOST /functions/v1/your-endpoint\nX-App-Attest-Assertion: <base64-encoded assertion>\nX-App-Attest-Device-Id: <base64-encoded keyId>\nContent-Type: application/json\n\n{\"text\": \"Hello world\", \"voice\": \"en-US\"}\n```\n\n### Sign count atomicity\n\n`commitSignCount` **must** use compare-and-swap: only update the stored count if the current value is strictly less than `newSignCount`. An unconditional `UPDATE ... SET sign_count = $1` silently breaks replay protection when two requests arrive concurrently.\n\n```sql\nUPDATE device_attestations\n   SET sign_count = $1, last_seen_at = now()\n WHERE key_id = $2 AND sign_count < $1\n```\n\nReturn `true` if the row was updated. The library converts `false` into `AssertionError(SIGN_COUNT_STALE)`.\n\n### Shared options\n\nOnce you have multiple protected functions, extract the shared options:\n\n```ts\n// supabase/functions/_shared/attest.ts\nimport type { WithAssertionOptions } from \"@bradford-tech/supabase-integrity-attest\";\n\nexport const assertionOptions: WithAssertionOptions = {\n  appId: Deno.env.get(\"APP_ATTEST_APP_ID\")!,\n  // ... getDeviceKey, commitSignCount as above\n};\n```\n\n```ts\n// supabase/functions/text-to-speech/index.ts\nimport { withAssertion } from \"@bradford-tech/supabase-integrity-attest\";\nimport { assertionOptions } from \"../_shared/attest.ts\";\n\nDeno.serve(withAssertion(assertionOptions, async (_req, { rawBody }) => {\n  const { text, voice } = JSON.parse(new TextDecoder().decode(rawBody));\n  return Response.json({ audio: \"...\" });\n}));\n```\n\n## Supabase adapter\n\nOn Supabase, skip writing the callbacks entirely. The `/supabase` subpath ships `createSupabaseAdapter()`, which provides all four storage callbacks plus `issueChallenge()`, backed by two Postgres tables:\n\n```ts\nimport { withAttestation } from \"@bradford-tech/supabase-integrity-attest/attestation\";\nimport { createSupabaseAdapter } from \"@bradford-tech/supabase-integrity-attest/supabase\";\n\nconst adapter = createSupabaseAdapter(supabase); // service-role client\n\n// Challenge endpoint\nconst { challengeBase64, expiresAt } = await adapter.issueChallenge(\"attestation\");\n\n// Registration endpoint -- adapter supplies consumeChallenge + storeDeviceKey\nDeno.serve(withAttestation(\n  { appId: Deno.env.get(\"APP_ATTEST_APP_ID\")!, ...adapter },\n  (_req, ctx) => Response.json({ deviceId: ctx.deviceId }),\n));\n\n// Protected endpoints -- adapter supplies getDeviceKey + commitSignCount\n// withAssertion({ appId, ...adapter }, handler)\n```\n\nThe schema ships with the package as [`sql/app_attest.sql`](./sql/app_attest.sql) (both tables, RLS locked to service role, expiry index, pg_cron sweep of expired challenges). Table names and challenge TTL are configurable via the options argument. `@supabase/supabase-js` is not a dependency — the client is typed structurally, so any recent client works.\n\nApp Attest proves device integrity, not user identity: the adapter and middleware compose alongside Supabase Auth, AWS Cognito, or any bearer JWT.\n\n## Low-level API\n\nFor full control over the verification flow, use `verifyAttestation` and `verifyAssertion` directly.\n\nThe quick start above shows `verifyAttestation`. Note that `clientDataHash` must be SHA-256 of the challenge, not the raw challenge. Client SDKs (Expo's `attestKeyAsync`, native `DCAppAttestService.attestKey`) hash the challenge internally before passing to Apple; you must produce the same hash server-side. The `withAttestation` middleware handles this automatically.\n\n### Assertion\n\n```ts\nimport { verifyAssertion } from \"@bradford-tech/supabase-integrity-attest\";\n\nconst { signCount } = await verifyAssertion(\n  { appId: \"TEAMID.com.example.app\" },\n  assertion,         // base64 CBOR from client\n  clientData,        // the request payload that was signed\n  storedPublicKeyPem,\n  storedSignCount,\n);\n// Update stored signCount to signCount\n```\n\n## Subpath imports\n\nImport only what you need to reduce bundle size:\n\n```ts\n// Full library (attestation + assertion)\nimport { verifyAttestation, verifyAssertion } from \"@bradford-tech/supabase-integrity-attest\";\n\n// Assertion only -- skips asn1js and @noble/curves\nimport { verifyAssertion, withAssertion } from \"@bradford-tech/supabase-integrity-attest/assertion\";\n\n// Attestation only\nimport { verifyAttestation, withAttestation } from \"@bradford-tech/supabase-integrity-attest/attestation\";\n\n// Supabase storage adapter\nimport { createSupabaseAdapter } from \"@bradford-tech/supabase-integrity-attest/supabase\";\n```\n\n## Error handling\n\n```ts\nimport {\n  AttestationError,\n  AssertionError,\n} from \"@bradford-tech/supabase-integrity-attest\";\n\ntry {\n  await verifyAttestation(appInfo, keyId, clientDataHash, attestation);\n} catch (e) {\n  if (e instanceof AttestationError) {\n    console.log(e.code);\n    // => \"NONCE_MISMATCH\"\n  }\n}\n```\n\n### Attestation error codes\n\n| Code | Meaning |\n| --- | --- |\n| `INVALID_FORMAT` | CBOR decoding or structural validation failed |\n| `INVALID_CERTIFICATE_CHAIN` | X.509 certificate chain verification failed |\n| `NONCE_MISMATCH` | Computed nonce does not match the certificate nonce |\n| `RP_ID_MISMATCH` | RP ID hash does not match SHA-256 of the app ID |\n| `KEY_ID_MISMATCH` | Public key hash does not match the provided key ID |\n| `INVALID_COUNTER` | Sign count is not zero (required for attestation) |\n| `INVALID_AAGUID` | AAGUID does not match the expected environment |\n| `CHALLENGE_INVALID` | Challenge missing, expired, or already consumed (`withAttestation` only) |\n| `INTERNAL_ERROR` | Storage callback or internal error (`withAttestation` only) |\n\n### Assertion error codes\n\n| Code | Meaning |\n| --- | --- |\n| `INVALID_FORMAT` | CBOR decoding or structural validation failed |\n| `RP_ID_MISMATCH` | RP ID hash does not match SHA-256 of the app ID |\n| `COUNTER_NOT_INCREMENTED` | Sign count was not greater than the stored value |\n| `SIGNATURE_INVALID` | ECDSA signature verification failed |\n| `DEVICE_NOT_FOUND` | No device key for the given device ID (`withAssertion` only) |\n| `INTERNAL_ERROR` | Storage callback or internal error (`withAssertion` only) |\n| `SIGN_COUNT_STALE` | Concurrent request already advanced the counter (`withAssertion` only) |\n\n## Development environment\n\nFor apps using Apple's development App Attest environment, pass `developmentEnv: true`:\n\n```ts\nawait verifyAttestation(\n  { appId: \"TEAMID.com.example.app\", developmentEnv: true },\n  keyId,\n  clientDataHash,\n  attestation,\n);\n```\n\n`withAttestation` also accepts `developmentEnv` in its options.\n\n## Documentation\n\nFull documentation at [integrity-attest.bradford.tech](https://integrity-attest.bradford.tech).\n\n## Contributing\n\nIssues and pull requests are welcome on [GitHub](https://github.com/bradford-tech/supabase-integrity-attest).\n\n## Security\n\nSee [SECURITY.md](./SECURITY.md) for vulnerability reporting.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}