Skip to main content

Redis — HIPAA Configuration (Cloud Memorystore)

Overview

Cloud Memorystore for Redis is a HIPAA-eligible service under Google's BAA. HIPAA compliance for Redis centers on three principles:

  1. No raw PHI in Redis — store only session tokens, encrypted references, or non-PHI cache data
  2. Encryption in transit and at rest
  3. Private network access only

1. Provisioning a HIPAA-Compliant Redis Instance

gcloud redis instances create phi-redis \
--size=2 \
--region=us-central1 \
--zone=us-central1-a \
--network=projects/YOUR_PROJECT_ID/global/networks/phi-vpc \
--redis-version=redis_7_0 \
--tier=STANDARD_HA \
--transit-encryption-mode=SERVER_AUTHENTICATION \ # TLS enabled
--auth-enabled \
--reserved-ip-range=10.0.0.0/29 \
--connect-mode=PRIVATE_SERVICE_ACCESS \
--project=YOUR_PHI_PROJECT_ID
FlagPurpose
--transit-encryption-mode=SERVER_AUTHENTICATIONEnables TLS
--auth-enabledRequires AUTH password
--tier=STANDARD_HAHigh availability with failover
--connect-mode=PRIVATE_SERVICE_ACCESSVPC peering only

2. Encryption in Transit

# Get and store the server CA certificate
gcloud redis instances describe phi-redis \
--region=us-central1 --project=YOUR_PHI_PROJECT_ID \
--format="value(serverCaCerts[0].cert)" > redis-server-ca.pem

gcloud secrets create redis-ca-cert \
--data-file=redis-server-ca.pem --project=YOUR_PHI_PROJECT_ID

# Store the AUTH string in Secret Manager
gcloud redis instances get-auth-string phi-redis \
--region=us-central1 --project=YOUR_PHI_PROJECT_ID

3. Connecting from Cloud Run

Python (TLS + AUTH)

import redis, ssl, tempfile, os
from google.cloud import secretmanager

def create_redis_client() -> redis.Redis:
auth_string = get_secret("redis-auth-string")
ca_cert_pem = get_secret("redis-ca-cert")

with tempfile.NamedTemporaryFile(mode='w', suffix='.pem', delete=False) as f:
f.write(ca_cert_pem)
ca_cert_path = f.name

try:
client = redis.Redis(
host="REDIS_PRIVATE_IP",
port=6378, # TLS port
password=auth_string,
ssl=True,
ssl_ca_certs=ca_cert_path,
ssl_cert_reqs=ssl.CERT_REQUIRED,
decode_responses=True,
)
client.ping()
return client
finally:
os.unlink(ca_cert_path)

4. PHI Data Rules for Redis

What CANNOT Be Stored

# WRONG — stores raw PHI
redis_client.setex(f"patient:{patient_id}", 3600,
json.dumps({"name": patient.name, "ssn": patient.ssn}))

Correct Approach — Session Tokens Only

def create_session(user_id: str, redis_client) -> str:
session_token = secrets.token_urlsafe(32)
session_data = {
"user_id": user_id, # Internal ID — not PHI
"created_at": datetime.utcnow().isoformat(),
# NO PHI fields
}
redis_client.setex(f"session:{session_token}", 1800, json.dumps(session_data))
return session_token

Acceptable vs Prohibited Use Cases

Use CaseAcceptableNotes
Session token storageYesToken only, no PHI
Rate limiting countersYesIP/user ID only
Job queue (Celery/RQ)YesUse task IDs, not PHI
Feature flagsYesNo PHI involved
Full patient record cacheNoNever store raw PHI

5. TTL Policy

All PHI-adjacent keys must have a TTL:

Key TypeMaximum TTL
Session tokens1800 seconds (30 min)
Encrypted PHI cache300 seconds (5 min)
Rate limit countersPer window
def audit_redis_ttls(redis_client):
"""Find keys without TTL — these must not exist in a PHI app."""
no_ttl_keys = []
cursor = 0
while True:
cursor, keys = redis_client.scan(cursor, count=100)
for key in keys:
if redis_client.ttl(key) == -1:
no_ttl_keys.append(key)
if cursor == 0:
break
return no_ttl_keys

6. Verification

echo "Auth Enabled (must be true):"
gcloud redis instances describe phi-redis --region=us-central1 --project=YOUR_PHI_PROJECT_ID \
--format="value(authEnabled)"

echo "TLS Mode (must be SERVER_AUTHENTICATION):"
gcloud redis instances describe phi-redis --region=us-central1 --project=YOUR_PHI_PROJECT_ID \
--format="value(transitEncryptionMode)"

Next: Encryption →