Security Guide
On this page
- Table of Contents
- Security Model
- TLS Configuration
- Minimum Requirements
- Server Configuration
- Cipher Suites
- Certificate Rotation
- Authentication
- JWT Authentication
- API Key Authentication
- WebAuthn/Passkeys
- OAuth Providers
- Authorization (RBAC)
- Role Hierarchy
- Permissions by Role
- RBAC Implementation
- Resource-Level Permissions
- Tenant Isolation
- Data Isolation
- Isolation Guarantees
- Tenant Context Propagation
- Audit Logging
- Audit Events
- Audit Log Storage
- Audit Log Retention
- Security Hardening
- Network Security
- Container Security
- Secret Management
- Rate Limiting
- Security-Critical Assertions
- Incident Response
- Security Incident Levels
- Incident Response Procedure
- Emergency Contacts
- Revocation Procedures
- Related Documentation
This document covers security configuration for Kimberlite and the cloud platform, including authentication, authorization, TLS, and tenant isolation.
Table of Contents
- Security Model
- TLS Configuration
- Authentication
- Authorization (RBAC)
- Tenant Isolation
- Audit Logging
- Security Hardening
- Incident Response
Security Model
Kimberlite’s security is built on defense in depth with multiple layers:
<div class="security-stack__layer"
role="button"
tabindex="0"
data-class:is-open="$open === 1"
data-on:click="$open = $open === 1 ? 0 : 1"
data-on:keydown="(evt.key === 'Enter' || evt.key === ' ') && ($open = $open === 1 ? 0 : 1)">
<div class="security-stack__layer-header">
<span class="security-stack__layer-number">1</span>
<span class="security-stack__layer-name">Network Security</span>
<span class="security-stack__layer-indicator" aria-hidden="true">›</span>
</div>
<div class="security-stack__layer-details" data-show="$open === 1">
<ul>
<li>TLS 1.3 for all client connections</li>
<li>mTLS for service-to-service communication</li>
<li>Network policies (Kubernetes / firewall rules)</li>
</ul>
</div>
</div>
<div class="security-stack__layer"
role="button"
tabindex="0"
data-class:is-open="$open === 2"
data-on:click="$open = $open === 2 ? 0 : 2"
data-on:keydown="(evt.key === 'Enter' || evt.key === ' ') && ($open = $open === 2 ? 0 : 2)">
<div class="security-stack__layer-header">
<span class="security-stack__layer-number">2</span>
<span class="security-stack__layer-name">Authentication</span>
<span class="security-stack__layer-indicator" aria-hidden="true">›</span>
</div>
<div class="security-stack__layer-details" data-show="$open === 2">
<ul>
<li>JWT tokens for API access</li>
<li>API keys for service accounts</li>
<li>WebAuthn / Passkeys for interactive users</li>
<li>OAuth 2.0 for identity provider federation</li>
</ul>
</div>
</div>
<div class="security-stack__layer"
role="button"
tabindex="0"
data-class:is-open="$open === 3"
data-on:click="$open = $open === 3 ? 0 : 3"
data-on:keydown="(evt.key === 'Enter' || evt.key === ' ') && ($open = $open === 3 ? 0 : 3)">
<div class="security-stack__layer-header">
<span class="security-stack__layer-number">3</span>
<span class="security-stack__layer-name">Authorization</span>
<span class="security-stack__layer-indicator" aria-hidden="true">›</span>
</div>
<div class="security-stack__layer-details" data-show="$open === 3">
<ul>
<li>RBAC at organization level</li>
<li>Structural tenant isolation at data level</li>
<li>Resource-level permissions per stream</li>
</ul>
</div>
</div>
<div class="security-stack__layer"
role="button"
tabindex="0"
data-class:is-open="$open === 4"
data-on:click="$open = $open === 4 ? 0 : 4"
data-on:keydown="(evt.key === 'Enter' || evt.key === ' ') && ($open = $open === 4 ? 0 : 4)">
<div class="security-stack__layer-header">
<span class="security-stack__layer-number">4</span>
<span class="security-stack__layer-name">Data Protection</span>
<span class="security-stack__layer-indicator" aria-hidden="true">›</span>
</div>
<div class="security-stack__layer-details" data-show="$open === 4">
<ul>
<li>Encryption at rest — AES-256-GCM per tenant</li>
<li>Hash chains for tamper-evident integrity</li>
<li>Field-level encryption for PII columns</li>
</ul>
</div>
</div>
<div class="security-stack__layer"
role="button"
tabindex="0"
data-class:is-open="$open === 5"
data-on:click="$open = $open === 5 ? 0 : 5"
data-on:keydown="(evt.key === 'Enter' || evt.key === ' ') && ($open = $open === 5 ? 0 : 5)">
<div class="security-stack__layer-header">
<span class="security-stack__layer-number">5</span>
<span class="security-stack__layer-name">Audit & Compliance</span>
<span class="security-stack__layer-indicator" aria-hidden="true">›</span>
</div>
<div class="security-stack__layer-details" data-show="$open === 5">
<ul>
<li>Immutable append-only audit log</li>
<li>Cryptographic proofs for tamper evidence</li>
<li>Access logging for every operation</li>
</ul>
</div>
</div>
TLS Configuration
Minimum Requirements
- TLS 1.3 required (TLS 1.2 disabled by default)
- Strong cipher suites only
- Certificate chain validation enabled
- OCSP stapling recommended
Server Configuration
// TLS configuration in kimberlite-server
Cipher Suites
Allowed cipher suites (TLS 1.3):
TLS_AES_256_GCM_SHA384TLS_CHACHA20_POLY1305_SHA256TLS_AES_128_GCM_SHA256
Certificate Rotation
Certificates should be rotated before expiration:
# Check certificate expiration
# Automated rotation with cert-manager (Kubernetes)
# See DEPLOYMENT.md for cert-manager configuration
Authentication
JWT Authentication
JWT tokens are used for API authentication.
Token Structure:
Server Validation:
API Key Authentication
API keys are used for service accounts and automation.
Key Format: kimberlite_<environment>_<random_bytes>
Example: kimberlite_prod_a1b2c3d4e5f6g7h8i9j0...
Storage:
- Keys are hashed (BLAKE3) before storage
- Only the hash is stored, never the raw key
- Keys can be scoped to specific operations
WebAuthn/Passkeys
For user authentication, WebAuthn provides phishing-resistant credentials.
Supported Authenticators:
- Platform authenticators (Touch ID, Windows Hello, Face ID)
- Security keys (YubiKey, SoloKey)
- Cross-platform (passkeys synced via iCloud/Google)
Configuration:
OAuth Providers
Supported OAuth providers:
- GitHub (implemented)
- Google (planned)
- Microsoft (planned)
- Custom OIDC (planned)
OAuth Flow:
- User clicks “Sign in with GitHub”
- Redirect to provider with PKCE challenge
- Provider redirects back with authorization code
- Exchange code for tokens
- Fetch user profile
- Create/link local user account
- Issue JWT session token
Authorization (RBAC)
Role Hierarchy
Owner
└── Admin
└── Member
└── Viewer
Permissions by Role
| Permission | Owner | Admin | Member | Viewer |
|---|---|---|---|---|
| View data | Yes | Yes | Yes | Yes |
| Query data | Yes | Yes | Yes | Yes |
| Create streams | Yes | Yes | Yes | No |
| Append events | Yes | Yes | Yes | No |
| Delete streams | Yes | Yes | No | No |
| Manage users | Yes | Yes | No | No |
| Manage roles | Yes | No | No | No |
| Manage billing | Yes | No | No | No |
| Delete org | Yes | No | No | No |
RBAC Implementation
Resource-Level Permissions
Beyond organization-level RBAC, resources can have fine-grained permissions:
Tenant Isolation
Data Isolation
Each tenant’s data is completely isolated:
<div class="tenant-isolation__pane">
<div class="tenant-isolation__header">Tenant A</div>
<div class="tenant-isolation__item">
<span class="tenant-isolation__item-icon">├</span>
<span>data/tenant_a/</span>
</div>
<div class="tenant-isolation__item">
<span class="tenant-isolation__item-icon">├</span>
<span>Keys: KEK_A → DEK_A1, DEK_A2…</span>
</div>
<div class="tenant-isolation__item">
<span class="tenant-isolation__item-icon">└</span>
<span>Streams: patients, visits, billing</span>
</div>
</div>
<div class="tenant-isolation__pane">
<div class="tenant-isolation__header">Tenant B</div>
<div class="tenant-isolation__item">
<span class="tenant-isolation__item-icon">├</span>
<span>data/tenant_b/</span>
</div>
<div class="tenant-isolation__item">
<span class="tenant-isolation__item-icon">├</span>
<span>Keys: KEK_B → DEK_B1, DEK_B2…</span>
</div>
<div class="tenant-isolation__item">
<span class="tenant-isolation__item-icon">└</span>
<span>Streams: orders, inventory</span>
</div>
</div>
Isolation Guarantees
- Storage Isolation: Each tenant has separate storage files
- Key Isolation: Each tenant has unique encryption keys
- Query Isolation: Queries cannot cross tenant boundaries
- Network Isolation: NATS streams are tenant-scoped
Tenant Context Propagation
Every request carries tenant context that is validated:
Audit Logging
Audit Events
All security-relevant events are logged:
Audit Log Storage
Audit logs are stored in Kimberlite itself, benefiting from:
- Immutable append-only storage
- Cryptographic hash chain
- Tamper-evident checkpoints
- Signed exports
Audit Log Retention
Default retention policies:
- Authentication events: 2 years
- Data access events: 7 years
- Administrative events: 10 years
Retention is configurable per compliance requirement:
- HIPAA: 6 years
- SOX: 7 years
- GDPR: Varies by purpose
Security Hardening
Network Security
Firewall Rules:
# Allow only necessary ports - 5432/tcp (Kimberlite protocol, TLS required) - 8080/tcp (Platform HTTP, behind ingress) - 9090/tcp (Metrics, internal only)Network Policies (Kubernetes):
apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: kimberlite-server spec: podSelector: matchLabels: app: kimberlite-server policyTypes: - Ingress - Egress ingress: - from: - podSelector: matchLabels: app: platform-app ports: - port: 5432 egress: - to: - podSelector: matchLabels: app: nats ports: - port: 4222
Container Security
- Non-root user: Run as non-root user
- Read-only filesystem: Mount root as read-only
- No new privileges: Prevent privilege escalation
- Resource limits: Set memory and CPU limits
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
Secret Management
- Never commit secrets: Use environment variables or secret managers
- Rotate regularly: Rotate keys at least quarterly
- Audit access: Log all secret access
- Use secret managers: HashiCorp Vault, AWS Secrets Manager, etc.
// Example: Secret management trait
// Implementations
;
Rate Limiting
Protect against abuse with rate limiting:
Security-Critical Assertions
As of v0.2.0, Kimberlite enforces 38 security-critical assertions in production to detect attacks and corruption before they propagate.
Why Production Assertions for Security:
- Detect Byzantine attacks in real-time
- Catch cryptographic failures (RNG issues, key corruption)
- Enforce consensus invariants (prevent rollback attacks)
- Verify tenant isolation (HIPAA/GDPR compliance)
- Provide forensic evidence of attack vectors
Cryptographic Assertions (25):
// All-zero detection (prevents weak keys, nonces, signatures)
assert!;
assert!;
// Key hierarchy integrity (Master→KEK→DEK)
assert!;
// Ciphertext validation (prevents truncation attacks)
assert!;
Consensus Safety Assertions (9):
// Prevent Byzantine leader attacks
assert!;
// Prevent rollback attacks
assert!;
// Prevent uncommit attacks
assert!;
// Enforce quorum requirements (Byzantine fault tolerance)
assert!;
Tenant Isolation Assertions (4):
// CRITICAL: Compliance requirement (HIPAA, GDPR)
assert!;
// Audit trail completeness
assert!;
Monitoring Recommendations:
Set up PagerDuty/OpsGenie alerts for assertion failures:
# Prometheus alert ruleCapture forensic state when assertions fire:
# Core dump # Replica state dump # Message logsImmediate Response Protocol:
- Isolate the node (remove from cluster, prevent client connections)
- Do NOT restart (preserves forensic state)
- Page on-call security engineer
- Begin incident response procedure (see below)
Performance Impact: <0.1% throughput regression, +1μs p99 latency. See docs/ASSERTIONS.md for complete guide.
Testing: Every assertion has a #[should_panic] test in crates/kimberlite-crypto/src/tests_assertions.rs.
Incident Response
Security Incident Levels
| Level | Description | Response Time | Examples |
|---|---|---|---|
| P1 | Critical | 15 minutes | Data breach, system compromise |
| P2 | High | 1 hour | Auth bypass, privilege escalation |
| P3 | Medium | 4 hours | Suspicious activity, policy violation |
| P4 | Low | 24 hours | Minor vulnerability, audit finding |
Incident Response Procedure
- Detection: Automated alerts or manual report
- Triage: Assess severity and impact
- Containment: Isolate affected systems
- Investigation: Analyze logs and evidence
- Remediation: Fix the vulnerability
- Recovery: Restore normal operations
- Post-mortem: Document lessons learned
Emergency Contacts
Configure emergency contacts in your deployment:
# security-contacts.yaml
contacts:
- name: Security Team
email: security@example.com
phone: +1-555-SECURITY
pagerduty: PXXXXXX
- name: On-Call Engineer
pagerduty: PXXXXXX
Revocation Procedures
Revoke User Access:
# Immediate session revocation
# Disable user account
Revoke API Key:
Rotate Secrets:
# Rotate JWT signing key (invalidates all tokens)
# Rotate encryption keys (transparent re-encryption)
Related Documentation
- COMPLIANCE.md - Compliance requirements
- Deployment Guide - Deployment guide
- Configuration Guide - Configuration reference
- BUG_BOUNTY.md - Security research program
This document describes the current security architecture as of v0.4.1. For planned security enhancements, see ROADMAP.md.