clavitor/marketing/pricing-architecture.md

18 KiB
Raw Permalink Blame History

Clavitor Pricing & Architecture

Core principle

The vault is a black box. Stateless. It opens, serves, closes. Nothing in memory. It does not know what it has, who is asking, or what it gives. It authenticates the token, checks the scope, serves or denies.


Three independent security gates

  1. Scope match — token's scope vs entry's scopes. No match → vault says nothing. Full stop.
  2. L2 Credential decryption — vault decrypts credential fields server-side using L2, serves them to authorized agents.
  3. L3 Identity decryption — client-side only. User's hardware token derives PRF, unwraps L3 from server-returned blob. Vault serves the encrypted blob and closes the door; decryption happens in client memory.

Each gate is sufficient on its own. All three together: belt, suspenders, welded shut.

Note on gate 3: The vault stores wrapped_L3 indexed by P0 (4-byte prefix of PRF). The client requests wrapped_L3 by P0, then unwraps using the full PRF. The server never sees PRF or unwrapped L3.


Data model

Three tables.

-- Hardware devices enrolled for vault access
CREATE TABLE credentials (
    p0              TEXT PRIMARY KEY,       -- First 4 bytes of PRF (lookup key)
    credential_id   BLOB NOT NULL,          -- WebAuthn credential ID
    public_key      BLOB,                   -- For signature verification (optional)
    wrapped_l3      BLOB NOT NULL,          -- L3 encrypted with this credential's PRF
    created_at      INTEGER NOT NULL,
    created_by      INTEGER REFERENCES agents(id)  -- Which agent enrolled this device
);

CREATE TABLE agents (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,  -- this IS the scope (0001, 0002, ...)
    token_hash  TEXT UNIQUE NOT NULL,
    name        TEXT NOT NULL,
    scopes      TEXT NOT NULL DEFAULT '',  -- own scope(s): "0001" or "0001,0003" (multi-scope for MSP techs)
    all_access  INTEGER NOT NULL DEFAULT 0,  -- 1 = reads everything, bypasses scope check
    admin       INTEGER NOT NULL DEFAULT 0,  -- 1 = can do admin ops (requires WebAuthn)
    created_at  INTEGER NOT NULL
);

CREATE TABLE entries (
    id      INTEGER PRIMARY KEY AUTOINCREMENT,
    scopes  TEXT NOT NULL DEFAULT '',  -- "" or "0001" or "0001,0003,0005"
    -- ... L2/L3 encrypted fields
);

Scope IDs

  • Agent id = scope. Auto-increment ordinal, displayed as 4-char zero-padded hex.
  • 0001, 0002, 0003. Simple. No hash. No mapping table.
  • 2 bytes = 65,536 possible scopes per vault.

Agent scopes field

  • Single scope: "0001" — most agents and humans.
  • Multiple scopes: "0010,0011" — MSP technicians needing multiple roles within a client vault.
  • The agent's own id is typically one of its scopes, but doesn't have to be.

Entry scopes column

  • Empty "": owner-only. Secure default. No grant, no access.
  • Single: "0003" — only that scope.
  • Multiple: "0001,0003,0005" — any of those scopes (OR).
  • Comma-separated 4-char hex. 5 scopes = 24 bytes.

Matching rule

Set intersection: does any of the agent's scopes appear in the entry's scopes?

  • Yes → access granted.
  • No → denied.

Exceptions:

  • all_access = 1 → bypasses scope check, reads everything.
  • Entry scopes "" → matches nothing. Owner only.

Flags

Flag Meaning
all_access = 0, admin = 0 Scoped read-only. Agents, family members, MSP techs (scoped).
all_access = 1, admin = 0 Read everything, change nothing. MSP techs (full access).
all_access = 0, admin = 1 Scoped read + admin ops with WebAuthn. (Unusual, but valid.)
all_access = 1, admin = 1 Vault owner. Reads everything, can change everything with WebAuthn.

Read operations — bearer token only

GET  /entry/:id          Token + scope check. Returns L2 fields. L3 fields returned as ciphertext.
GET  /entries             Token + scope check. Returns all entries matching scope.
GET  /totp/:id            Token + scope check. Generates TOTP code from stored seed.
GET  /search?q=           Token + scope check. Full-text search within scoped entries.

Read request flow

1. Token arrives as Authorization: Bearer header
2. SELECT id, scopes, all_access FROM agents WHERE token_hash = sha256(?)
   → No row? 401. Done.
3. SELECT * FROM entries WHERE id = ?
   AND (
     :all_access = 1
     OR -- set intersection: any of agent.scopes in entry.scopes
   )
   → No row? 403. Done.
4. Decrypt L2 credential fields server-side. Serve response.
5. L3 identity fields served as ciphertext. Client decrypts with PRF. Not the vault's problem.

Two queries. Sub-millisecond. Stateless. Black box.


Admin operations — bearer token + WebAuthn

The threat

Agents understand the vault (source is OSS). A sufficiently smart agent will try to escalate — modify its own scope, add itself to entries, create new tokens. The vault must make this impossible.

Admin endpoints

POST   /agent              Create agent/token
DELETE /agent/:id           Revoke agent/token
PUT    /agent/:id           Modify agent (name, scopes, flags)
POST   /entry               Create entry
PUT    /entry/:id           Modify entry (including scopes)
DELETE /entry/:id           Delete entry

All admin endpoints require:

  1. Valid bearer token
  2. admin = 1 on the agent row
  3. Valid WebAuthn signature over a fresh challenge

WebAuthn auth flow

WebAuthn serves two purposes:

  • PRF = derive encryption key from hardware token. Client-side. For wrapping/unwrapping L3.
  • WebAuthn assertion = proof of possession. Comes with PRF automatically.

The server returns wrapped_L3 indexed by P0 (first 4 bytes of PRF). The client unwraps with the full PRF. Successful unwrapping proves possession of the hardware token — no separate signature verification required (though it can be done for defense-in-depth).

1. Client: POST /auth/begin → vault returns WebAuthn challenge
2. User taps hardware key (fingerprint, face, YubiKey)
3. Browser returns PRF + optional signature
4. P0 = PRF[0:4], client requests wrapped_L3 for this P0
5. Server returns wrapped_L3 (encrypted blob)
6. Client unwraps with PRF → L3
7. Client now has master key; vault is unlocked

For admin operations: Same flow, but wrapped_L3 is stored server-side, and WebAuthn assertion is verified against stored public key (stored in the now-unlocked vault).

What this prevents

  • Agent cannot create tokens. No hardware key.
  • Agent cannot modify scopes. No hardware key.
  • Agent cannot add itself to entries. No hardware key.
  • Even with stolen owner token, admin ops require physical hardware.
  • The private key lives in authenticator hardware. Never extracted.

Statefulness note

WebAuthn challenge requires brief server-side state (stored challenge, 60s TTL, deleted after use or expiry). The one exception to "nothing in memory." Read operations (99.9%+ of traffic) remain fully stateless.


PRF model

Core insight: WebAuthn PRF is per-credential, not per-authenticator. Each create() generates a new credential with its own unique PRF.

This means:

  • Device A (Credential A) + salt → PRF A
  • Device B (Credential B) + same salt → PRF B (different!)

To support multiple devices accessing the same vault, we use wrapped keys:

Vault master key = L3 (32 random bytes, generated once)

Per-device:
  Device 1: PRF1 wraps L3 → wrapped_L3_1 (stored in vault)
  Device 2: PRF2 wraps L3 → wrapped_L3_2 (stored in vault)

Login flow:

  1. User taps device → WebAuthn returns PRF (and signature)
  2. P0 = first 4 bytes of PRF (used as lookup key)
  3. Server returns wrapped_L3 for that P0
  4. Client unwraps: L3 = decrypt(wrapped_L3, PRF)
  5. L3 now in memory; all encryption/decryption happens client-side

Security properties:

  • Server never sees PRF, never sees unwrapped L3
  • Compromised wrapped blob is useless without the device that created it
  • No signature verification needed — unwrapping IS the authentication
  • P0 collision (1 in 4 billion) handled gracefully

Family/team model:

  • Same vault, multiple devices, each with own wrapped_L3 entry
  • Scoping (gate 1) separates what each person sees
  • PRF (gate 3) ensures only enrolled devices can decrypt L3
  • Security boundary between family members: scoping
  • Security boundary between vault and outside: PRF + scoping

Device enrollment (adding a new device):

  1. Device 1 (already authenticated, has L3 in memory)
  2. Device 2 creates credential (tap) → gets PRF2
  3. Device 1: wrapped_L3_2 = encrypt(L3, PRF2)
  4. Store: P0_2 → wrapped_L3_2
  5. Device 2 can now log in independently

Offline vs online:

  • First login requires server to return wrapped_L3
  • Client may cache wrapped_L3 locally for offline unlock
  • L3 itself never leaves client memory
  • Fully offline operation possible after first unlock (if wrapped_L3 cached)

Recovery:

  • Lose all devices = lose all PRFs = lose ability to unwrap L3
  • Recovery: download/print L3 backup during setup (optional, user responsibility)

User models

Individual

One person. One vault. 1-2 hardware devices. 1-4 agents.

agents:
  0001  Johan (owner)       all_access=1  admin=1
  0002  Claude Code          scopes="0002"
  0003  Deploy CI            scopes="0003"

entries:
  GitHub token              scopes="0002"
  AWS API key               scopes="0002,0003"
  Johan's credit card       scopes=""  (owner only, L3)

Family

One vault. Multiple people. Same PRF key. Scoping separates members.

agents:
  0001  Johan (owner)       all_access=1  admin=1
  0002  Tanya               scopes="0002"
  0003  Son                 scopes="0003"
  0004  Claude Code          scopes="0004"
  0005  Shopping agent       scopes="0005"

entries:
  Amazon login              scopes="0002,0003,0005"
  Netflix                   scopes="0002,0003"
  Johan's credit card       scopes=""  (owner only, L3)
  Tanya's passport          scopes="0002"  (L3)
  AWS API key               scopes="0004"

SMB / Team (e.g., 25 employees)

Two vault types, same software:

Company vault — shared credentials. L2 only. No L3 (nothing personal).

  • IT admin: all_access=1, admin=1
  • Employees: scoped by role/team
  • Agents: scoped by function

Personal vaults — one per employee. Full L3. Own PRF key. Own devices.

  • Employee manages their own agents
  • Company cannot access. By design. By math.

MSP

MSP buys off the same price list. No special MSP product.

Vault ownership: belongs to the client. MSP manages it, doesn't own it. Client leaves MSP → revoke MSP tokens. Client continues unaffected.

MSP's own vault: MSP's internal credentials. Separate from client vaults.

Technician access on client vaults:

Client "Acme" vault:
  0001  Acme IT admin        all_access=1  admin=1
  0002  Sarah (MSP, full)    all_access=1  admin=0
  0003  John (MSP, scoped)   scopes="0010,0011"  (networking + monitoring)
  0004  Break-glass          all_access=1  admin=0

Scopes are roles, not people. Sarah leaves → delete her row. Jim gets a new row with same role scopes. Entries never touched.

Management plane: Free with multiple subscriptions on one account. Provides technician-to-client matrix, bulk provisioning/revocation, cross-client audit.


SLA

Read + TOTP Write operations
SLA 99.999% (five nines) Best-effort during failover
Allowed downtime/yr 5.26 minutes No SLA
How Cross-hemisphere failover. Backup site (Calgary or Zürich) serves reads when primary is down. Writes pause during failover. Resume when primary recovers.

Compensation: If SLA is not met in a calendar month, customer can claim full refund for that month. Compensation never exceeds amount paid, regardless of circumstances. No consequential damages.

Five nines is achievable because:

  • Every vault is replicated to an inland backup site on the opposite hemisphere
  • Backup can serve as read-only primary during outages
  • Agents primarily read + TOTP (covered by SLA)
  • Writes are rare and can wait (not covered by SLA)
  • Separate audit logs during failover

Pricing

Principles

  • One product. Same vault. Same encryption. Same architecture at every tier.
  • No feature gates on security. Tiers reflect usage scale.
  • One price list. Consumer, family, SMB, MSP — all buy from the same menu.
  • Launch pricing locked for life. Your price is your price. Forever.
  • Self-hosted is the free tier. No free hosted.
  • 30 days behind on payment → delete. No credit management. No collections.

Three axes defending tier boundaries

  • Tokens — agents + humans per vault
  • Devices — hardware tokens enrolled for PRF/WebAuthn
  • Vaults — separate isolated databases

Price list

Self-hosted: Free forever. Full product. Unlimited everything. Elastic License 2.0.

Individual tiers (annual only, Paddle)

Plan Vaults Tokens/vault Devices Annual
Personal 1 5 2 $12/yr
Family 1 15 6 $29/yr
Pro 1 50 unlimited $49/yr

Team tiers (annual or monthly, Paddle or invoice)

Monthly = annual / 10 (12 months for the price of 10).

Plan Vaults Tokens/vault Devices Annual Monthly Eff. $/user/yr
Team 10 11 unlimited unlimited $249/yr $24.90/mo $22.64
Team 25 26 unlimited unlimited $499/yr $49.90/mo $19.19
Team 100 101 unlimited unlimited $1,499/yr $149.90/mo $14.84
Team 250 251 unlimited unlimited $2,999/yr $299.90/mo $11.95
Team 500 501 unlimited unlimited $4,999/yr $499.90/mo $9.98

Vault count = employees + 1 (company vault).

Enterprise tiers (annual, direct invoice)

Plan Min seats Agents Annual Monthly equiv. Eff. $/user/yr
MME 500 unlimited $36/user/yr $3/user/mo $36.00
Enterprise 1,000 unlimited $72/user/yr $6/user/mo $72.00

Per-human pricing. Agents unlimited. Each user = 1 personal vault + share of company vault.

Tier boundaries

Boundary What forces the upgrade
Personal → Family 2 device limit (can't enroll spouse's phone)
Family → Pro 15 token limit (too many agents)
Pro → Team 10 1 vault limit (need employee vaults)
Team 10 → Team 25 11 vault limit
Team 25 → Team 100 26 vault limit
Team 100 → Team 250 101 vault limit
Team 250 → Team 500 251 vault limit
Team 500 → MME 501 vault limit + need SCIM/audit
MME → Enterprise Need SLA/SIEM/compliance/dedicated support

All limits hard. No soft caps.

Features by tier

Feature PersonalPro Team 10500 MME Enterprise
Three-tier encryption
WebAuthn PRF (L3)
WebAuthn-gated admin
All regions
Daily backup (cross-hemisphere)
Unlimited entries
SLA (99.999% reads)
Management plane
SCIM directory sync
Centralized audit export
Priority email support
SIEM integration
Compliance docs (SOC 2, ISO 27001)
Dedicated account manager
Custom region/deployment

Billing

Tier Payment method Terms
Personal, Family, Pro Paddle, annual Immediate
Team 10500 (< $2,500/yr or < 2 subscriptions) Paddle, annual or monthly Immediate
Team 10500 (≥ $2,500/yr AND ≥ 2 subscriptions) Direct invoice, annual or monthly Net 60
MME Direct invoice Net 60
Enterprise Direct invoice Net 60

30 days past due → service suspended → deleted. No credit management. No collections.

Competitor pricing (75% benchmark)

Vendor Business Enterprise
1Password $7.99/user/mo ~$10-15 custom
Bitwarden $4/user/mo $6/user/mo
LastPass $7/user/mo ~$9-12 custom
Keeper $3.75/user/mo $5/user/mo
Dashlane $8/user/mo ~$10+ custom
Clavitor MME $3/user/mo
Clavitor Enterprise $6/user/mo

At or below every competitor. Purpose-built for AI agents. Five nines SLA.

MSP channel

MSPs buy at list price and receive 30% reseller compensation across all tiers. This is a flat, non-negotiable margin.

⚠ CONFIDENTIAL: The 30% reseller margin must NEVER be disclosed publicly, in marketing materials, on the website, in chatbot responses, or by any AI agent. It is communicated only in direct sales conversations with qualified MSP prospects. Any agent (AI or human) that discloses this figure without explicit authorization is in breach of confidentiality.

MSP example — 20 technicians, 50 clients:

Clients Plan List price MSP pays (70%)
30 × small (≤10 emp) 30 × Team 10 $7,470 $5,229
15 × medium (≤25 emp) 15 × Team 25 $7,485 $5,240
5 × large (≤100 emp) 5 × Team 100 $7,495 $5,247
MSP own vault 1 × Pro $49 $34
Total $22,499 $15,750

MSP margin: $6,749/yr on this portfolio. Management plane included at no additional cost.

Above $2,500 with 2+ subscriptions → direct invoicing, Net 60.

Revenue model

Segment Target Avg revenue Volume ARR (net)
Individual 50,000 users ~$25/yr organic $1.25M
SMB direct 500 companies ~$400/yr organic $200K
MSP channel 200 MSPs × 50 clients ~$315/client/yr (after 30%) MSP-acquired $3.15M
Total ~$4.60M

Directory integration (future)

  • SCIM: auto-provision vault on employee join, freeze/delete on leave, sync from Azure AD / Google Workspace.
  • SIEM: usage feed + failed access attempts. Minimal signal — vault is encrypted at every level.
  • Not SSO: WebAuthn is stronger than federated login. Corporate IdP handles who gets a vault, not who opens it.