This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
CipherStash Proxy is a PostgreSQL proxy that provides transparent, searchable encryption for existing applications. It sits between applications and PostgreSQL databases, automatically encrypting sensitive data while preserving the ability to query encrypted values using equality, comparison, and ordering operations.
Key capabilities:
- Zero-change SQL queries - applications connect to Proxy instead of directly to PostgreSQL
- EQL v2 (Encrypt Query Language) for searchable encryption using CipherStash ZeroKMS
- Support for encrypted equality, comparison, ordering, and grouping operations
- Written in Rust for performance with strongly-typed SQL statement mapping
Core Proxy (packages/cipherstash-proxy/):
postgresql/- PostgreSQL wire protocol implementation, message parsing, and client handlingencrypt/- Integration with CipherStash ZeroKMS for key management and encryption operationsconfig/- Configuration management for database connections, TLS, and encryption settingseql/- EQL v2 types and encryption abstractions
EQL Mapper (packages/eql-mapper/):
- SQL parsing and type inference engine
- Transformation rules for converting plaintext SQL to encrypted operations
- Schema analysis and column mapping for encryption
Integration Tests (packages/cipherstash-proxy-integration/):
- Comprehensive test suite covering encryption scenarios
- Language-specific integration tests (Python, Go, Elixir)
Showcase (packages/showcase/):
- Healthcare data model demonstrating EQL v2 encryption
- Example of realistic encrypted application with foreign keys and relationships
- Application connects to Proxy (port 6432) using standard PostgreSQL protocol
- Proxy intercepts SQL statements and uses EQL Mapper to analyze query structure
- For encrypted columns, Proxy transforms SQL using EQL v2 operations
- Encrypted queries are sent to actual PostgreSQL database
- Results are decrypted before returning to application
# Install mise (required for all development)
brew install mise # macOS
mise trust --yes && mise install
# Start PostgreSQL containers
mise run postgres:up --extra-args "--detach --wait"
mise run postgres:setup # Install EQL and schemamacOS Note: If you hit file descriptor limits during development (e.g. "Too many open files"), you may need to increase the limit:
ulimit -n 10240To make this persistent, add it to your shell profile (e.g.
~/.zshrc).
# Build and run Proxy as a process (development)
mise run proxy
# Run Proxy in container (integration testing)
mise run proxy:up --extra-args "--detach --wait"
# Kill running processes
mise run proxy:kill
# Reset database state
mise run reset# Full test suite (hygiene + unit + integration)
mise run test
# Hygiene checks only
mise run check
# Unit tests only
mise run test:unit [test_name]
# Integration tests
mise run test:integration
# Language-specific integration tests
mise run test:integration:lang:python
mise run test:integration:lang:golang
# Individual test packages
mise run test:local:integration # cipherstash-proxy-integration
mise run test:local:mapper # eql-mapper# Connect to Proxy interactively
mise run proxy:psql
# Connect directly to PostgreSQL (bypassing Proxy)
mise run postgres:psql
# Clean shutdown
mise run postgres:downProxy requires CipherStash credentials configured in mise.local.toml:
CS_WORKSPACE_CRN = "crn:region:workspace-id"
CS_CLIENT_ACCESS_KEY = "your-access-key"
CS_DEFAULT_KEYSET_ID = "your-keyset-id"
CS_CLIENT_ID = "your-client-id"
CS_CLIENT_KEY = "your-client-key"5532- PostgreSQL latest (non-TLS)5617- PostgreSQL 17 (TLS)6432- CipherStash Proxy
Container names: postgres, postgres-tls, proxy, proxy-tls
Set granular log levels by target:
CS_LOG__MAPPER_LEVEL=debug
CS_LOG__AUTHENTICATION_LEVEL=debug
CS_LOG__ENCRYPT_LEVEL=debug
CS_LOG__ZEROKMS_LEVEL=debugAvailable targets: DEVELOPMENT, AUTHENTICATION, CONFIG, CONTEXT, ENCODING, ENCRYPT, DECRYPT, ENCRYPT_CONFIG, ZEROKMS, MIGRATE, PROTOCOL, MAPPER, SCHEMA, SLOW_STATEMENTS
- All errors defined in
packages/cipherstash-proxy/src/error.rs - Errors grouped by problem domain (not module structure)
- Customer-facing errors include friendly messages and documentation links
- Use descriptive variant names without "Error" suffix
- Use
unwrap()instead ofexpect()unless providing meaningful context - Prefer
assert_eq!overassert!for equality checks - Integration tests use Docker containers for reproducible environments
- EQL Mapper handles SQL parsing and type inference
- Transformation rules in
packages/eql-mapper/src/transformation_rules/ - Schema analysis determines which columns require encryption
- Supports complex queries including JOINs, subqueries, and aggregations
CipherStash Proxy uses EQL v2 for searchable encryption. Key concepts:
- Plaintext columns - standard PostgreSQL data types
- Encrypted columns - use
eql_v2_encryptedtype in schema - Searchable operations - equality, comparison, ordering work on encrypted data
- Index support - ORE (Order Revealing Encryption) and Match indexes for performance
EQL is automatically downloaded and installed during setup. Use CS_EQL_PATH to point to local EQL development version.
# Build binary for current platform
mise run build:binary
# Cross-compile for Linux (from macOS)
mise run build:binary --target aarch64-unknown-linux-gnu
# Build Docker image
mise run build:docker --platform linux/arm64The build system supports cross-compilation from macOS to Linux using MaterializeInc/crosstools.
The project maintains a CHANGELOG.md following Keep a Changelog format. When making changes that are user-facing or notable, update the changelog:
- Add entries under an
## [Unreleased]section at the top - Use appropriate subsections:
Added,Changed,Deprecated,Removed,Fixed,Security - Write entries from the user's perspective, not implementation details
- When a release is cut, rename
[Unreleased]to the version number and date
Example entry:
## [Unreleased]
### Added
- **Feature name**: Brief description of what users can now do.
### Fixed
- Description of bug that was fixed.For significant releases, write an ANNOUNCEMENT.md for the GitHub Discussions page:
- Title:
CipherStash Proxy X.Y.Z Released - Brief Feature Summary - Structure:
- Opening paragraph summarizing the release
- H2 sections for each major feature with examples
- Configuration tables where applicable
- Code examples (SQL, JSON, PromQL as relevant)
- "Other Changes" section for minor updates
- "Upgrade" section linking to the releases page
- Callouts: Use GitHub callout syntax for important notes:
> [!NOTE] > Helpful context or clarification. > [!TIP] > Recommended best practices. > [!IMPORTANT] > Critical information users must know.
- After copying content to GitHub Discussions, delete
ANNOUNCEMENT.mdfrom the repo