Skip to content

Commit f74f8ce

Browse files
authored
Merge pull request #285 from cipherstash/test/walkthrough
feature(showcase): add comprehensive Proxy/EQL showcase crate
2 parents d4a6c6f + bbd7143 commit f74f8ce

File tree

32 files changed

+3468
-266
lines changed

32 files changed

+3468
-266
lines changed

.claude/commands/commit.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# Claude Command: Commit
2+
3+
This command helps you create well-formatted commits with conventional commit messages and emoji.
4+
5+
## Usage
6+
7+
To create a commit, just type:
8+
```
9+
/commit
10+
```
11+
12+
Or with options:
13+
```
14+
/commit --no-verify
15+
```
16+
17+
## What This Command Does
18+
19+
1. Unless specified with `--no-verify`, automatically runs pre-commit checks:
20+
- `cargo clippy` to ensure code quality
21+
- `cargo check` to verify the build succeeds
22+
- `cargo fmt --check` to ensure consistent code formatting
23+
2. Checks which files are staged with `git status`
24+
3. If 0 files are staged, automatically adds all modified and new files with `git add`
25+
4. Performs a `git diff` to understand what changes are being committed
26+
5. Analyzes the diff to determine if multiple distinct logical changes are present
27+
6. If multiple distinct changes are detected, suggests breaking the commit into multiple smaller commits
28+
7. For each commit (or the single commit if not split), creates a commit message using emoji conventional commit format
29+
30+
## Best Practices for Commits
31+
32+
- **Verify before committing**: Ensure code is linted, builds correctly, and documentation is updated
33+
- **Atomic commits**: Each commit should contain related changes that serve a single purpose
34+
- **Split large changes**: If changes touch multiple concerns, split them into separate commits
35+
- **Conventional commit format**: Use the format `<type>: <description>` where type is one of:
36+
- `feat`: A new feature
37+
- `fix`: A bug fix
38+
- `docs`: Documentation changes
39+
- `style`: Code style changes (formatting, etc)
40+
- `refactor`: Code changes that neither fix bugs nor add features
41+
- `perf`: Performance improvements
42+
- `test`: Adding or fixing tests
43+
- `chore`: Changes to the build process, tools, etc.
44+
- **Present tense, imperative mood**: Write commit messages as commands (e.g., "add feature" not "added feature")
45+
- **Concise first line**: Keep the first line under 72 characters
46+
- **Emoji**: Each commit type is paired with an appropriate emoji:
47+
- `feat`: ✨ New feature
48+
- `fix`: 🐛 Bug fix
49+
- `docs`: 📝 Documentation
50+
- `style`: 💄 Formatting/style
51+
- `refactor`: ♻️ Code refactoring
52+
- `perf`: ⚡️ Performance improvements
53+
- `test`: ✅ Tests
54+
- `chore`: 🔧 Tooling, configuration
55+
- `ci`: 🚀 CI/CD improvements
56+
- `revert`: 🗑️ Reverting changes
57+
- `test`: 🧪 Add a failing test
58+
- `fix`: 🚨 Fix compiler/linter warnings
59+
- `fix`: 🔒️ Fix security issues
60+
- `chore`: 👥 Add or update contributors
61+
- `refactor`: 🚚 Move or rename resources
62+
- `refactor`: 🏗️ Make architectural changes
63+
- `chore`: 🔀 Merge branches
64+
- `chore`: 📦️ Add or update compiled files or packages
65+
- `chore`: ➕ Add a dependency
66+
- `chore`: ➖ Remove a dependency
67+
- `chore`: 🌱 Add or update seed files
68+
- `chore`: 🧑‍💻 Improve developer experience
69+
- `feat`: 🧵 Add or update code related to multithreading or concurrency
70+
- `feat`: 🔍️ Improve SEO
71+
- `feat`: 🏷️ Add or update types
72+
- `feat`: 💬 Add or update text and literals
73+
- `feat`: 🌐 Internationalization and localization
74+
- `feat`: 👔 Add or update business logic
75+
- `feat`: 📱 Work on responsive design
76+
- `feat`: 🚸 Improve user experience / usability
77+
- `fix`: 🩹 Simple fix for a non-critical issue
78+
- `fix`: 🥅 Catch errors
79+
- `fix`: 👽️ Update code due to external API changes
80+
- `fix`: 🔥 Remove code or files
81+
- `style`: 🎨 Improve structure/format of the code
82+
- `fix`: 🚑️ Critical hotfix
83+
- `chore`: 🎉 Begin a project
84+
- `chore`: 🔖 Release/Version tags
85+
- `wip`: 🚧 Work in progress
86+
- `fix`: 💚 Fix CI build
87+
- `chore`: 📌 Pin dependencies to specific versions
88+
- `ci`: 👷 Add or update CI build system
89+
- `feat`: 📈 Add or update analytics or tracking code
90+
- `fix`: ✏️ Fix typos
91+
- `revert`: ⏪️ Revert changes
92+
- `chore`: 📄 Add or update license
93+
- `feat`: 💥 Introduce breaking changes
94+
- `assets`: 🍱 Add or update assets
95+
- `feat`: ♿️ Improve accessibility
96+
- `docs`: 💡 Add or update comments in source code
97+
- `db`: 🗃️ Perform database related changes
98+
- `feat`: 🔊 Add or update logs
99+
- `fix`: 🔇 Remove logs
100+
- `test`: 🤡 Mock things
101+
- `feat`: 🥚 Add or update an easter egg
102+
- `chore`: 🙈 Add or update .gitignore file
103+
- `test`: 📸 Add or update snapshots
104+
- `experiment`: ⚗️ Perform experiments
105+
- `feat`: 🚩 Add, update, or remove feature flags
106+
- `ui`: 💫 Add or update animations and transitions
107+
- `refactor`: ⚰️ Remove dead code
108+
- `feat`: 🦺 Add or update code related to validation
109+
- `feat`: ✈️ Improve offline support
110+
111+
## Guidelines for Splitting Commits
112+
113+
When analyzing the diff, consider splitting commits based on these criteria:
114+
115+
1. **Different concerns**: Changes to unrelated parts of the codebase
116+
2. **Different types of changes**: Mixing features, fixes, refactoring, etc.
117+
3. **File patterns**: Changes to different types of files (e.g., source code vs documentation)
118+
4. **Logical grouping**: Changes that would be easier to understand or review separately
119+
5. **Size**: Very large changes that would be clearer if broken down
120+
121+
## Examples
122+
123+
Good commit messages:
124+
- feat: ✨ add user authentication system
125+
- fix: 🐛 resolve memory leak in rendering process
126+
- docs: 📝 update API documentation with new endpoints
127+
- refactor: ♻️ simplify error handling logic in parser
128+
- fix: 🚨 resolve linter warnings in component files
129+
- chore: 🧑‍💻 improve developer tooling setup process
130+
- feat: 👔 implement business logic for transaction validation
131+
- fix: 🩹 address minor styling inconsistency in header
132+
- fix: 🚑️ patch critical security vulnerability in auth flow
133+
- style: 🎨 reorganize component structure for better readability
134+
- fix: 🔥 remove deprecated legacy code
135+
- feat: 🦺 add input validation for user registration form
136+
- fix: 💚 resolve failing CI pipeline tests
137+
- feat: 📈 implement analytics tracking for user engagement
138+
- fix: 🔒️ strengthen authentication password requirements
139+
- feat: ♿️ improve form accessibility for screen readers
140+
141+
Example of splitting commits:
142+
- First commit: ✨ feat: add new solc version type definitions
143+
- Second commit: 📝 docs: update documentation for new solc versions
144+
- Third commit: 🔧 chore: update package.json dependencies
145+
- Fourth commit: 🏷️ feat: add type definitions for new API endpoints
146+
- Fifth commit: 🧵 feat: improve concurrency handling in worker threads
147+
- Sixth commit: 🚨 fix: resolve linting issues in new code
148+
- Seventh commit: ✅ test: add unit tests for new solc version features
149+
- Eighth commit: 🔒️ fix: update dependencies with security vulnerabilities
150+
151+
## Command Options
152+
153+
- `--no-verify`: Skip running the pre-commit checks (`cargo check`, `cargo clippy`, `cargo fmt --check`)
154+
155+
## Important Notes
156+
157+
- By default, pre-commit checks (`cargo check`, `cargo clippy`, `cargo fmt --check`) will run to ensure code quality
158+
- If these checks fail, you'll be asked if you want to proceed with the commit anyway or fix the issues first
159+
- If specific files are already staged, the command will only commit those files
160+
- If no files are staged, it will automatically stage all modified and new files
161+
- The commit message will be constructed based on the changes detected
162+
- Before committing, the command will review the diff to identify if multiple commits would be more appropriate
163+
- If suggesting multiple commits, it will help you stage and commit the changes separately
164+
- Always reviews the commit diff to ensure the message matches the changes

CLAUDE.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
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.
8+
9+
Key capabilities:
10+
- Zero-change SQL queries - applications connect to Proxy instead of directly to PostgreSQL
11+
- EQL v2 (Encrypt Query Language) for searchable encryption using CipherStash ZeroKMS
12+
- Support for encrypted equality, comparison, ordering, and grouping operations
13+
- Written in Rust for performance with strongly-typed SQL statement mapping
14+
15+
## Architecture
16+
17+
### High-Level Components
18+
19+
**Core Proxy (`packages/cipherstash-proxy/`):**
20+
- `postgresql/` - PostgreSQL wire protocol implementation, message parsing, and client handling
21+
- `encrypt/` - Integration with CipherStash ZeroKMS for key management and encryption operations
22+
- `config/` - Configuration management for database connections, TLS, and encryption settings
23+
- `eql/` - EQL v2 types and encryption abstractions
24+
25+
**EQL Mapper (`packages/eql-mapper/`):**
26+
- SQL parsing and type inference engine
27+
- Transformation rules for converting plaintext SQL to encrypted operations
28+
- Schema analysis and column mapping for encryption
29+
30+
**Integration Tests (`packages/cipherstash-proxy-integration/`):**
31+
- Comprehensive test suite covering encryption scenarios
32+
- Language-specific integration tests (Python, Go, Elixir)
33+
34+
**Showcase (`packages/showcase/`):**
35+
- Healthcare data model demonstrating EQL v2 encryption
36+
- Example of realistic encrypted application with foreign keys and relationships
37+
38+
### Request Flow
39+
40+
1. Application connects to Proxy (port 6432) using standard PostgreSQL protocol
41+
2. Proxy intercepts SQL statements and uses EQL Mapper to analyze query structure
42+
3. For encrypted columns, Proxy transforms SQL using EQL v2 operations
43+
4. Encrypted queries are sent to actual PostgreSQL database
44+
5. Results are decrypted before returning to application
45+
46+
## Development Commands
47+
48+
### Prerequisites Setup
49+
```bash
50+
# Install mise (required for all development)
51+
brew install mise # macOS
52+
mise trust --yes && mise install
53+
54+
# Start PostgreSQL containers
55+
mise run postgres:up --extra-args "--detach --wait"
56+
mise run postgres:setup # Install EQL and schema
57+
```
58+
59+
### Core Development Workflow
60+
```bash
61+
# Build and run Proxy as a process (development)
62+
mise run proxy
63+
64+
# Run Proxy in container (integration testing)
65+
mise run proxy:up --extra-args "--detach --wait"
66+
67+
# Kill running processes
68+
mise run proxy:kill
69+
70+
# Reset database state
71+
mise run reset
72+
```
73+
74+
### Testing
75+
```bash
76+
# Full test suite (hygiene + unit + integration)
77+
mise run test
78+
79+
# Unit tests only
80+
mise run test:unit [test_name]
81+
82+
# Integration tests
83+
mise run test:integration
84+
85+
# Language-specific integration tests
86+
mise run test:integration:lang:python
87+
mise run test:integration:lang:golang
88+
89+
# Individual test packages
90+
mise run test:local:integration # cipherstash-proxy-integration
91+
mise run test:local:mapper # eql-mapper
92+
```
93+
94+
### Database Management
95+
```bash
96+
# Connect to Proxy interactively
97+
mise run proxy:psql
98+
99+
# Connect directly to PostgreSQL (bypassing Proxy)
100+
mise run postgres:psql
101+
102+
# Clean shutdown
103+
mise run postgres:down
104+
```
105+
106+
## Configuration
107+
108+
### Authentication & Encryption
109+
Proxy requires CipherStash credentials configured in `mise.local.toml`:
110+
```toml
111+
CS_WORKSPACE_CRN = "crn:region:workspace-id"
112+
CS_CLIENT_ACCESS_KEY = "your-access-key"
113+
CS_DEFAULT_KEYSET_ID = "your-keyset-id"
114+
CS_CLIENT_ID = "your-client-id"
115+
CS_CLIENT_KEY = "your-client-key"
116+
```
117+
118+
### PostgreSQL Port Conventions
119+
- `5532` - PostgreSQL latest (non-TLS)
120+
- `5617` - PostgreSQL 17 (TLS)
121+
- `6432` - CipherStash Proxy
122+
123+
Container names: `postgres`, `postgres-17-tls`, `proxy`, `proxy-tls`
124+
125+
### Logging Configuration
126+
Set granular log levels by target:
127+
```bash
128+
CS_LOG__MAPPER_LEVEL=debug
129+
CS_LOG__AUTHENTICATION_LEVEL=debug
130+
CS_LOG__ENCRYPT_LEVEL=debug
131+
```
132+
133+
Available targets: `DEVELOPMENT`, `AUTHENTICATION`, `CONTEXT`, `ENCRYPT`, `KEYSET`, `PROTOCOL`, `MAPPER`, `SCHEMA`
134+
135+
## Key Development Patterns
136+
137+
### Error Handling
138+
- All errors defined in `packages/cipherstash-proxy/src/error.rs`
139+
- Errors grouped by problem domain (not module structure)
140+
- Customer-facing errors include friendly messages and documentation links
141+
- Use descriptive variant names without "Error" suffix
142+
143+
### Testing Patterns
144+
- Use `unwrap()` instead of `expect()` unless providing meaningful context
145+
- Prefer `assert_eq!` over `assert!` for equality checks
146+
- Integration tests use Docker containers for reproducible environments
147+
148+
### SQL Transformation
149+
- EQL Mapper handles SQL parsing and type inference
150+
- Transformation rules in `packages/eql-mapper/src/transformation_rules/`
151+
- Schema analysis determines which columns require encryption
152+
- Supports complex queries including JOINs, subqueries, and aggregations
153+
154+
## EQL Integration
155+
156+
CipherStash Proxy uses EQL v2 for searchable encryption. Key concepts:
157+
158+
- **Plaintext columns** - standard PostgreSQL data types
159+
- **Encrypted columns** - use `eql_v2_encrypted` type in schema
160+
- **Searchable operations** - equality, comparison, ordering work on encrypted data
161+
- **Index support** - ORE (Order Revealing Encryption) and Match indexes for performance
162+
163+
EQL is automatically downloaded and installed during setup. Use `CS_EQL_PATH` to point to local EQL development version.
164+
165+
## Cross-Compilation & Building
166+
167+
```bash
168+
# Build binary for current platform
169+
mise run build:binary
170+
171+
# Cross-compile for Linux (from macOS)
172+
mise run build:binary --target aarch64-unknown-linux-gnu
173+
174+
# Build Docker image
175+
mise run build:docker --platform linux/arm64
176+
```
177+
178+
The build system supports cross-compilation from macOS to Linux using MaterializeInc/crosstools.

Cargo.lock

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mise.local.example.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ CS_CLIENT_KEY = "client-key"
1515
CS_CLIENT_ID = "client-id"
1616

1717
# The release of EQL that the proxy tests will use and releases will be built with
18-
CS_EQL_VERSION="eql-1.0.0"
18+
CS_EQL_VERSION="eql-2.1.6"
1919

2020
# TLS variables are required for providing TLS to Proxy's clients.
2121
# CS_TLS__TYPE can be either "Path" or "Pem" (case-sensitive).

0 commit comments

Comments
 (0)