{"_id":"@ai-sdk-byok/cloudflare","name":"@ai-sdk-byok/cloudflare","dist-tags":{"latest":"0.2.0"},"versions":{"0.2.0":{"name":"@ai-sdk-byok/cloudflare","version":"0.2.0","description":"Cloudflare D1 storage adapter and Workers KV credential cache for ai-sdk-byok.","license":"MIT","homepage":"https://github.com/Xyri1/ai-sdk-byok#readme","repository":{"type":"git","url":"git+https://github.com/Xyri1/ai-sdk-byok.git","directory":"packages/cloudflare"},"bugs":{"url":"https://github.com/Xyri1/ai-sdk-byok/issues"},"type":"module","sideEffects":false,"engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"dependencies":{"ai-sdk-byok":"0.2.0"},"gitHead":"f79474d0a535b1083bdfc54440bd30592a3b16af","_id":"@ai-sdk-byok/cloudflare@0.2.0","_nodeVersion":"24.13.0","_npmVersion":"11.18.0","dist":{"integrity":"sha512-7PkYAJ/q0l+zYHyN7cd/LpqrnkEklnEOxTOokUEey2JY0Wl802hAdHGu1cP8svxosbQf5d24ExW1FuzN5KX9hg==","shasum":"4c9acd24af13f5f776885e60b95b05ef87f521f8","tarball":"https://registry.npmjs.org/@ai-sdk-byok/cloudflare/-/cloudflare-0.2.0.tgz","fileCount":7,"unpackedSize":38165,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEwtUhWm/XW5hLrLDECw6cIx+PcaGdFzJF7puNDjkRQgAiA27YJdMZOlDPCI3FTQRecHZ9QoCL9oB2u2PM6BWgczJA=="}]},"_npmUser":{"name":"xyril","email":"tsuixyril@gmail.com"},"directories":{},"maintainers":[{"name":"xyril","email":"tsuixyril@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/cloudflare_0.2.0_1784370790765_0.5049911127945861"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-18T10:33:10.578Z","0.2.0":"2026-07-18T10:33:10.901Z","modified":"2026-07-18T10:33:11.155Z"},"maintainers":[{"name":"xyril","email":"tsuixyril@gmail.com"}],"description":"Cloudflare D1 storage adapter and Workers KV credential cache for ai-sdk-byok.","homepage":"https://github.com/Xyri1/ai-sdk-byok#readme","repository":{"type":"git","url":"git+https://github.com/Xyri1/ai-sdk-byok.git","directory":"packages/cloudflare"},"bugs":{"url":"https://github.com/Xyri1/ai-sdk-byok/issues"},"license":"MIT","readme":"# @ai-sdk-byok/cloudflare\n\nCloudflare D1 storage adapter and Workers KV credential cache for [`ai-sdk-byok`](https://github.com/Xyri1/ai-sdk-byok). Credentials are always sealed with AES-256-GCM before touching D1 or KV; the master key lives in a Worker secret or Secrets Store binding.\n\n## Setup\n\n1. Generate a 32-byte master key and store it as a Worker secret:\n\n   ```sh\n   openssl rand -base64 32 | wrangler secret put BYOK_MASTER_KEY\n   ```\n\n2. Create a D1 database and KV namespace, bind them in `wrangler.jsonc` (for example as `DB` and `BYOK_CACHE`), and apply the shipped migration:\n\n   ```sh\n   wrangler d1 migrations apply <DATABASE_NAME> --remote\n   ```\n\n   The migration file is `node_modules/@ai-sdk-byok/cloudflare/migrations/0001_ai_sdk_byok_init.sql`; copy it into your project's `migrations/` directory.\n\n## Usage (inside a Worker)\n\n```ts\nimport { createByokManager, cachedStorage } from 'ai-sdk-byok';\nimport { d1Adapter, kvCredentialCache } from '@ai-sdk-byok/cloudflare';\n\nexport default {\n  async fetch(request: Request, env: Env): Promise<Response> {\n    const manager = createByokManager({\n      storage: cachedStorage({\n        storage: d1Adapter({ database: env.DB, encryptionKey: env.BYOK_MASTER_KEY }),\n        cache: kvCredentialCache({ namespace: env.BYOK_CACHE, encryptionKey: env.BYOK_MASTER_KEY }),\n        ttlMs: 60_000,\n      }),\n    });\n\n    // save / list / get / getById / delete — see the ai-sdk-byok README.\n    // Retrieve plaintext credentials as late as possible, server-side only.\n    return new Response('ok');\n  },\n};\n```\n\nUsing Secrets Store instead of a Worker secret? Pass a getter: `encryptionKey: () => env.BYOK_KEY_STORE.get()`.\n\n## Security model\n\n- D1 rows and KV values hold only AES-256-GCM ciphertext; a dump of both without the master key exposes nothing.\n- Ciphertext is AAD-bound to its slot (`userId`/`provider`/`label` in D1, `userId`/`keyId` in KV) — sealed blobs copied between rows fail decryption.\n- Losing the master key means stored credentials are unrecoverable; users re-enter their API keys.\n- KV is eventually consistent: a rotated or deleted key may be served from another region until propagation (~60 s) plus remaining TTL. Keep `ttlMs` short.\n- Cache invalidation is best-effort: if KV is unavailable, `save` and `delete` still succeed against D1, and any stale cache entry expires by its TTL.\n- See `docs/threat-model.md` in the repository for the full model.\n\n## Capacity\n\nD1 caps a database at 10 GB — roughly 8M stored keys at typical API-key sizes. The schema is shard-friendly (all queries are keyed by `user_id`); shard across multiple D1 databases above that scale.\n","readmeFilename":"README.md","_rev":"1-dd62f5dd23c02209954059dba65280cc"}