2025-07-17 12:29:20 +00:00
# OHTTP Gateway
An RFC 9458 compliant Oblivious HTTP gateway implementation in Rust.
## Overview
This gateway implements the Oblivious HTTP protocol as defined in [RFC 9458 ](https://datatracker.ietf.org/doc/rfc9458/ ), providing a privacy-preserving HTTP proxy that prevents servers from linking requests to individual clients. The gateway acts as the decryption endpoint in the OHTTP architecture, receiving encrypted requests from relays and forwarding them to target servers.
OHTTP enables clients to make HTTP requests without revealing their identity to the target server by routing requests through a trusted relay that forwards encrypted messages to this gateway. The gateway decrypts the requests using HPKE (Hybrid Public Key Encryption), forwards them to the target server, and returns encrypted responses back through the relay.
## Architecture
2025-07-22 11:51:55 +00:00
```
2025-07-17 12:29:20 +00:00
Client -> Relay -> Gateway -> Target Server
| |
| v
| [Decrypt Request]
| [Forward to Target]
| [Encrypt Response]
| |
< -------- +
2025-07-22 11:51:55 +00:00
```
2025-07-17 12:29:20 +00:00
This implementation serves as the Gateway component, handling:
- HPKE-encrypted request decapsulation
- Request validation and origin policy enforcement
- Target server communication
- Response encryption and encapsulation
- Key management and rotation
## Features
- **RFC 9458 Compliance**: Full implementation of the OHTTP specification
- **HPKE Encryption**: Uses the `ohttp` crate with HPKE for secure request/response handling
- **Automatic Key Rotation**: Configurable key rotation with graceful key transitions
- **Security Controls**: Origin allowlists, request validation, and rate limiting
- **Target Rewrites**: Configurable request rewriting for backend routing
- **Observability**: Prometheus metrics, structured logging, and health checks
- **Production Ready**: Docker support, graceful shutdown, and comprehensive error handling
## Configuration
The gateway is configured via environment variables:
### Basic Configuration
```bash
2025-07-22 11:51:55 +00:00
PORT="8080" # Server port
2025-07-17 12:29:20 +00:00
BACKEND_URL=http://localhost:8080 # Default backend URL
REQUEST_TIMEOUT=30 # Request timeout in seconds
MAX_BODY_SIZE=10485760 # Maximum request body size (10MB)
```
### Key Management
```bash
KEY_ROTATION_INTERVAL=2592000 # Key rotation interval in seconds (30 days)
KEY_RETENTION_PERIOD=604800 # Key retention period in seconds (7 days)
KEY_ROTATION_ENABLED=true # Enable automatic key rotation
SEED_SECRET_KEY=hex_encoded_32_byte_seed # Optional deterministic key generation
```
### Security
```bash
ALLOWED_TARGET_ORIGINS=example.com,api.example.com # Comma-separated allowed origins
TARGET_REWRITES='{"old.com":{"scheme":"https","host":"new.com"}}' # JSON target rewrites
RATE_LIMIT_RPS=100 # Requests per second limit
RATE_LIMIT_BURST=200 # Burst size for rate limiting
RATE_LIMIT_BY_IP=true # Rate limit by client IP
```
### Operational
```bash
METRICS_ENABLED=true # Enable Prometheus metrics
GATEWAY_DEBUG=false # Enable debug mode
LOG_FORMAT=json # Log format: json or default
LOG_LEVEL=info # Log level: debug, info, warn, error
```
## Quick Start
### Using Docker
```bash
# Build the image
docker build -t ohttp-gateway .
# Run with basic configuration
docker run -p 8080:8080 \
-e BACKEND_URL=https://httpbin.org \
-e ALLOWED_TARGET_ORIGINS=httpbin.org \
ohttp-gateway
```
### From Source
```bash
cargo build --release
# Run with environment configuration
export BACKEND_URL=https://httpbin.org
export ALLOWED_TARGET_ORIGINS=httpbin.org
./target/release/ohttp-gateway
```
## API Endpoints
### Gateway Endpoint
- `POST /gateway` - Main OHTTP request handler
- Accepts `message/ohttp-req` content type
- Returns `message/ohttp-res` content type
### Key Configuration
2025-07-22 15:46:27 +00:00
- `GET /ohttp-configs` - Retrieve current key configuration
2025-07-17 12:29:20 +00:00
- Returns `application/ohttp-keys` content type
- Used by clients to obtain encryption keys
### Health and Monitoring
- `GET /health` - Basic health check
- `GET /health/keys` - Key management health check
- `GET /metrics` - Prometheus metrics
## Client Integration
Clients need the key configuration to encrypt requests:
```bash
# Fetch key configuration
2025-07-22 15:46:27 +00:00
curl -H "Accept: application/ohttp-keys" https://gateway:8080/ohttp-configs
2025-07-17 12:29:20 +00:00
# Send OHTTP request (encrypted)
curl -X POST \
-H "Content-Type: message/ohttp-req" \
--data-binary @encrypted_request .bin \
https://gateway:8080/gateway
```
Security Considerations
### Origin Control
Configure `ALLOWED_TARGET_ORIGINS` to restrict which domains the gateway can reach. Without this, the gateway may be used to proxy requests to unintended targets.
### Rate Limiting
Enable rate limiting to prevent abuse:
```bash
RATE_LIMIT_RPS=50
RATE_LIMIT_BURST=100
RATE_LIMIT_BY_IP=true
```
### Key Management
- Keys rotate automatically based on `KEY_ROTATION_INTERVAL`
- Old keys are retained for `KEY_RETENTION_PERIOD` to handle delayed requests
- Use `SEED_SECRET_KEY` for deterministic key generation in clustered deployments
### Request Validation
The gateway validates:
- Request size limits
- Binary HTTP message format
- Target origin allowlists
- Path traversal attempts
## Monitoring
### Metrics
Prometheus metrics are available at `/metrics` :
- `ohttp_requests_total` - Total requests processed
- `ohttp_request_duration_seconds` - Request processing time
- `ohttp_decryption_errors_total` - Decryption failures
- `ohttp_encryption_errors_total` - Encryption failures
- `ohttp_backend_errors_total` - Backend request failures
### Health Checks
- `/health` - Basic service health
- `/health/keys` - Key management status
### Logging
Structured logging with configurable levels and formats. Set `LOG_FORMAT=json` for machine-readable logs.
## Deployment
### Production Considerations
- Use HTTPS for all external traffic
- Configure proper origin allowlists
- Enable rate limiting and monitoring
- Set appropriate resource limits
- Use a reverse proxy for TLS termination
### Kubernetes Example
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: ohttp-gateway
spec:
replicas: 3
selector:
matchLabels:
app: ohttp-gateway
template:
metadata:
labels:
app: ohttp-gateway
spec:
containers:
- name: gateway
image: ohttp-gateway:latest
ports:
- containerPort: 8080
env:
- name: BACKEND_URL
value: "https://api.example.com"
- name: ALLOWED_TARGET_ORIGINS
value: "api.example.com"
- name: RATE_LIMIT_RPS
value: "100"
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
```
## Development
### Building
```bash
cargo build --release
```
### Testing
```bash
cargo test
```
### Linting
```bash
cargo clippy
cargo fmt