clavitor/clavitor.ai/admin/STATUS.md

5.1 KiB

Clavitor Admin & Paddle Integration - Status

Date: April 5, 2026
Status: Foundation Complete, Secure Auth Pending


What We Built

1. Dual-Write Layer (sync.go)

Generic abstraction that writes to our DB + Paddle API simultaneously:

  • Entities supported: customers, addresses, businesses, subscriptions, transactions, discounts
  • Pattern: JSON in → writes to our SQLite first → calls Paddle API → merges response back
  • Retry logic: pending_since timestamp, automatic retry after 5 minutes
  • Webhook handler: Processes inbound Paddle updates, updates our DB

Key insight: We are the source of truth. Paddle handles billing, we handle everything else.

2. Corporate DB Schema (schema.sql)

95% Paddle format + 5% our extensions:

Paddle tables (mirrored):

  • products, prices, discounts - Product catalog
  • customers, addresses, businesses - Billing identity
  • subscriptions, subscription_items - Recurring billing
  • transactions, adjustments - Payments and refunds

Our extensions:

  • customers.parent_id, level - Hierarchy (MSP → Customer → Dept)
  • subscriptions.vault_l0 - Link to vault
  • credentials - P0 → WL3 mapping for POP sync
  • vaults - Vault registry
  • roles, role_assignments, humans - RBAC
  • events - Audit log
  • pop_sync_state - POP synchronization tracking
  • wl3_storage - Wrapped L3 blobs (temporary, to be WORM filesystem)

3. Q&D Admin UI (main.go)

CRUD pages for all entities:

  • Dashboard with stats
  • Customers (with hierarchy support)
  • Subscriptions (linked to vaults)
  • Transactions
  • Vaults (with credential count)
  • Discounts (for MSP margins)
  • Events (audit log)

No authentication yet - open for development.

4. P0/PRF Registration API (credentials_api.go)

Endpoints for device enrollment:

  • POST /api/v1/credentials/register - Store new P0→WL3
  • GET /api/v1/credentials - List credentials for customer
  • GET /api/v1/credentials/wl3?p0=xxx - Download WL3 content
  • GET /api/v1/credentials/sync - POP sync status

Status: Implemented but not wired to main.go (compilation issues).


What's Missing / TODO

HIGH PRIORITY

1. SUPER DUPER SECURE POP Authentication Requirements documented but not implemented:

  • mTLS - POP presents certificate signed by our CA
  • Signed requests - each request signed with POP's private key
  • Replay protection - nonce + timestamp validation
  • IP allowlist - only known POP IPs
  • Rate limiting per POP ID
  • Request signing with HMAC
  • Short-lived tokens (5 min) with refresh
  • Audit logging of ALL POP access

2. WORM Filesystem for WL3 Storage

  • 256 shard directories (first 2 chars of P0)
  • Immutable files: {shard}/{p0}/{timestamp}_{random}.cla
  • rsync for replication between POPs
  • chattr +a for append-only protection
  • Hourly pull from core to POPs (not push)

3. Paddle Webhook Handler

  • Receive subscription.status changes from Paddle
  • Update our DB (active → past_due → canceled)
  • Idempotency via paddle_event_id

MEDIUM PRIORITY

4. Admin Authentication

  • YubiKey/WebAuthn protection for admin pages
  • Currently wide open

5. Paddle Integration Testing

  • Test actual API calls in sandbox
  • Verify dual-write works end-to-end
  • Test retry logic

6. POP Implementation

  • POP server that pulls WL3s from admin
  • Local WORM storage
  • Serves WL3 lookups to vault

Architecture Decisions

We Lead, Paddle Follows

  • We create subscriptions in our DB first
  • We push to Paddle via API
  • We store Paddle's ID for future reference
  • Webhooks update our state (but we're not dependent on them)

Hierarchy via parent_id

  • Level 1: MSP (manages multiple customers)
  • Level 2: End Customer (has vault)
  • Level 3: Department (optional, within customer)

MSP Margins via Discounts

  • Each MSP gets a dedicated discount (e.g., 30% off)
  • Applied to all their customer subscriptions
  • Clean reporting: revenue by discount ID

POP Sync Model

  • Core (admin) stores master WL3s
  • POPs pull incrementally (hourly, 3 min staggered)
  • No full scans - use created_at > last_sync cursor
  • POPs serve WL3s to vaults locally (low latency)

Next Steps (Priority Order)

  1. Secure POP auth - Implement mTLS + signed requests
  2. WORM filesystem - Replace wl3_storage table with actual files
  3. Wire up credential API - Fix compilation, add to main.go
  4. Test Paddle integration - Sandbox testing
  5. Return to vault login - Now we have the infrastructure

Files

File Purpose
admin/sync.go Dual-write abstraction layer
admin/schema.sql Full database schema
admin/main.go Q&D admin UI
admin/credentials_api.go P0/PRF registration API
admin/paddleproxy.go (Old, may delete)

Notes

  • No billing logic in vault - All billing in admin, vault just checks subscription status
  • Flat rate pricing - No usage metering, just tier enforcement (max vaults/devices)
  • Paddle handles tax - We don't calculate tax, Paddle does
  • Zero-knowledge - Admin DB has metadata only, WL3s encrypted, vault data separate

Ready to return to vault login flow when secure auth is implemented.