Commit Graph

35 Commits

Author SHA1 Message Date
James def0c6fb1d test: rewrite agent credential tests for client-side generation
Rewrites 7 skipped integration tests to work with client-side credential generation:

- TestScopedAccess_agent_sees_only_scoped_entries
- TestScopedAccess_agent_forbidden_on_unscoped
- TestScopedAccess_all_access_sees_everything
- TestScopedAccess_agent_cannot_manage_agents
- TestScopedAccess_agent_cannot_create_system_types (renamed from _modify_scopes)
- TestScopedAccess_agent_entries_invisible
- TestKeyLeak_agent_credential_is_opaque

Adds MintCredential/ParseCredential test helpers to lib/cvt.go for creating
type 0x01 client credential tokens in tests. These simulate the client-side
credential generation that normally happens in browser/CLI.

Adds test helper methods to integration_test.go:
- reqAgent(): sends requests with CVT wire token authentication
- mintWireToken(): creates type 0x00 wire tokens for agent auth

Security boundaries tested:
- Agents with limited scope cannot access owner-only entries
- Agents with all_access can see all entries
- Agents cannot manage other agents (create/list)
- Agents cannot create system-type entries (agent, scope)
- Server responses never contain raw L2/L3 key material

Fixes #14
2026-04-09 03:45:42 -04:00
James 989f7e5f2b ui: remove strikethrough pricing — always show $12/yr
Removes crossed-out "$20" pricing from all templates and test files.
The hosted plan is now permanently $12/year.

Files modified:
- test-index.html: Header CTA button
- test-hosted.html: Header CTA and hero text
- base.tmpl: Header CTA button
- hosted.tmpl: Hero text and CTA section
- index.tmpl: Hero button and hosted CTA section
- upgrade.tmpl: Pricing comparison text
- integrations.tmpl: All 4 CTA buttons (English + Chinese)
- install.tmpl: Hosted option section

fixes #9

Author: Emma <emma-20250409-001>
2026-04-09 03:36:54 -04:00
James fe9f98a69e telemetry: add Prometheus metrics endpoint
Adds /metrics endpoint that returns Prometheus-format metrics for monitoring:

- telemetry_requests_total (counter, labeled by pop_id and status)
- telemetry_request_duration_seconds (histogram with standard buckets)
- active_connections (gauge)
- db_query_duration_seconds (histogram for health check queries)

Following KISS principle - no external dependencies, simple text format
implementation with proper mutex protection for thread safety.

All error paths handled with unique error codes per Cardinal Rule.

fixes #8
2026-04-09 03:29:32 -04:00
James 6c2b708c4d telemetry: verify dispatcher agent spawning for Hans
Adds verification documentation that the dispatcher flow correctly:
- Identifies clavis-telemetry domain issues
- Assigns to Hans (NOC/Operations agent)
- Spawns Hans successfully to process telemetry issues

All tests pass, no security violations detected.

fixes #5
2026-04-09 03:14:27 -04:00
James b4aced5c03 telemetry: fix CRITICAL silent failures (Cardinal Rule #1)
Fixes #2, #3, #4

Issue #2 - Silent database errors in updateSpan():
- Add error handling for telemetry INSERT (ERR-TELEMETRY-004)
- Add error handling for all table/index creation (ERR-TELEMETRY-005 to -010)
- Return HTTP 500 to client on insert failure

Issue #3 - Silent failure in Kuma push:
- Return early on non-OK status from Kuma
- Proper error logging with body close handling

Issue #4 - Unchecked flush error in tarpit:
- Verify http.Flusher available before tarpit
- Log ERR-TELEMETRY-040 and abort if flusher unavailable
- Remove redundant flusher checks in loop

All changes: security failures are now LOUD (Cardinal Rule #1)

Author: Hans <hans-20250409-001>
2026-04-09 01:20:08 -04:00
James b920203314 Address Hans' workflow feedback - make it actionable
1. Created QUICKSTART.md (60 second read vs 1295 line handbook)
   - Who you are, 4 session-start actions, critical rules
   - All CLAUDE.md files now reference QUICKSTART first

2. Created scripts/daily-review.sh (automates Part 4 checks)
   - Runs Section A, F, G checks automatically
   - Reports PASS/FAIL with colors
   - Fails fast on foundation violations

3. Added workflow section to handbook
   - Where to find tasks (git.clavitor.ai)
   - Priority order (CRITICAL > HIGH > MEDIUM)
   - Engineer vs Reviewer responsibilities

4. Created tasks skill (.claude/skills/tasks/SKILL.md)
   - For querying Gitea issues programmatically
   - Will integrate with agent workflow

5. Updated all 11 CLAUDE.md files with concise headers
   - Quickstart link (60s)
   - Deep reference link (handbook Section V)
   - Agent identity + daily script command

Hans' feedback addressed:
-  Handbook too long → QUICKSTART.md
-  Daily review manual → automated script
-  Vague instructions → specific script + task query
-  No task queue → skill created
2026-04-09 01:10:39 -04:00
James 68dcc2f2f4 telemetry: fix Cardinal Rule violations - add unique error codes
Fixes 4 Cardinal Rule violations identified by Yurii audit:

- ERR-TELEMETRY-001/002/003: Fatal error codes for DB init, CA loading, cert verify
- ERR-TELEMETRY-010/011/012/013/014: Database error handling in updateSpan()
- ERR-TELEMETRY-020/021/022: ntfy alert error codes with context
- ERR-TELEMETRY-030/031/032/033: Kuma push error handling (was silent)

Per CLAVITOR-AGENT-HANDBOOK.md Part 1:
- Every error now has unique ERR-TELEMETRY-XXX code
- Database errors in updateSpan() no longer silent
- Kuma push failures now logged (was silent with misleading comment)
- All errors include actionable context

Assignee: Hans
Auditor: Yurii
Refs: issues/001, issues/002, issues/003, issues/004
2026-04-08 18:05:00 -04:00
James 96f98ef807 Rename mobile agent: Maya → Xiao (晓)
Xiao (Chinese: 晓) means 'dawn/morning' - fitting for mobile.
Distinct from Western names (Sarah, Charles, Maria, James, etc.).
Short, memorable outlier in the agent roster.
2026-04-08 15:30:52 -04:00
James b327d86ee9 Add Maya as dedicated mobile agent
- Added Maya to agent persona table (iOS/Android specialist)
- Updated directory mapping: clavis-android/ios → Maya
- Updated clavis-ios/CLAUDE.md → You are Maya
- Updated clavis-android/CLAUDE.md → You are Maya
- James now focused solely on browser extensions
2026-04-08 15:30:06 -04:00
James 9860a679d4 Update all CLAUDE.md files to reference CLAVITOR-AGENT-HANDBOOK.md
Updated 13 CLAUDE.md files across all subprojects:
- Root CLAUDE.md → Section I (Culture)
- clavis-vault/CLAUDE.md → Section V: clavis-vault (Sarah)
- clavis-cli/CLAUDE.md → Section V: clavis-cli (Charles)
- clavis-chrome/firefox/safari/CLAUDE.md → Section V: Browser extensions (James)
- clavis-crypto/CLAUDE.md → Section V: clavis-crypto (Maria)
- clavis-ios/android/CLAUDE.md → Section V: Mobile (James)
- clavis-telemetry/CLAUDE.md → Section V: clavis-telemetry (Hans)
- clavitor.ai/CLAUDE.md → Section V: clavitor.ai/admin (Emma)
- clavitor.ai/admin/CLAUDE.md → Section V: clavitor.ai/admin (Emma)
- clavis-vault/edition/CLAUDE.md → Section V: clavis-vault (Sarah)

All references now point to the 5-section handbook structure.
2026-04-08 15:24:51 -04:00
James 724f64bda5 Update CLAVITOR-PRINCIPLES.md with all feedback fixes
- Added document version header (F25)
- Added test fixture key material rule with 32x same byte pattern (F21)
- Added LLM-only checks, removed grep emphasis (F26)
- Fixed Section A duplication and renumbered sections
- Fixed 'entire universe' -> 'primary universe' (F28)
- Fixed key tier table formatting (F29)
- Added escalation path with permanent ban rules (F23)
- Added note about master_key/L3/P3 being exceptionally rare terms
- Added Section C for test fixture security
- Created lib/errors.go with event registry and error handling flow
2026-04-08 13:48:54 -04:00
James 659caa20b8 clavis-vault: api/lib/cmd updates + drop _old scaffolding
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 12:10:59 -04:00
James 5cf089a58e Multi-project update: import system, edition system, web UI, CLI, website, POP sync
Vault: importer refactor with mapping-driven parsers, auth.js login flow,
edition system enhancements (commercial features), agent UI fixes,
mTLS improvements, schema and handler updates.

CLI: cvt protocol updates, keystore changes, JS bridge additions.

Website (clavitor.ai): expanded main.go with new routes/templates,
admin panel with Paddle checkout and credentials API.

POP sync: mTLS CA support, command examples.

Marketing: pricing architecture doc.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 06:40:40 -04:00
James 2410a2d128 Fix agent creation UI: scope selector + agent widget on main screen
1. Fixed 'Scoped' agent creation:
   - Scope selector now appears when 'Scoped' is selected
   - Loads available scopes from entries
   - Shows checkboxes for each scope
   - Select All/None button
   - Validates at least one scope selected

2. Fixed token display:
   - Uses result.credential (was result.token)
   - Uses result.scopes (was result.scope)

3. Added agent widget to main screen:
   - Shows active agent count
   - Click to open agent management
   - Only appears when agents exist

4. Removed Admin option from create/edit (agents can't manage agents)
2026-04-02 02:42:35 -04:00
James d3e9f89bc0 Add PUT /api/agents/{id} endpoint for updating agent WL/RL
HandleUpdateAgent allows updating:
- IP whitelist (ip_whitelist array)
- Rate limit per minute (rate_limit_minute)

Does NOT allow updating (security):
- Admin status (intentionally omitted)
- All_access flag
- Scopes

Requires admin token (PRF tap) since it's a sensitive operation.
This enables the Edit Agent GUI in agents.html to save changes.
2026-04-02 02:14:00 -04:00
James c4350a614e Add GUI for editing Agent WL (IP Whitelist) and RL (Rate Limit)
- Added Edit modal for existing agents
- Can modify IP whitelist (comma-separated, supports CIDR/FQDN)
- Can modify rate limits (per minute and per hour)
- Shows current values in modal
- Cancel/Save workflow with toast notifications
- Click outside modal to close

The agents.html page now has full CRUD for agent settings:
- Create with WL/RL
- Edit WL/RL
- Lock/Unlock/Revoke
2026-04-02 01:22:50 -04:00
James a2cfff8ec2 Complete replication implementation with L0/L1 auth (Commercial Only)
Replication now fully functional for Commercial Edition:

Authentication:
- Uses existing vault L0/L1 credentials (same as vault access)
- L0 in X-Clavitor-L0 header (vault ID)
- L1 in X-Clavitor-L1 header (vault encryption key)
- Validated by opening vault DB with L1
- Anti-replay: 5-minute timestamp window

Architecture:
- Primary-only POPs: No config file needed
- Replication POPs (Calgary/Zurich): Config in /etc/clavitor/replication.yaml
- Config has replication.peers list (can be empty for primary-only)
- Event-driven: SignalReplication() on every write

Files added:
- api/replication.go: HTTP handler for incoming replication
- api/routes_commercial.go: Commercial-only route registration
- api/routes_community.go: Community stub
- lib/auth.go: ValidateL0L1() for vault credential validation
- lib/base64.go: Base64URLEncode/Base64URLDecode helpers

Files modified:
- edition/config.go: New config structure with peers list
- edition/edition.go: ReplicationConfig struct with peers
- edition/replication.go: Replicate to all peers, use new config
- edition/backup_mode.go: Removed env var, config-based
- cmd/clavitor/main.go: Load config, nil config = primary-only
- api/routes.go: Call registerCommercialRoutes()

Security:
- L0/L1 auth prevents unauthorized replication
- Timestamp window prevents replay attacks
- Audit alerts on auth failures and rejections
2026-04-02 01:21:20 -04:00
James fa7541bd4d Security review: Replication functionality (Commercial Only)
Comprehensive security audit of event-driven replication.

CRITICAL issues (5):
1. Inter-POP authentication not implemented (stub TODO)
2. Backup-side request authentication missing
3. Backup mode uses env var (should be config-only)
4. No replay attack protection (need nonces + signatures)
5. Weak token validation (only checks existence, not entropy)

HIGH issues (4):
6. HTTPS cert validation concern
7. No audit logging of replication attempts
8. Cascade replication not prevented
9. Information disclosure in error messages

Status: NOT PRODUCTION READY - security TODO stubs present
2026-04-02 01:02:36 -04:00
James 16045d5185 Mandatory config file for commercial replication (no env vars)
Replication is mandatory in Commercial Edition, configured via
/etc/clavitor/replication.yaml (not env vars or CLI flags).

Changes:
- edition/config.go: LoadReplicationConfig() for commercial - validates YAML
- edition/config_community.go: Community stub returning error
- edition/edition.go: Shared ReplicationConfig type with nested structure
- edition/replication.go: Use new nested config (BackupPOP.URL, etc.)
- edition/backup_mode.go: Fix X-Primary-Location header (TODO: add primary_pop to config)
- cmd/clavitor/main.go: Remove replication-* flags, load from /etc/clavitor/replication.yaml
- go.mod/go.sum: Add gopkg.in/yaml.v3 dependency

Config structure:
pop_id: calgary-01
region: north-america
role: primary  # or backup
backup_pop:
  id: zurich-01
  url: https://zurich-01.clavitor.ai
  auth_token_file: /etc/clavitor/replication.key
auth:
  token_file: /etc/clavitor/replication.key

Validation:
- pop_id, region, role are required
- primary role requires backup_pop.id and backup_pop.url
- backup role should NOT have backup_pop configured
- Auth token file must exist

Startup behavior:
- Commercial without config: vault refuses to start
- Community: ignores replication, single-node only

Documentation:
- SPEC-replication-config.md: Full config file design
2026-04-02 00:56:30 -04:00
James 00b7105e18 Event-driven async replication (Commercial Only)
Replaces wasteful 30s polling with event-driven design:
- No polling - worker sleeps until woken by SignalReplication()
- Replication triggers immediately on write operations
- Perfect for low-change vaults (could be days without writes)

Changes:
- edition/replication.go: Event-driven worker with channel signaling
- edition/edition.go: Add SignalReplication var
- edition/community.go: No-op SignalReplication stub
- edition/commercial.go: Wire up signalReplication

Architecture:
1. Write handler marks entry dirty (replication_dirty = 1)
2. Calls edition.SignalReplication() (non-blocking)
3. Worker wakes, batches ALL dirty entries
4. POSTs to backup POP
5. Clears dirty flags on success
6. Worker sleeps until next signal

Retry logic:
- Exponential backoff: 1s, 5s, 25s, 125s...
- Max 5 retries, then operator alert
- Dirty entries persist in DB until replicated

Resource efficiency:
- CPU: Only wakes on actual writes (not 2,880x/day polling)
- Network: Only sends when data changes
- For 10 writes/day: ~288x fewer wakeups than polling

Documentation:
- SPEC-replication-async.md: Full event-driven design spec
2026-04-02 00:51:51 -04:00
James 7fca22b130 Replication v2: Active-Passive with Async Sync (Commercial Only)
Implements Johan's design:
- Primary POP (e.g., Calgary) replicates writes to Backup POP (e.g., Zurich)
- Backup serves READ-ONLY traffic when primary fails
- Same wire format preserved for replication
- Async, non-blocking replication with queue + retry

Database Schema:
- Added replication_dirty BOOLEAN column to entries table
- Index idx_entries_dirty for fast dirty entry lookup
- EntryMarkDirty() - mark entry needing replication
- EntryMarkReplicated() - clear dirty flag on ACK
- EntryListDirty() - get pending entries (fast path)

Commercial-Only Files:
- edition/replication.go - core replication queue/worker
- edition/backup_mode.go - backup mode detection, write rejection
- edition/commercial.go - wire up IsBackupMode, IsBackupRequest

Backup Mode:
- CLAVITOR_BACKUP_MODE env var sets backup mode
- BackupModeMiddleware rejects writes with 503
- X-Primary-Location header tells client where primary is
- IsBackupMode() and IsBackupRequest() edition functions

Community:
- No replication functionality (privacy-first, single-node)
- IsBackupMode() always returns false
- StartReplication() is no-op

Documentation:
- SPEC-replication.md - full design specification
2026-04-02 00:50:20 -04:00
James 53b2770465 Commercial-only replication infrastructure
Replication is a COMMERCIAL-ONLY feature:
- Community Edition: No replication functionality (privacy-first, single-node)
- Commercial Edition: Real-time sync to backup POPs (Calgary/Zurich)

Changes:
- edition/replication.go: Commercial-only replication implementation stub
- edition/edition.go: Add ReplicationConfig and StartReplication stub
- edition/commercial.go: Wire up replication, use globalConfig
- edition/community.go: No-op StartReplication stub
- edition/CLAUDE.md: Document replication as commercial-only
- cmd/clavitor/main.go: Add replication flags (replication-*)
  - replication-primary, replication-backup, replication-token
  - Warning if used in Community Edition

Security:
- Replication requires inter-POP auth token
- 30-second poll interval, batch up to 100 entries
- Automatic retry with backoff

Note: Full implementation TBD - this is the infrastructure scaffolding.
The actual replicationBatch() logic needs to be implemented for production.
2026-04-02 00:42:40 -04:00
James 48bf5d8aa0 Security hardening v2: Edition system + 24 security fixes
EDITION SYSTEM (Community/Commercial):
- Add edition/ package with build-time separation
- Community: No telemetry, local logging only, AGPL
- Commercial: Centralized alerting to clavitor.ai, managed POPs
- Build: go build ./cmd/clavitor/ (community) or -tags commercial

SECURITY FIXES (Issues 1-24):
1. L3 field protection in batch import - agents can't overwrite tier 3
2. FQDN lookup caching - 5min TTL prevents DNS DoS
3. IP whitelist race documented and accepted
4. Admin token consumption - accepted UX limitation
5. Type guard now returns 403 (not silent skip)
6. Agents blocked entirely from batch import
7. IP whitelist DB errors return 500 + telemetry
8. L3 protection in upsert
9. DeleteEntry scope check added
10. CreateEntry scope validation for agents
11. SearchEntries audit logging
13. CSP tightened - removed unused tailwind, img-src restricted
15. Backup path validation (isValidVaultName)
17. Request body size limit - 64KB max, binary content blocked
18. WebAuthn auth challenge verification
19. RestoreBackup requires admin auth
20. TOTP scope check (already existed)
21. PRF-only enforcement (no non-PRF fallbacks)
22. Empty scopes documented as quarantine feature
23. Scope format validation with operator alerts
24. DB errors surfaced via edition.AlertOperator()

OPERATOR ALERTS:
- edition.Current.AlertOperator() routes to local logs (community)
- or POSTs to /v1/alerts (commercial)
- Alerts: auth_system_error, data_corruption

NEW DOCUMENTATION:
- edition/CLAUDE.md - full edition system docs
- GIT_WORKFLOW.md - Zurich-only Git policy
2026-04-02 00:36:31 -04:00
James 230acd394e feat: vault v2 rewrite — CVT tokens, scoped access, agents-as-entries, 14 importers
Complete vault rewrite with correct foundation:

- CVT encrypted envelope tokens (type 0x00 wire, type 0x01 client credential)
- Agents and scopes stored as L1-encrypted entries (no separate tables)
- Scope-based access control with AgentCanAccess() set intersection
- Owner-only admin enforcement (agents cannot manage agents/scopes)
- 14 password manager importers (Proton, Bitwarden, 1Password, LastPass,
  Dashlane, KeePass, KeePassXC, NordPass, Keeper, RoboForm, Enpass,
  Safari/iCloud, Chrome, Firefox)
- FIELD_SPEC single source of truth for field kind and tier
- L2/L3 client-side encryption on import (PRF required)
- Domain classification service on clavitor.ai/classify
- Scope auto-assignment during import (13 categories)
- Light theme default (Figtree font, matching clavitor.ai branding)
- Unified page shell across all screens (topbar on every page)
- Batch import with progress indicator
- ZIP extraction for Proton Pass exports
- Proton dedup by title+user+url
- 55 tests passing (26 API + 29 lib)
- Key leak detection tests (L1/L2/L3 never in responses)
- CLI updated for CVT token format
- Old code archived in _old/

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-31 13:36:04 -04:00
James dcdca016db feat: add MITM proxy mode with LLM policy evaluation (C-017)
- New package clavis/clavis-vault/proxy/
  - HTTPS MITM proxy via HTTP CONNECT tunnel
  - Dynamic per-host TLS cert generation (signed by local CA)
  - CA cert auto-generated at DataDir/proxy/ca.crt (1-year validity)
  - Per-cert cache with 24h TTL
  - Credential injection hook (stub — DB wiring next)
  - LLM policy evaluation hook (stub — OpenAI-compatible API)
  - L2 (identity/card) fields are never injectable by design

- cmd/clavitor/main.go: new flags
  --proxy            Enable proxy mode (default: off)
  --proxy-addr       Listen addr (default: 127.0.0.1:19840)
  --proxy-llm        Enable LLM policy evaluation
  --proxy-llm-url    LLM base URL (OpenAI-compat)
  --proxy-llm-key    LLM API key
  --proxy-llm-model  LLM model name

Usage:
  clavitor --proxy
  export HTTP_PROXY=http://127.0.0.1:19840 HTTPS_PROXY=http://127.0.0.1:19840
  # Install DataDir/proxy/ca.crt in OS trust store for HTTPS MITM
2026-03-29 08:54:51 -04:00
James f5f852fe40 rebrand: rename vault1984 references to clavitor in Makefile and pop-sync (C-005) 2026-03-29 07:16:12 -04:00
James 472e9dc07b chore: auto-commit uncommitted changes 2026-03-29 06:01:26 -04:00
James f9e2a3bdf1 seo: enhanced sitemap.xml with lastmod/priority/changefreq, added Open Graph meta tags, added JSON-LD structured data (WebSite, Organization, SoftwareApplication schemas), improved robots.txt 2026-03-29 02:24:59 -04:00
James 35c9e106b5 chore: auto-commit uncommitted changes 2026-03-28 06:01:23 -04:00
James fc9f49bf18 chore: auto-commit uncommitted changes 2026-03-27 06:03:32 -04:00
James 27c26c03b3 chore: auto-commit uncommitted changes 2026-03-26 18:03:10 -04:00
James 14b6079a61 chore: auto-commit uncommitted changes 2026-03-26 12:01:24 -04:00
James 0922dde30a chore: auto-commit uncommitted changes 2026-03-26 06:03:15 -04:00
James cb7c7c51ce chore: auto-commit uncommitted changes 2026-03-26 00:01:24 -04:00
James 55699985ae chore: auto-commit uncommitted changes 2026-03-25 06:04:04 -04:00