Skip to content

feat(storage): redis interface addition#167

Closed
su-shivanshmathur wants to merge 10 commits into
mainfrom
redis-interface-addtion-to-vault
Closed

feat(storage): redis interface addition#167
su-shivanshmathur wants to merge 10 commits into
mainfrom
redis-interface-addtion-to-vault

Conversation

@su-shivanshmathur

Copy link
Copy Markdown

Description

This PR adds a Redis client to the locker, built on the redis_interface crate from https://github.com/juspay/hyperswitch (fred backend). It is gated behind a new redis Cargo feature, so it is off by default and compiles out completely when the feature is not enabled.

This PR includes the following changes:

  • Adds an optional redis feature (also part of the release feature set); hyperswitch_redis_interface is now an optional dependency.
  • Builds a single shared connection pool once at startup and stores it on the global app state.
  • Gives each tenant a handle that prefixes its keys with the tenant id, so keys do not collide across tenants and no extra pool is opened per tenant.
  • Exposes the pool to handlers through an availability-gated accessor (get_redis_conn) that does not hand back the pool when Redis is known to be down.
  • Reports Redis in /health/diagnostics (Working / Failing / Disabled) via a set/get/delete round-trip.
  • Keeps Redis optional at runtime: if there is no [redis] config, or the server cannot reach Redis at startup, the locker logs it and keeps running.
  • Adds a [redis] block to development.toml, docker-configuration.toml, and config.example.toml (the example file documents each field inline).

Testing

  1. Log of RedisSetting in GlobalConfig
[INFO] log_utils: Using console filtering directive: WARN,hyperswitch_masking=DEBUG,tower_http=DEBUG,build_info=DEBUG,locker=DEBUG,tartarus=DEBUG,log_utils=DEBUG
  2026-06-15T05:22:06.193816Z  INFO tartarus::app: Locker started [Server { host: "127.0.0.1", port: 3001 }] [Log { console: LogConsole { enabled: true, level: Level(Level(Debug)), log_format: Default, filtering_directive: None } }]
    at src/app.rs:219

  2026-06-15T05:22:06.193864Z DEBUG tartarus::app: startup_config: GlobalConfig { server: Server { host: "127.0.0.1", port: 3001 }, database: Database { username: "db_user", password: *** alloc::string::String ***, host: "localhost", port: 5432, dbname: "locker", pool_size: None }, secrets: Secrets, secrets_management: NoEncryption, log: Log { console: LogConsole { enabled: true, level: Level(Level(Debug)), log_format: Default, filtering_directive: None } }, cache: Cache { tti: Some(7200), max_capacity: 5000 }, tenant_secrets: TenantsSecrets({"public": TenantSecrets { master_key: [254, 255, 233, 146, 134, 101, 115, 28, 109, 106, 143, 148, 103, 48, 131, 8, 254, 255, 233, 146, 134, 101, 115, 28, 109, 106, 143, 148, 103, 48, 131, 8], schema: "public" }}), tls: None, api_client: ApiClientConfig { client_idle_timeout: 90, pool_max_idle_per_host: 5 }, external_key_manager: Disabled, redis: Some(RedisSettings { host: "127.0.0.1", port: 6379, cluster_enabled: false, cluster_urls: [], use_legacy_version: false, pool_size: 5, reconnect_max_attempts: 5, reconnect_delay: 5, default_ttl: 300, default_hash_ttl: 900, stream_read_count: 1, auto_pipeline: true, disable_auto_backpressure: false, max_in_flight_commands: 5000, default_command_timeout: 30, max_feed_count: 200, unresponsive_timeout: 10, unresponsive_check_interval: 2, broadcast_channel_capacity: 32, max_failure_threshold_seconds: 5 }) }
  1. Reconnection with Redis
Request
curl --location 'http://localhost:3001/health/diagnostics' \
--header 'x-tenant-id: public'
Response
{
    "key_custodian_locked": false,
    "database": {
        "database_connection": "Failing",
        "database_read": "Failing",
        "database_write": "Failing",
        "database_delete": "Failing"
    },
    "redis_status": "Working"
}
Logs
  2026-06-15T05:45:38.602663Z DEBUG tartarus::app: startup_config: GlobalConfig { server: Server { host: "127.0.0.1", port: 3001 }, database: Database { username: "db_user", password: *** alloc::string::String ***, host: "localhost", port: 5432, dbname: "locker", pool_size: None }, secrets: Secrets, secrets_management: NoEncryption, log: Log { console: LogConsole { enabled: true, level: Level(Level(Debug)), log_format: Default, filtering_directive: None } }, cache: Cache { tti: Some(7200), max_capacity: 5000 }, tenant_secrets: TenantsSecrets({"public": TenantSecrets { master_key: [254, 255, 233, 146, 134, 101, 115, 28, 109, 106, 143, 148, 103, 48, 131, 8, 254, 255, 233, 146, 134, 101, 115, 28, 109, 106, 143, 148, 103, 48, 131, 8], schema: "public" }}), tls: None, api_client: ApiClientConfig { client_idle_timeout: 90, pool_max_idle_per_host: 5 }, external_key_manager: Disabled, redis: Some(RedisSettings { host: "127.0.0.1", port: 6379, cluster_enabled: false, cluster_urls: [], use_legacy_version: false, pool_size: 5, reconnect_max_attempts: 0, reconnect_delay: 200, default_ttl: 300, default_hash_ttl: 900, stream_read_count: 1, auto_pipeline: true, disable_auto_backpressure: false, max_in_flight_commands: 5000, default_command_timeout: 30, max_feed_count: 200, unresponsive_timeout: 10, unresponsive_check_interval: 2, broadcast_channel_capacity: 32, max_failure_threshold_seconds: 5 }) }
    at src/app.rs:225

  2026-06-15T05:45:43.439948Z  WARN fred::router::responses: fred-WQNTeoiVmR: Ending reader task from 127.0.0.1:6379 due to None
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fred-8.0.6/src/router/responses.rs:350

  2026-06-15T05:45:43.440260Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: Canceled, details: Canceled.
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.440343Z  WARN fred::router::responses: fred-pCs6Vbkqc3: Ending reader task from 127.0.0.1:6379 due to None
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fred-8.0.6/src/router/responses.rs:350

  2026-06-15T05:45:43.440322Z  WARN fred::router::responses: fred-NXMKQD7IMZ: Ending reader task from 127.0.0.1:6379 due to None
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fred-8.0.6/src/router/responses.rs:350

  2026-06-15T05:45:43.440400Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: Canceled, details: Canceled.
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.440417Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: Canceled, details: Canceled.
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.440458Z  WARN fred::router::responses: fred-YoUkJlWZbv: Ending reader task from 127.0.0.1:6379 due to None
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fred-8.0.6/src/router/responses.rs:350

  2026-06-15T05:45:43.440497Z  WARN fred::router::responses: fred-QDZ4MRi4Yh: Ending reader task from 127.0.0.1:6379 due to None
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fred-8.0.6/src/router/responses.rs:350

  2026-06-15T05:45:43.440563Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: Canceled, details: Canceled.
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.440590Z  WARN fred::router::responses: fred-YsNKXlfkHe: Ending reader task from 127.0.0.1:6379 due to None
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fred-8.0.6/src/router/responses.rs:350

  2026-06-15T05:45:43.440623Z  WARN fred::router::responses: fred-RnJf9p1RwM: Ending reader task from 127.0.0.1:6379 due to None
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fred-8.0.6/src/router/responses.rs:350

  2026-06-15T05:45:43.440666Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: Canceled, details: Canceled.
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.645426Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: IO, details: Os { code: 61, kind: ConnectionRefused, message: "Connection refused" }
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.672502Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: IO, details: Os { code: 61, kind: ConnectionRefused, message: "Connection refused" }
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.694324Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: IO, details: Os { code: 61, kind: ConnectionRefused, message: "Connection refused" }
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.708261Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: IO, details: Os { code: 61, kind: ConnectionRefused, message: "Connection refused" }
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:43.728115Z ERROR redis_interface::module::fred: Redis protocol or connection error, error: Redis Error - kind: IO, details: Os { code: 61, kind: ConnectionRefused, message: "Connection refused" }
    at /Users/shivansh.mathur/.cargo/git/checkouts/hyperswitch-90748e17e947b406/c15bf9c/crates/redis_interface/src/module/fred.rs:291

  2026-06-15T05:45:51.303474Z  INFO tower_http::trace::on_request: started processing request
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-http-0.6.8/src/trace/on_request.rs:80
    in tartarus::utils::request with method: GET, uri: /health/diagnostics, version: HTTP/1.1, tenant_id: "public", request_id: "019ec9d0-97c6-7661-9977-48cb249f42f7"

  2026-06-15T05:45:51.303858Z  INFO tartarus::routes::health: Health diagnostics was called
    at src/routes/health.rs:62
    in tartarus::utils::request with method: GET, uri: /health/diagnostics, version: HTTP/1.1, tenant_id: "public", request_id: "019ec9d0-97c6-7661-9977-48cb249f42f7"

  2026-06-15T05:45:51.465903Z  INFO tower_http::trace::on_response: finished processing request, latency: 162826 μs, status: 200
    at /Users/shivansh.mathur/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-http-0.6.8/src/trace/on_response.rs:114
    in tartarus::utils::request with method: GET, uri: /health/diagnostics, version: HTTP/1.1, tenant_id: "public", request_id: "019ec9d0-97c6-7661-9977-48cb249f42f7"

@sentinelone-cnapp-aps1

Copy link
Copy Markdown

SentinelOne CNS Hardcoded Secret Detector
❌ Detected 2 hardcoded secret(s) in your pull request

  • Here are the detected secrets.
Secret Type File Secret Status
RSA private key tenant-private-key.pem RSA Private Key: `-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEApzVECRWBbOueXgPIq1kVh7N11/sS53sxfMtJQ7F6q6qmWPCq
AwpVlb3nkpCk51n/D9vpsqyh3z0YcObIoShdxxf6WSS/GAwwapRpxSSmpcEHKGte
rgkFpVyl9uAY/NzDQxEdygQDHqHm62ykX5qiLjVjF+0AApvSu+8JZkBScXPzfQlT
lFva/Z6HLYF6SrAIGT0rHku/********bp/rl5IqWTKgIe38v0vGBXjH+zTq1lorVrk
EyyVIAcCgYBNLcaZ8RdG273bE8oe6Ze3zQH4KVcN2B6QI76d5k3qhequpb9VZ0bo
2mLvbiBniP9bG8O1srjQfYTQzmMUg+ay/DnVS19tQtvlAsbfnjqi4izaDbFOtzUg
Zn5662of8vunb1ojjPqJpCElnxkxmu7uj4ONNHjx3Ld7sJlTQDgaZQ==
-----END RSA PRIVATE KEY-----` Unknown
RSA private key locker-private-key.pem RSA Private Key: `-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAxtqCAtK29bNARIK4YiO2hcQMBukcluh2RuyUYg4eHivt6fbr
PTP0fRzl7GiC3Tl407NH4UZgkQfhcO06JCq7nNhAa5RC0ZaW0P7jDOUNE0Pbnh6N
DLdUvbzkIGHZmnT4OlmXNU4Eq2UyQNXLHZbF72QEwEeYiesIBlLW5J4QeHfhVtp0
T7C6q5LwMf0O22VWrnsOJFZY********dQIKo2D0BQbDFOs/LPuXBDtiz4aql3hLnebgZ1
kmM1AoGAL4U77eiQ72WonX+r5z96G62Db/vF/qcK068v8dxKvGydU++d6lDeYQba
PPGCEblooZRKytrNftF/KLFPgevDaymelhe8q/kwV72f8OrbR0KnrYlbptW/V8AC
vorC1vQMZoFYPLWc4O1gmfJDNWev2vO5+JhlNd/T2304tckSMFY=
-----END RSA PRIVATE KEY-----` Unknown

SentinelOne CNS detects secrets in your source code. We encourage you to remediate any secret incidents detected. If you want to ignore secrets or change your check runs settings, please go to your SentinelOne CNS Dashboard.

🛠 Guidelines to remediate hardcoded secrets

  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely.
  3. Revoke and rotate this secret
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
  5. If you think this is a false positive, you can mute the issue in the SentinelOne CNS Dashboard

SentinelOne CNS is a cloud-agnostic, agentless CSPM & CWPP solution that continuously detects and prevents vulnerabilities that have the highest probability of being exploited in Azure, AWS, Google Cloud, and Kubernetes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant