AbsoluteJS

@absolutejs/secure-messaging-redis

@absolutejs/secure-messaging-redisv0.4.0betaMessaging

Tenant-scoped atomic Redis SecureMessagingStore for explicitly durable Redis deployments.

#Installation

BASH
bun add @absolutejs/secure-messaging-redis

#Capabilities

Overview

An atomic Redis SecureMessagingStore for operators deliberately using Redis as durable primary storage. Lua scripts commit sealed MLS state, replay receipts, and encrypted outbox entries as one transition. Every tenant uses a Redis Cluster hash tag so all transaction keys occupy one slot.

An ioredis wrapper is also exported. Configure AOF and RDB persistence, replication, backups, and maxmemory-policy noeviction. A cache or evicting Redis deployment is unsafe for MLS state. PostgreSQL is the default recommendation.

Durability is mandatory and explicit. aof uses Redis 7.2+ WAITAOF after each successful mutation and fails closed unless the local AOF plus the requested replica AOF count acknowledge it. replicated uses WAIT, which reduces but does not eliminate failover data loss. memory performs no acknowledgement and must be limited to tests or deliberately lossy development environments. A durability timeout is an ambiguous commit: reload state before retrying. The adapter reports this boundary as SecureMessagingDurabilityUncertainError. Resolve the authoritative primary and call resolveSecureMessagingStoreCommit() with the intended conversation and expected revision; retry only when it returns retry. applied means the exact conversation and its atomic replay/outbox effects already committed, while conflict must never be overwritten.

Show 6 more

Sentinel operators should also configure min-replicas-to-write and min-replicas-max-lag so an isolated former primary stops accepting mutations. That admission gate reduces the unsafe partition window but does not replace WAIT/WAITAOF, authoritative-primary resolution, or uncertainty handling.

Create application users from the exported least-privilege contract instead of granting command categories or using the legacy default user:

The default profile grants no Pub/Sub channels, scopes keys to absolute:secure-messaging:, denies every command category, and restores only the connection, read, Lua-internal mutation, and durability commands used by this adapter. Custom prefixes must contain only ASCII letters, digits, colon, underscore, and hyphen so ACL glob metacharacters cannot widen key access.

The built-in node-redis and ioredis wrappers are for a direct standalone or Sentinel-managed primary connection. Although the hash tag keeps Lua keys in one Redis Cluster slot, a keyless WAIT or WAITAOF sent through a generic Cluster router is not proven to use that same primary connection. Cluster operators must provide a custom SecureMessagingRedisClient that pins eval and durability acknowledgement to the same shard connection; this is an independent-review target, not an inferred guarantee.

Inbound replay receipts use absolute expiry. Tenant and device IDs jointly bind the Redis Cluster namespace because each device has distinct MLS state. Conversation state and outbox entries do not expire and must never be evicted. Run the shared conformance suite after failover and restore drills.

Licensed under Apache-2.0.

Outcomes

What you can build

Build on the supported package contract

Use @absolutejs/secure-messaging-redis through its supported public entry points.

Hardening checklist

Production guidance

Make every external boundary explicitPin the deployed @absolutejs/secure-messaging-redis version, replace example or memory-backed dependencies with durable implementations, bound external calls, protect credentials, and emit enough evidence to retry or recover safely.

Follow in order

Troubleshooting path

1
Trace from the first failed boundary
Reproduce the smallest canonical @absolutejs/secure-messaging-redis example, confirm the supported entry point and version in the API explorer, then inspect the first boundary that did not produce its documented result.

#@absolutejs/secure-messaging-redis quick start

Partial snippet

# @absolutejs/secure-messaging-redis

TS
const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();

const store = createRedisSecureMessagingStore({
  client: createNodeRedisSecureMessagingClient(redis),
  deviceId: authenticatedDevice.id,
  durability: {
    mode: "aof",
    replicaFsyncs: 1,
    timeoutMilliseconds: 5_000,
  },
  tenantId: authenticatedTenant.id,
});

#@absolutejs/secure-messaging-redis quick start 2

Partial snippet

# @absolutejs/secure-messaging-redis

TS
const permissions = createSecureMessagingRedisAclRules();
await admin.call(
  "ACL",
  "SETUSER",
  username,
  "reset",
  "on",
  `>${generatedPassword}`,
  ...permissions,
);

#Public entry points

Supported entry points declared by this package manifest.

@absolutejs/secure-messaging-redisPackage entry point declared in package.json.

#Package commands

Scripts declared by this package manifest.

bun run buildrm -rf dist && bun build src/index.ts --outdir dist --root src --sourcemap --target=browser --external @absolutejs/secure-messaging && tsc --project tsconfig.build.json
bun run check:packagebun run format:check && bun run typecheck && bun run test && bun run build
bun run format:checkprettier --check "./**/*.{ts,json,md}"
bun run testbun test tests/
bun run test:integrationbun test tests/redis.test.ts
bun run typechecktsc --noEmit

#API reference

Search the declarations exported by the current package type files. Expand a symbol to inspect its source-backed signature.

14 symbols
SECURE_MESSAGING_REDIS_DEFAULT_KEY_PREFIXvaluePermalinkSource
TS
const SECURE_MESSAGING_REDIS_DEFAULT_KEY_PREFIX: "absolute:secure-messaging:";
Exported from @absolutejs/secure-messaging-redis