Client Secrets & Security Guide
Status: Complete
Generated: 2025-08-11 UTC
Purpose: Explain how SESSION_SECRET and JWT_SECRET work in multi-client deployments
Overview
Each Sasha Studio client deployment requires unique cryptographic secrets for secure operation. These secrets ensure session management, authentication, and client isolation work properly.
The Two Critical Secrets
SESSION_SECRET
Purpose: Secures user session cookies
Used by: Express.js session middleware
When: Every user login, session validation, cookie operations
// How it's used in the application
app.use(session({
secret: process.env.SESSION_SECRET, // <- This is your generated secret
resave: false,
saveUninitialized: false,
cookie: { secure: false }
}));
JWT_SECRET
Purpose: Signs and verifies JSON Web Tokens
Used by: Authentication system, API token validation
When: User authentication, API calls, token refresh
// How it's used in the application
const token = jwt.sign({
userId: user.id,
clientId: 'hirebest'
}, process.env.JWT_SECRET, { expiresIn: '24h' });
// Later verification
const decoded = jwt.verify(token, process.env.JWT_SECRET);
How Secrets Are Generated
Automatic Generation Process
# Each secret is generated using:
openssl rand -base64 32
# This creates:
# - 32 random bytes (256 bits of entropy)
# - Base64 encoded for safe storage
# - Cryptographically secure random generation
Example Generated Secrets
SESSION_SECRET="xNdbDe/wv8R3qc4kY27MaYQH8B5mh/ssbfZFkf6Ubm0="
JWT_SECRET="dTVzaMHd5VB9ObZ9Dm+fO11VocoMXwAiT046ig9WUNo="
Multi-Client Security Architecture
Client Isolation
Each client gets unique secrets to ensure:
βββββββββββββββββββ βββββββββββββββββββ
β HireBest β β Sasha Main β
β β β β
β SESSION_SECRET: β β SESSION_SECRET: β
β xNdbDe/wv8R... β β DHc27bK2QC... β
β β β β
β JWT_SECRET: β β JWT_SECRET: β
β dTVzaMHd5V... β β sdksgJdzD7... β
βββββββββββββββββββ βββββββββββββββββββ
Security Benefits
- Session Isolation: HireBest users cannot access Sasha Main sessions
- Token Isolation: JWT tokens from one client won't work on another
- Cryptographic Separation: Each client has independent security boundary
- Breach Containment: Compromise of one client doesn't affect others
Secrets Lifecycle
Creation (New Client)
./manage-clients.sh create my-new-client
# β Automatically generates unique SESSION_SECRET and JWT_SECRET
# β Saves to client-management/clients/my-new-client/config.json
# β Ready for Sliplane deployment
Deployment Flow
- Config File: Secrets stored in
clients/{client}/config.json - Sliplane Setup: Copy secrets to Environment Variables tab
- Container Runtime: Docker passes secrets as
process.envvariables - Application: Node.js reads secrets and uses for security
Environment Variable Mapping
# In Sliplane Environment tab:
SESSION_SECRET=xNdbDe/wv8R3qc4kY27MaYQH8B5mh/ssbfZFkf6Ubm0=
JWT_SECRET=dTVzaMHd5VB9ObZ9Dm+fO11VocoMXwAiT046ig9WUNo=
# In Node.js application:
const sessionSecret = process.env.SESSION_SECRET;
const jwtSecret = process.env.JWT_SECRET;
Security Considerations
Secret Management Best Practices
DO:
- Use the auto-generated secrets (256-bit entropy)
- Keep secrets in Sliplane environment variables
- Use different secrets for each client
- Rotate secrets periodically for high-security environments
DON'T:
- Use weak/predictable secrets
- Share secrets between clients
- Commit secrets to version control
- Log secrets in application logs
- Transmit secrets in URLs or forms
What Happens When Secrets Are Wrong
| Scenario | Result | User Experience |
|---|---|---|
| Missing SESSION_SECRET | Sessions fail | Users can't stay logged in |
| Missing JWT_SECRET | Authentication fails | API calls rejected |
| Wrong SESSION_SECRET | Session validation fails | Existing users logged out |
| Wrong JWT_SECRET | Token verification fails | "Invalid token" errors |
| Shared secrets | Security vulnerability | Cross-client access possible |
Troubleshooting
Common Issues
Problem: "Session secret is required"
# Solution: Check Sliplane environment variables
SESSION_SECRET=your-generated-secret-here
Problem: "JWT secret not provided"
# Solution: Ensure JWT_SECRET is set in Sliplane
JWT_SECRET=your-generated-jwt-secret-here
Problem: Users getting logged out randomly
# Likely cause: SESSION_SECRET changed or missing
# Solution: Verify SESSION_SECRET matches what was originally deployed
Verification Commands
# Check client configuration
./manage-clients.sh info hirebest
# Verify secrets are properly formatted (base64, ~44 characters)
echo "xNdbDe/wv8R3qc4kY27MaYQH8B5mh/ssbfZFkf6Ubm0=" | wc -c # Should be ~45
# Test secret generation manually
openssl rand -base64 32
Secret Rotation (Advanced)
For high-security environments, rotate secrets periodically:
# 1. Generate new secrets
NEW_SESSION_SECRET=$(openssl rand -base64 32)
NEW_JWT_SECRET=$(openssl rand -base64 32)
# 2. Update client config
# Edit clients/hirebest/config.json with new secrets
# 3. Update Sliplane environment variables
# Go to Sliplane β Environment β Update SESSION_SECRET and JWT_SECRET
# 4. Redeploy
./deploy-client.sh hirebest
# Note: This will log out all existing users
Integration with Shared Docker Images
How Secrets Work with Shared Images
Same Docker Image: linzoid/sasha-studio:1.0.2
βββ HireBest Instance (unique secrets)
βββ Sasha Main Instance (unique secrets)
βββ Future Client Instance (unique secrets)
- Same codebase reads
process.env.SESSION_SECRET - Different values per deployment via Sliplane environment
- Client isolation maintained through unique secrets
- No code changes needed for new clients
Benefits of This Architecture
- Single image to maintain - same security code everywhere
- Environment-driven configuration - secrets set at deploy time
- Perfect client isolation - cryptographically separated
- Easy scaling - add clients without code changes
Related Documentation
- Client Management README - Complete system overview
- Deployment Guide - Step-by-step deployment
- Troubleshooting Guide - Common issues and solutions
This document explains the cryptographic foundation that keeps each client's data and sessions secure in the multi-tenant Sasha Studio architecture.