Skip to content

security: remove REDIS_SSL_PRIVATE_KEY env var path (PER-8500)#52

Open
amandeepsingh333 wants to merge 2 commits into
masterfrom
security/per-8500-remove-redis-key-env
Open

security: remove REDIS_SSL_PRIVATE_KEY env var path (PER-8500)#52
amandeepsingh333 wants to merge 2 commits into
masterfrom
security/per-8500-remove-redis-key-env

Conversation

@amandeepsingh333

@amandeepsingh333 amandeepsingh333 commented Jun 30, 2026

Copy link
Copy Markdown

Summary

PER-8500 — `Percy::RedisClient` previously accepted the raw RSA private key via `REDIS_SSL_PRIVATE_KEY`. Anything that captures the process environment (`/proc`, Sentry, Honeybadger, Datadog APM env-capture, pod specs, audit logs) could lift the key in plaintext, enabling Redis-client impersonation in mTLS or decryption of captured sessions. CVSS 5.5, CWE-321.

This PR drops the `private_key_from_env` code path entirely. Key material must now be supplied either:

  1. explicitly via `ssl_params[:key]` when constructing the client, or
  2. by pointing `REDIS_SSL_PRIVATE_KEY_PATH` at a file with restrictive (e.g. 0400) permissions — on k8s/ECS, a volume-backed secret.

Why this is split from the other PER-* fixes

This is a behaviour-changing breaking change: any downstream service currently setting `REDIS_SSL_PRIVATE_KEY` will start raising `InvalidConfiguration: REDIS_SSL_PRIVATE_KEY_PATH is not defined` the moment it picks up the new percy-common. Separating it from the other PER tickets so it can be reviewed and rolled out on its own cadence.

Action item for reviewers: before merging, please confirm whether any production service in the org sets `REDIS_SSL_PRIVATE_KEY` (rg / grep across the consuming repos). If so, those services need to be cut over to `REDIS_SSL_PRIVATE_KEY_PATH` (or pass the key directly via `ssl_params`) in the same release that bumps percy-common.

The cert-side counterpart `REDIS_SSL_CLIENT_CERTIFICATE` (env var) is left in place — it carries no private-key material — and can be tackled separately if we want to standardise on file-only inputs.

Test plan

  • `bundle exec rubocop lib/percy/redis_client.rb` (clean)
  • `bundle exec rspec spec/percy/redis_client_spec.rb` — the two SSL-mock specs fail on master today on Ruby 3.2+ because the committed test CA is SHA-1 signed (`ca md too weak`). That regression is unrelated to this change and is fixed by PER-8502 / PR #1. After that PR lands, CI on this branch should be green.
  • Confirm no production service still reads `REDIS_SSL_PRIVATE_KEY`

Percy::RedisClient previously accepted the raw RSA private key via the
REDIS_SSL_PRIVATE_KEY environment variable. Anything that captures the
process environment -- /proc, crash reporters (Sentry, Honeybadger, the
Datadog APM env-capture, etc.), pod specs, audit logs -- could lift the
key in plaintext, after which an attacker could impersonate the Redis
client in mutual-TLS or decrypt captured sessions (CVSS 5.5, AV:L/PR:L).

Drop the private_key_from_env code path entirely. Callers must now
supply key material either explicitly via ssl_params[:key] or by
pointing REDIS_SSL_PRIVATE_KEY_PATH at a file with restrictive (e.g.
0400) permissions. On k8s/ECS this should be a volume-backed secret,
not an env var.

This is intentionally a breaking change for any downstream service
currently setting REDIS_SSL_PRIVATE_KEY: they need to migrate to the
_PATH variant or pass the key into ssl_params directly. The cert-side
counterpart (REDIS_SSL_CLIENT_CERTIFICATE) is left in place -- it
carries no private key material -- and should be tackled separately
if we want to standardise on file-only inputs.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@amandeepsingh333 amandeepsingh333 requested a review from a team as a code owner June 30, 2026 04:05
Adds a spec under 'with an SSL-enabled redis URL' that:
  * unsets every REDIS_SSL_* env var,
  * supplies REDIS_SSL_CERTIFICATE_AUTHORITY_PATH and
    REDIS_SSL_CLIENT_CERTIFICATE_PATH so the configuration check
    reaches the private-key branch,
  * sets REDIS_SSL_PRIVATE_KEY (the env var the removed code path used
    to honour) to a placeholder value, and
  * asserts that Percy::RedisClient.new raises
    InvalidConfiguration with `REDIS_SSL_PRIVATE_KEY_PATH is not defined`.

The assertion pins the new failure mode and prevents a future patch
from silently restoring the env-var fallback. The original env state
is restored in `ensure`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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