Encryption architecture
LaneSync uses envelope encryption (the same pattern as AWS KMS, Google Cloud KMS, and Azure Key Vault):- A Data Encryption Key (DEK) encrypts the sensitive payload (AES-256-GCM).
- The DEK is wrapped by a Key Encryption Key (KEK) managed in AWS KMS (staging/production) or a local software KEK (development).
- Stored format:
ciphertext + wrapped DEK— decrypting requires both KMS access and the correct encryption context.
Per-tenant key isolation
Every encrypt/decrypt operation includes an encryption context withtenant_id. AWS KMS cryptographically binds the ciphertext to that context — attempting to decrypt with a different tenant’s context fails, even with valid KMS permissions.
Application config secrets (GitHub App credentials) use a separate context: { scope: app_config, profile: staging }.
What is encrypted
LaneSync does not store application source code.
Tenant isolation
Each GitHub organization maps to one tenant. PostgreSQL Row Level Security (RLS) enforces that queries only return rows for the active tenant. RLS protects against application-layer bugs. Envelope encryption protects against database credential compromise — the defense-in-depth layer. See Multi-tenancy.Authentication
Session cookies are
httpOnly, sameSite=lax, and secure in production.
CI workload identity
LaneSync follows the industry-standard OIDC workload identity pattern (same approach as AWS, GCP, Azure, and Datadog CI):- GitHub Actions mints a short-lived JWT per workflow run
- LaneSync verifies the signature against GitHub’s JWKS
- Tenant is derived from the
repository_ownerclaim — not from request body fields - Optional per-tenant API keys (
lsk_*) support non-GitHub CI; keys are SHA-256 hashed at rest
Rate limiting and abuse protection
- Global and per-endpoint rate limits on public surfaces
- Webhook body size cap (1 MB) before signature verification
- Evidence report HTML served with sandbox CSP and
Content-Disposition: attachmentto prevent stored XSS
Database access model
- Migration role (superuser): schema bootstrap only; connection pool closed after init.
- sdlc_app role: runtime queries with
FORCE ROW LEVEL SECURITY— no BYPASSRLS.
infrastructure/terraform/DB_ACCESS.md in the repository.
Audit logging
Security-sensitive actions are logged to theaudit_log table (tenant-scoped):
- Evidence uploads (
evidence.upload) - Report views (
evidence.report.view)
GenerateDataKey and Decrypt calls are auditable via AWS CloudTrail (when enabled).
Key rotation
- KEK: AWS KMS automatic rotation every 365 days (enabled in Terraform).
- DEK: unique per record — KEK rotation re-wraps DEKs without re-encrypting data.
- Application secrets: rotate via AWS Secrets Manager (recommended 90-day cadence).
Compliance readiness
SOC 2 Type II certification requires an external audit — contact
security@lanesync.dev for the latest status.
Hardening checklist (self-hosted)
1
TLS everywhere
Terminate HTTPS at load balancer or reverse proxy. Set
trust proxy (enabled in backend).2
Set KMS and S3 env vars
KMS_KEY_ID, EVIDENCE_BUCKET, AWS_REGION for envelope encryption and blob storage.3
Rotate secrets
SESSION_SECRET, ENCRYPTION_KEY, GitHub App private key, database credentials.4
Use sdlc_app DB role
Set
DATABASE_APP_URL to a non-superuser role. Never run the app as postgres superuser.5
Backup PostgreSQL and S3
Milestone, evidence metadata, and encrypted blobs — include both in DR plan.