Launch Week Day 1: Socket for Jira Is Now Available.Learn More
Socket
Book a DemoSign in
Socket

secure-store-redis

Package Overview
Dependencies
Maintainers
1
Versions
40
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

secure-store-redis

A simple wrapper to encrypt and decrypt data stored in Redis

latest
Source
npmnpm
Version
4.1.3
Version published
Weekly downloads
104
-65.45%
Maintainers
1
Weekly downloads
 
Created
Source

secure-store-redis

npm version license build

Encrypt and store data in Redis. Uses AES-256-GCM encryption with unique IVs per entry.

Installation

npm install secure-store-redis

Quick Start

import SecureStore, { SecretValidator } from "secure-store-redis";

const store = new SecureStore({
    uid: "myApp",
    secret: SecretValidator.generate(),
    redis: { url: "redis://localhost:6379" },
});

await store.connect();
await store.save("key", { foo: "bar" });
const data = await store.get("key");
await store.disconnect();

API

Constructor

new SecureStore(config: SecureStoreConfig)
OptionTypeRequiredDescription
uidstringYesUnique prefix for Redis keys (e.g., "myApp", "myApp:sessions")
secretstringYes32-character encryption secret. Use SecretValidator.generate().
redisRedisOptions | { url: string } | { client: Redis | Cluster }YesRedis connection config or existing client
allowWeakSecretsbooleanNoBypass secret strength validation (default: false)

Using an Existing Redis Client

You can pass your own ioredis Redis or Cluster client instead of connection options. This enables connection sharing, pre-configured clients, and integration with existing Redis infrastructure.

import { Redis } from "ioredis";
import SecureStore, { SecretValidator } from "secure-store-redis";

const redis = new Redis({ host: "localhost", port: 6379 });

const store = new SecureStore({
    uid: "myApp",
    secret: SecretValidator.generate(),
    redis: { client: redis },
});

await store.connect();
await store.save("key", "value");
await store.disconnect();

// Your client is still connected - you manage its lifecycle
console.log(redis.status); // "ready"
await redis.quit();

Redis Cluster

import { Cluster } from "ioredis";
import SecureStore, { SecretValidator } from "secure-store-redis";

const cluster = new Cluster([
    { host: "node1", port: 6379 },
    { host: "node2", port: 6379 },
]);

const store = new SecureStore({
    uid: "myApp",
    secret: SecretValidator.generate(),
    redis: { client: cluster },
});

await store.connect();

Sharing Connections

Multiple SecureStore instances can share a single Redis connection:

const redis = new Redis();

const sessionsStore = new SecureStore({
    uid: "sessions",
    secret: sessionSecret,
    redis: { client: redis },
});

const cacheStore = new SecureStore({
    uid: "cache",
    secret: cacheSecret,
    redis: { client: redis },
});

await sessionsStore.connect();
await cacheStore.connect();

// Both stores use the same connection
// Disconnecting either store does NOT close the Redis client

Important notes:

  • When using an external client, disconnect() will NOT close the Redis connection - you are responsible for calling redis.quit() when done
  • The client can be in any connectable state (ready, connecting, or lazyConnect); connect() will wait for it to be ready
  • If the client is already closed, connect() will throw a ConnectionError

Methods

connect(): Promise<void>

Connect to Redis. Must be called before other operations.

save<T>(key: string, data: T, postfix?: string): Promise<void>

Encrypt and store data.

get<T>(key: string, postfix?: string): Promise<T | null>

Retrieve and decrypt data. Returns null if not found or decryption fails.

delete(key: string, postfix?: string): Promise<number>

Delete data. Returns count of deleted keys.

disconnect(client?: Redis): Promise<void>

Close Redis connection. Optionally pass a specific Redis client to disconnect.

namespace<TSchema>(name: string): TypedNamespace<TSchema>

Create a typed namespace for organizing data. See Namespaces for details.

Properties

  • client: RedisClient | undefined - The underlying ioredis client (Redis or Cluster)
  • isConnected: boolean - Connection status

Namespaces

Namespaces allow you to organize data with type-safe operations. Each namespace acts as an isolated partition within the same store.

const store = new SecureStore({
    uid: "myApp",
    secret: SecretValidator.generate(),
    redis: { url: "redis://localhost:6379" },
});
await store.connect();

// Create a typed namespace
interface UserSchema {
    profile: { name: string; age: number };
    settings: { theme: string; notifications: boolean };
}

const users = store.namespace<UserSchema>("users");

// Type-safe operations
await users.save("profile", { name: "John", age: 30 });
await users.save("settings", { theme: "dark", notifications: true });

const profile = await users.get("profile"); // { name: string; age: number } | null
const settings = await users.get("settings");

await users.delete("profile");

Namespace Methods

Each namespace provides the same core operations as the store:

  • get<K>(key: K): Promise<T[K] | null>
  • save<K>(key: K, data: T[K]): Promise<void>
  • delete<K>(key: K): Promise<number>

Namespace Isolation

Data in different namespaces is completely isolated:

const users = store.namespace("users");
const sessions = store.namespace("sessions");

await users.save("data", "user-data");
await sessions.save("data", "session-data");

await users.get("data");    // "user-data"
await sessions.get("data"); // "session-data"
await store.get("data");    // null (root store is separate)

SecretValidator

Utility class for generating and validating encryption secrets.

Methods

generate(length?: number): string

Generate a cryptographically secure secret. Defaults to 32 characters if no length specified.

validate(secret: string): { valid: boolean; reason?: string }

Validate secret strength against security requirements.

Validation Rules

Secrets must:

  • Be exactly 32 characters
  • Have sufficient entropy (Shannon entropy ≥ 4.0)
  • Not contain weak patterns (repeated chars, sequential numbers, etc.)
  • Contain at least 3 of: uppercase, lowercase, numbers, special characters

Error Handling

All errors extend SecureStoreError and include a code property for programmatic handling.

import {
    SecureStoreError,
    ConnectionError,
    EncryptionError,
    ValidationError,
} from "secure-store-redis";

try {
    await store.connect();
} catch (err) {
    if (err instanceof ConnectionError) {
        console.error(`Connection failed (${err.code}):`, err.message);
        // err.code === "CONNECTION_ERROR"
    }
}
Error ClassCodeWhen Thrown
ConnectionErrorCONNECTION_ERRORRedis connection failures
EncryptionErrorENCRYPTION_ERROREncryption/decryption failures
ValidationErrorVALIDATION_ERRORInvalid configuration, keys, or data

Security Best Practices

  • Store secrets in environment variables, not code
  • Use SecretValidator.generate() for cryptographically secure secrets
  • Enable Redis authentication and TLS in production
  • Use unique uid values per application/environment to prevent data collisions
  • Rotate secrets periodically (requires re-encryption of existing data)

Migration from v3.x

Breaking Changes

ChangeMigration
uid requiredAdd explicit uid to constructor
secret requiredUse SecretValidator.generate() or provide your own
connect() requiredCall await store.connect() before use
AES-256-GCMRe-encrypt existing data (format changed)
Secret validationUse strong secrets or set allowWeakSecrets: true

Example

// v3.x
const store = new SecureStore({ redis: { url: "..." } });
await store.init();

// v4.0
const store = new SecureStore({
    uid: "myApp",
    secret: SecretValidator.generate(),
    redis: { url: "..." },
});
await store.connect();

TypeScript

Full TypeScript support with exported types:

import SecureStore, {
    SecureStoreConfig,
    TypedNamespace,
    RedisClient,
    SecretValidator,
    SecureStoreError,
    ConnectionError,
    EncryptionError,
    ValidationError,
} from "secure-store-redis";

License

MIT

Keywords

redis

FAQs

Package last updated on 07 Apr 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts