191 lines
6.2 KiB
Markdown
191 lines
6.2 KiB
Markdown
# Clavitor Edition System
|
|
|
|
> **Required reading before any work**: [CLAVITOR-AGENT-HANDBOOK.md](../../../CLAVITOR-AGENT-HANDBOOK.md) — Section I (Culture), Section II (Security), Section III (Workflow), and Section V: clavis-vault (this subproject). You are **Sarah**. Commercial-only code MUST be behind build tags so community builds cannot accidentally activate it.
|
|
|
|
This directory implements build-time differentiation between **Community** (OSS) and **Commercial** (hosted) editions of Clavitor Vault.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
edition/
|
|
├── edition.go # Interface definition (build-agnostic)
|
|
├── community.go # Community Edition (default, !commercial build tag)
|
|
└── commercial.go # Commercial Edition (commercial build tag)
|
|
```
|
|
|
|
## Build Instructions
|
|
|
|
### Community Edition (Default)
|
|
```bash
|
|
# Self-hosted, no telemetry, Elastic 2
|
|
go build -o clavitor ./cmd/clavitor/
|
|
```
|
|
|
|
### Commercial Edition
|
|
```bash
|
|
# Managed by clavitor.ai, telemetry enabled, SCIM/SIEM support
|
|
go build -tags commercial -o clavitor ./cmd/clavitor/
|
|
```
|
|
|
|
## Key Differences
|
|
|
|
| Feature | Community | Commercial |
|
|
|---------|-----------|------------|
|
|
| Telemetry | Manual opt-in via CLI flags | Enabled by default, centralized |
|
|
| Operator Alerts | Local logs only | POSTs to `/v1/alerts` endpoint |
|
|
| **Replication** | **Not available** | **Real-time sync to backup POPs (Calgary/Zurich)** |
|
|
| **Tarpit** | **Not available (simple 404)** | **30s connection drain (anti-scanner)** |
|
|
| Central Management | None | Multi-POP dashboard at clavitor.ai |
|
|
| SCIM/SIEM | No | Yes |
|
|
| **License** | Elastic License 2.0 | Commercial license |
|
|
|
|
## Commercial-Only Features
|
|
|
|
The following features are **only available in Commercial Edition** and do not exist in Community code:
|
|
|
|
### 1. Real-Time Replication to Backup POPs
|
|
**Build constraint:** `//go:build commercial`
|
|
|
|
Background replicator that:
|
|
- Polls `EntryListUnreplicated()` every 30 seconds
|
|
- POSTs encrypted entry blobs to backup POP (Calgary or Zurich)
|
|
- Automatic retry with exponential backoff (max 5 retries)
|
|
- Batching for efficiency (up to 100 entries per request)
|
|
- Conflict resolution: last-write-wins by timestamp
|
|
- Automatic failover: primary → backup POP switching
|
|
|
|
**Community behavior:** No replication code. `ReplicatedAt` field exists in DB schema (for future compatibility) but is never populated or read.
|
|
|
|
### 2. Multi-POP Failover
|
|
Commercial POPs register with the control plane. If primary POP fails, DNS routes to backup within 60 seconds.
|
|
|
|
### 3. Centralized Audit Log Aggregation
|
|
All operator alerts across all POPs feed into central dashboard at clavitor.ai.
|
|
|
|
### 4. Tarpit (Anti-Scanner Defense)
|
|
**Build constraint:** `//go:build commercial`
|
|
|
|
Commercial edition includes a "tarpit" handler for 404/405 responses that:
|
|
- Holds unrecognized requests for 30 seconds
|
|
- Drips one byte per second to keep connection alive
|
|
- Wastes scanner/bot resources (automated tools timeout waiting)
|
|
- Capped at 1000 concurrent connections (drops excess immediately)
|
|
- **Interruptible on shutdown** — checks `edition.ShutdownContext` each second
|
|
|
|
**Community behavior:** Simple 404/405 responses. Fast, user-friendly, immediate shutdown.
|
|
|
|
**Why this is commercial-only:**
|
|
- Self-hosted users (community) don't need anti-scanner defense
|
|
- Tarpit complicates shutdown (needs context cancellation)
|
|
- Enterprise (commercial) faces more automated attacks
|
|
|
|
## Usage in Code
|
|
|
|
### Sending Operator Alerts
|
|
|
|
```go
|
|
// Always use edition.Current.AlertOperator() instead of log.Printf
|
|
edition.Current.AlertOperator(ctx, "auth_error", "message", map[string]any{
|
|
"key": "value",
|
|
})
|
|
```
|
|
|
|
**Community behavior:** Logs to stderr with `OPERATOR ALERT [type]: message` prefix.
|
|
|
|
**Commercial behavior:** Logs locally + POSTs JSON to `{TelemetryHost}/v1/alerts`.
|
|
|
|
### Checking Edition
|
|
|
|
```go
|
|
if edition.Current.Name() == "commercial" {
|
|
// Commercial-only features
|
|
}
|
|
|
|
if edition.Current.IsTelemetryEnabled() {
|
|
// Telemetry is active (commercial always, community if configured)
|
|
}
|
|
```
|
|
|
|
### Commercial Configuration
|
|
|
|
Only valid for commercial builds. Community builds log a warning if called.
|
|
|
|
```go
|
|
edition.SetCommercialConfig(&edition.CommercialConfig{
|
|
TelemetryHost: "https://hq.clavitor.com",
|
|
TelemetryToken: "bearer-token",
|
|
TelemetryFreq: 300, // 5 minutes
|
|
POPRegion: "us-east-1",
|
|
})
|
|
|
|
// Start periodic telemetry reporting
|
|
ctx := context.Background()
|
|
edition.StartTelemetry(ctx)
|
|
```
|
|
|
|
## Environment Variables (Commercial)
|
|
|
|
| Variable | Purpose |
|
|
|----------|---------|
|
|
| `TELEMETRY_HOST` | Base URL for telemetry (e.g., `https://hq.clavitor.com`) |
|
|
| `TELEMETRY_TOKEN` | Bearer token for authentication |
|
|
| `TELEMETRY_FREQ` | Seconds between POSTs (default: 300) |
|
|
| `POP_REGION` | POP identifier for dashboards |
|
|
|
|
## Alert Endpoint (Commercial)
|
|
|
|
Commercial builds POST to:
|
|
```
|
|
POST {TelemetryHost}/v1/alerts
|
|
Authorization: Bearer {TelemetryToken}
|
|
Content-Type: application/json
|
|
```
|
|
|
|
Payload:
|
|
```json
|
|
{
|
|
"edition": "commercial",
|
|
"type": "auth_system_error",
|
|
"message": "Agent lookup failed",
|
|
"details": {"error": "..."},
|
|
"hostname": "pop-us-east-1-03",
|
|
"pop_region": "us-east-1",
|
|
"timestamp": "2026-04-02T00:11:45Z"
|
|
}
|
|
```
|
|
|
|
### Handling 404/Method Not Allowed
|
|
|
|
The router uses edition-specific handlers for unmatched routes:
|
|
|
|
```go
|
|
notFoundHandler := edition.Current.NotFoundHandler()
|
|
r.NotFound(notFoundHandler)
|
|
r.MethodNotAllowed(notFoundHandler)
|
|
```
|
|
|
|
**Community:** Returns simple 404. Fast shutdown, no resource waste.
|
|
|
|
**Commercial:** Tarpit handler holds connections for 30s (anti-scanner), but exits immediately on `edition.ShutdownContext` cancellation.
|
|
|
|
## Important Notes for Opus
|
|
|
|
1. **Never remove the build tags** — they're essential for the dual-license model.
|
|
2. **Always use `edition.Current`** — don't branch on build tags in application code.
|
|
3. **Community is default** — if someone builds without tags, they get OSS edition.
|
|
4. **Commercial config is optional** — commercial builds work without telemetry (just logs).
|
|
5. **Telemetry is separate** — the old `lib/telemetry.go` still exists for community opt-in.
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
# Test community
|
|
go test ./edition/...
|
|
|
|
# Test commercial
|
|
go test -tags commercial ./edition/...
|
|
|
|
# Build both
|
|
go build ./cmd/clavitor/ && go build -tags commercial ./cmd/clavitor/
|
|
```
|