{"_id":"@absolutejs/secure-messaging-redis","_rev":"5-8a2e0a20f7c004fa491ff5be3677f63b","name":"@absolutejs/secure-messaging-redis","dist-tags":{"latest":"0.4.0"},"versions":{"0.0.1":{"name":"@absolutejs/secure-messaging-redis","version":"0.0.1","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/secure-messaging-redis@0.0.1","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/secure-messaging-adapters#readme","bugs":{"url":"https://github.com/absolutejs/secure-messaging-adapters/issues"},"dist":{"shasum":"78f3286c85a86a90531e84afa057bdf77478661d","tarball":"https://registry.npmjs.org/@absolutejs/secure-messaging-redis/-/secure-messaging-redis-0.0.1.tgz","fileCount":7,"integrity":"sha512-tNr0wgXnd5KlS9dPI00Q/17juMhVlzBOEAhIhanSrAyhzcMUT2pYSxES/jffAP5XeOWwvXHyQ+R4SxQqdWzfGA==","signatures":[{"sig":"MEQCIHMbOSTLDaCvLu57ck7RScWoT2cbtk5HufFDS5oVvTNgAiAs0u6MGzKdhlDArONCfiQesuxVxPHmuFf/eFNcz6gO+Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54777},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"cac2a620a8539a395976e452b5eed74ab34b65bf","scripts":{"test":"bun test tests/","build":"rm -rf dist && bun build src/index.ts --outdir dist --root src --sourcemap --target=browser --external @absolutejs/secure-messaging && tsc --project tsconfig.build.json","release":"bun run check:package && npm publish --access public","typecheck":"tsc --noEmit","format:check":"prettier --check \"./**/*.{ts,json,md}\"","check:package":"bun run format:check && bun run typecheck && bun run test && bun run build","test:integration":"bun test tests/redis.test.ts"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/secure-messaging-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.9.2","description":"Tenant-scoped atomic Redis SecureMessagingStore for explicitly durable Redis deployments.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ioredis":"6.0.0","@absolutejs/secure-messaging":"0.5.1","@absolutejs/secure-messaging-store-conformance":"0.0.1"},"peerDependencies":{"@absolutejs/secure-messaging":">=0.5.1 <0.6"},"_npmOperationalInternal":{"tmp":"tmp/secure-messaging-redis_0.0.1_1787874291467_0.18526002164448774","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@absolutejs/secure-messaging-redis","version":"0.1.0","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/secure-messaging-redis@0.1.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/secure-messaging-adapters#readme","bugs":{"url":"https://github.com/absolutejs/secure-messaging-adapters/issues"},"dist":{"shasum":"52f7f0520fefb27501bcd95e228994a93b990002","tarball":"https://registry.npmjs.org/@absolutejs/secure-messaging-redis/-/secure-messaging-redis-0.1.0.tgz","fileCount":7,"integrity":"sha512-xqZuG/5t/Xh4MLmPywBU7jUGqBPzeBsEt4Ylv39a3JvUDlIfy/V0PXT/dX5+5bofLyXswnusdwSBPzB4Qj4eYA==","signatures":[{"sig":"MEUCIQC4Fw9+LZCn+zMTZBRSp98jQaLFy/e4rj59x8oFtQV8vwIgf/kNb1OTwKDwe8MDlpGuWEy+dglUmWqO/di1otdyuxM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQD7ZVjWt8WyxoWX9Je8Sm+nSADFZ9ntGQOpavBKlrHQYAIhAKTfw78vdZPqz6VhVPcF9PhK3j2klaWtcXuwryuqxiKY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":55224},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"7c4d4a466cbc6dcd1fbb65cf2eb0c30378865ab7","scripts":{"test":"bun test tests/","build":"rm -rf dist && bun build src/index.ts --outdir dist --root src --sourcemap --target=browser --external @absolutejs/secure-messaging && tsc --project tsconfig.build.json","release":"bun run check:package && npm publish --access public","typecheck":"tsc --noEmit","format:check":"prettier --check \"./**/*.{ts,json,md}\"","check:package":"bun run format:check && bun run typecheck && bun run test && bun run build","test:integration":"bun test tests/redis.test.ts"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/secure-messaging-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.9.2","description":"Tenant-scoped atomic Redis SecureMessagingStore for explicitly durable Redis deployments.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ioredis":"6.0.0","@absolutejs/secure-messaging":"0.5.1","@absolutejs/secure-messaging-store-conformance":"0.0.1"},"peerDependencies":{"@absolutejs/secure-messaging":">=0.5.1 <0.6"},"_npmOperationalInternal":{"tmp":"tmp/secure-messaging-redis_0.1.0_1787874512688_0.29804304062704756","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@absolutejs/secure-messaging-redis","version":"0.2.0","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/secure-messaging-redis@0.2.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/secure-messaging-adapters#readme","bugs":{"url":"https://github.com/absolutejs/secure-messaging-adapters/issues"},"dist":{"shasum":"9b819cc9a76722ed2f8568eb1d822bef8030bdbc","tarball":"https://registry.npmjs.org/@absolutejs/secure-messaging-redis/-/secure-messaging-redis-0.2.0.tgz","fileCount":7,"integrity":"sha512-8zwDxJCnGkdOsaK9AwcTib9WgLqK8Wg39bN0LWa/faCZrNxGxipwesmWNPBQJZ+A9qdD7rUd7vs3m06U2l33iA==","signatures":[{"sig":"MEYCIQDtMQyyYaTBeSXUWWOxSSLiYp/hstj5bPfkP+CEsVRXqgIhAIFu2f5osyeR6r8N5F83y8QpIDfLAjgYWDWjMf5LMGJp","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIERVUHjptc3lgVrEl3mgrxb0C1adhs0v6ukw91aAvwBgAiEA/QGVs5ELLmfnmF8IEHS7UHvACflKZJyaZyKExN/AGjI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":65469},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"a5e3ea32991615e717652e6ae73dd93086131466","scripts":{"test":"bun test tests/","build":"rm -rf dist && bun build src/index.ts --outdir dist --root src --sourcemap --target=browser --external @absolutejs/secure-messaging && tsc --project tsconfig.build.json","release":"bun run check:package && npm publish --access public","typecheck":"tsc --noEmit","format:check":"prettier --check \"./**/*.{ts,json,md}\"","check:package":"bun run format:check && bun run typecheck && bun run test && bun run build","test:integration":"bun test tests/redis.test.ts"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/secure-messaging-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.9.2","description":"Tenant-scoped atomic Redis SecureMessagingStore for explicitly durable Redis deployments.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ioredis":"6.0.0","@absolutejs/secure-messaging":"0.5.1","@absolutejs/secure-messaging-store-conformance":"0.1.0"},"peerDependencies":{"@absolutejs/secure-messaging":">=0.5.1 <0.6"},"_npmOperationalInternal":{"tmp":"tmp/secure-messaging-redis_0.2.0_1787875918339_0.3892079389146468","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@absolutejs/secure-messaging-redis","version":"0.3.0","author":{"name":"Alex Kahn"},"license":"Apache-2.0","_id":"@absolutejs/secure-messaging-redis@0.3.0","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"homepage":"https://github.com/absolutejs/secure-messaging-adapters#readme","bugs":{"url":"https://github.com/absolutejs/secure-messaging-adapters/issues"},"dist":{"shasum":"083870ecc99db9cce32b19f47a597bd276193e45","tarball":"https://registry.npmjs.org/@absolutejs/secure-messaging-redis/-/secure-messaging-redis-0.3.0.tgz","fileCount":7,"integrity":"sha512-dMG0WWVNG2+/NsEXL/hqVq1cip+GI8a8n0PYntK6JtfE3+m4Krys7E8RsZ2/CYdrTeJpJbWFA88r+LlzFRysRg==","signatures":[{"sig":"MEUCIDgu0UdIe8A4WZqj1rgsRSL5C0kkVPVkd6IJELntWw1KAiEAoNU2EH378YX0FZFooRJoa7sPGX9uxTrz4zvRSJElitc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGzqQQK5j/vkpE5YO/d1Z41c5ypRmV+5goUJt8o7z/NZAiBTvWw/qH/kbT2L1Yrczv7yzV8P4tNjOUntF42GvWtnbw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":68984},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"9c94ad2e5e2a7ed1d7ad259b82c6094265f423e5","scripts":{"test":"bun test tests/","build":"rm -rf dist && bun build src/index.ts --outdir dist --root src --sourcemap --target=browser --external @absolutejs/secure-messaging && tsc --project tsconfig.build.json","release":"bun run check:package && npm publish --access public","typecheck":"tsc --noEmit","format:check":"prettier --check \"./**/*.{ts,json,md}\"","check:package":"bun run format:check && bun run typecheck && bun run test && bun run build","test:integration":"bun test tests/redis.test.ts"},"_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"repository":{"url":"git+https://github.com/absolutejs/secure-messaging-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.9.2","description":"Tenant-scoped atomic Redis SecureMessagingStore for explicitly durable Redis deployments.","directories":{},"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ioredis":"6.0.0","@absolutejs/secure-messaging":"0.6.1","@absolutejs/secure-messaging-store-conformance":"0.2.0"},"peerDependencies":{"@absolutejs/secure-messaging":">=0.6.1 <0.7"},"_npmOperationalInternal":{"tmp":"tmp/secure-messaging-redis_0.3.0_1787884416087_0.48381507025570536","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"_id":"@absolutejs/secure-messaging-redis@0.4.0","bugs":{"url":"https://github.com/absolutejs/secure-messaging-adapters/issues"},"dist":{"shasum":"bba9527fa4c22117a27c8de2e1bbdbd48261a852","tarball":"https://registry.npmjs.org/@absolutejs/secure-messaging-redis/-/secure-messaging-redis-0.4.0.tgz","fileCount":7,"integrity":"sha512-InvTnFNQd1STzScvw410Nz3CR9F+hDY2ewEJrGbyiakyzHUqtCFYvPDX7f5r76zUGjsVR6kDo31y46das2jNDg==","signatures":[{"sig":"MEUCIHXdVZph3X9LuguEQ3P8ycqQgslix7V4BEYxR16Qx+BcAiEA9xRRodmjVhcHzdMGjtFiJ4z9QfHwDpBwVvamL/2hcHc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDCaD5okVET72SkNPRlJ/TC1kKpZ/PbSaGLUP0JPHsliwIgQ8B2BdzpKwHFapGuqblKUbWxJdRoAtl2SnPj71I5CKs="}],"unpackedSize":72895},"main":"./dist/index.js","name":"@absolutejs/secure-messaging-redis","type":"module","types":"./dist/index.d.ts","author":{"name":"Alex Kahn"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"}},"gitHead":"7eb7599515114086143c7471a20f870f4125b215","license":"Apache-2.0","scripts":{"test":"bun test tests/","build":"rm -rf dist && bun build src/index.ts --outdir dist --root src --sourcemap --target=browser --external @absolutejs/secure-messaging && tsc --project tsconfig.build.json","release":"bun run check:package && npm publish --access public","typecheck":"tsc --noEmit","format:check":"prettier --check \"./**/*.{ts,json,md}\"","check:package":"bun run format:check && bun run typecheck && bun run test && bun run build","test:integration":"bun test tests/redis.test.ts"},"version":"0.4.0","_npmUser":{"name":"alexkahndev","email":"alexkahn2019@gmail.com"},"homepage":"https://github.com/absolutejs/secure-messaging-adapters#readme","repository":{"url":"git+https://github.com/absolutejs/secure-messaging-adapters.git","type":"git","directory":"redis"},"_npmVersion":"10.9.2","description":"Tenant-scoped atomic Redis SecureMessagingStore for explicitly durable Redis deployments.","directories":{},"maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"_nodeVersion":"22.14.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"ioredis":"6.0.0","@absolutejs/secure-messaging":"0.6.1","@absolutejs/secure-messaging-store-conformance":"0.2.0"},"peerDependencies":{"@absolutejs/secure-messaging":">=0.6.1 <0.7"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/secure-messaging-redis_0.4.0_1787885745975_0.38936228230413006"}}},"time":{"created":"2026-08-27T23:44:51.269Z","modified":"2026-08-28T02:55:46.262Z","0.0.1":"2026-08-27T23:44:51.631Z","0.1.0":"2026-08-27T23:48:32.783Z","0.2.0":"2026-08-28T00:11:58.424Z","0.3.0":"2026-08-28T02:33:36.176Z","0.4.0":"2026-08-28T02:55:46.069Z"},"bugs":{"url":"https://github.com/absolutejs/secure-messaging-adapters/issues"},"author":{"name":"Alex Kahn"},"license":"Apache-2.0","homepage":"https://github.com/absolutejs/secure-messaging-adapters#readme","repository":{"url":"git+https://github.com/absolutejs/secure-messaging-adapters.git","type":"git","directory":"redis"},"description":"Tenant-scoped atomic Redis SecureMessagingStore for explicitly durable Redis deployments.","maintainers":[{"name":"alexkahndev","email":"alexkahn2019@gmail.com"}],"readme":"# `@absolutejs/secure-messaging-redis`\n\nAn atomic Redis `SecureMessagingStore` for operators deliberately using Redis as\ndurable primary storage. Lua scripts commit sealed MLS state, replay receipts,\nand encrypted outbox entries as one transition. Every tenant uses a Redis Cluster\nhash tag so all transaction keys occupy one slot.\n\n```ts\nconst redis = createClient({ url: process.env.REDIS_URL });\nawait redis.connect();\n\nconst store = createRedisSecureMessagingStore({\n  client: createNodeRedisSecureMessagingClient(redis),\n  deviceId: authenticatedDevice.id,\n  durability: {\n    mode: \"aof\",\n    replicaFsyncs: 1,\n    timeoutMilliseconds: 5_000,\n  },\n  tenantId: authenticatedTenant.id,\n});\n```\n\nAn ioredis wrapper is also exported. Configure AOF and RDB persistence,\nreplication, backups, and `maxmemory-policy noeviction`. A cache or evicting Redis\ndeployment is unsafe for MLS state. PostgreSQL is the default recommendation.\n\nDurability is mandatory and explicit. `aof` uses Redis 7.2+ `WAITAOF` after\neach successful mutation and fails closed unless the local AOF plus the requested\nreplica AOF count acknowledge it. `replicated` uses `WAIT`, which reduces but\ndoes not eliminate failover data loss. `memory` performs no acknowledgement and\nmust be limited to tests or deliberately lossy development environments. A\ndurability timeout is an ambiguous commit: reload state before retrying.\nThe adapter reports this boundary as\n`SecureMessagingDurabilityUncertainError`. Resolve the authoritative primary and\ncall `resolveSecureMessagingStoreCommit()` with the intended conversation and\nexpected revision; retry only when it returns `retry`. `applied` means the exact\nconversation and its atomic replay/outbox effects already committed, while\n`conflict` must never be overwritten.\n\nSentinel operators should also configure `min-replicas-to-write` and\n`min-replicas-max-lag` so an isolated former primary stops accepting mutations.\nThat admission gate reduces the unsafe partition window but does not replace\n`WAIT`/`WAITAOF`, authoritative-primary resolution, or uncertainty handling.\n\nCreate application users from the exported least-privilege contract instead of\ngranting command categories or using the legacy default user:\n\n```ts\nconst permissions = createSecureMessagingRedisAclRules();\nawait admin.call(\n  \"ACL\",\n  \"SETUSER\",\n  username,\n  \"reset\",\n  \"on\",\n  `>${generatedPassword}`,\n  ...permissions,\n);\n```\n\nThe default profile grants no Pub/Sub channels, scopes keys to\n`absolute:secure-messaging:*`, denies every command category, and restores only\nthe connection, read, Lua-internal mutation, and durability commands used by\nthis adapter. Custom prefixes must contain only ASCII letters, digits, colon,\nunderscore, and hyphen so ACL glob metacharacters cannot widen key access.\n\nThe built-in node-redis and ioredis wrappers are for a direct standalone or\nSentinel-managed primary connection. Although the hash tag keeps Lua keys in one\nRedis Cluster slot, a keyless `WAIT` or `WAITAOF` sent through a generic Cluster\nrouter is not proven to use that same primary connection. Cluster operators must\nprovide a custom `SecureMessagingRedisClient` that pins `eval` and durability\nacknowledgement to the same shard connection; this is an independent-review\ntarget, not an inferred guarantee.\n\nInbound replay receipts use absolute expiry. Tenant and device IDs jointly bind\nthe Redis Cluster namespace because each device has distinct MLS state.\nConversation state and outbox entries do not expire and must never be evicted.\nRun the shared conformance suite after failover and restore drills.\n\nLicensed under Apache-2.0.\n","readmeFilename":"README.md"}