Security Architecture
b1e55ed security model: minimize trust, maximize auditability.Core Principles
- Event-sourced integrity - Hash chain commits to full event record
- Secure by default - Refuse to start in insecure configuration
- Encrypted at rest - Identity keys encrypted with master password
- Consistent identity - Single signing key across all operations
- Audit trail - Every event signed and traceable
Event Hash Chain
What It Does
Every event appended tobrain.db includes a cryptographic hash that commits to:
- Previous event hash (chain linkage)
- Timestamp (prevents backdating)
- Event ID (prevents duplication)
- Event type (prevents type confusion)
- Schema version (prevents downgrade attacks)
- Source, trace ID, dedupe key (metadata integrity)
- Payload (content integrity)
Implementation
Hash computation (engine/core/models.py):
engine/core/database.py):
Security Guarantees
✅ Tamper-evident: Can’t modify any field without breaking chain✅ Append-only: Can’t reorder or delete events without detection
✅ Timestamped: Can’t backdate events
✅ Traceable: Every event links to previous ❌ Not encrypted: Events are plaintext (encrypted at rest via filesystem/disk encryption)
❌ Not distributed: Single SQLite file (backup/replication is operator responsibility)
API Security
Secure by Default
API refuses to start ifauth_token is empty (unless B1E55ED_INSECURE_OK=1 override).
Why: Prevents accidental deployment without authentication.
Error message:
CORS Configuration
Before (insecure):allow_origins=["*"] + allow_credentials=True allows any site to make authenticated requests to your API.
Authentication
Bearer token required for protected endpoints:POST /brain/run- Trigger manual cycleGET /positions- View open positions- All karma endpoints
GET /health- System statusGET /signals- Recent signals (read-only)
Rate Limiting
Default: 100 requests/minute per IP (not yet implemented, placeholder for v1.0.0)Identity & Signing
Node Identity
Every b1e55ed instance has a persistent Ed25519 identity:- Node ID:
b1e55ed-<hex> - Public key: Ed25519 public key (hex)
- Private key: Ed25519 private key (encrypted at rest)
~/.b1e55ed/identity.key
Encryption at Rest
With master password (production):B1E55ED_MASTER_PASSWORD- Encrypt identity (required for production)B1E55ED_DEV_MODE=1- Allow plaintext (dev/test only)
Identity Consistency
Before (broken audit trail):- CLI: Persisted identity (
~/.b1e55ed/identity.key) - API: Ephemeral identity (new key per request)
- Result: Events signed by different keys, no accountability
- Both CLI and API: Same persisted identity via
ensure_identity() - All events signed by same key
- Audit trail traceable to single node_id
Signing Flow
Secret Management
Storage Tiers
Tier 0: Environment Variables- Read from
os.environ - No persistence
- Secure: Yes (process-isolated)
- File:
~/.b1e55ed/keystore.vault - Encryption: Fernet (AES-128-CBC + HMAC-SHA256)
- Password:
B1E55ED_MASTER_PASSWORD
- Platform-specific (Keychain on macOS, Secret Service on Linux, etc.)
- Not yet implemented
Keystore Usage
Save secret:- Environment variable (if set)
- Vault (if exists)
- OS keyring (future)
- Raise error if not found
Best Practices
✅ Do:- Store API keys in vault or environment
- Use
B1E55ED_MASTER_PASSWORDin production - Rotate secrets regularly
- Use
.envfiles locally (gitignored)
- Hardcode secrets in code
- Commit secrets to git
- Store plaintext secrets in config files
- Share master password in chat/email
Redaction & Logging
Automatic Redaction
Before logging:- API keys (pattern:
sk-,xai-, etc.) - Bearer tokens
- Private keys
- Passwords
- Auth headers
***REDACTED***
Audit Logging
Audit events (engine.security.audit.AuditLogger):
brain.db events table with type system.audit.v1
Use cases:
- Track who accessed what
- Detect anomalous access patterns
- Compliance/forensics
Kill Switch
Purpose
Emergency shutdown when system detects:- Unusual trading activity
- Large unexpected losses
- Policy violations
- External threats
Levels
| Level | State | Action |
|---|---|---|
| 0 | Normal | No restrictions |
| 1 | Caution | Log warnings, continue |
| 2 | Crisis | Block new trades, allow exits |
| 3 | Lockdown | Block all trades, manual intervention required |
Monotonic Escalation
Rule: Kill switch can only escalate, never auto-de-escalate. Why: Prevents “recovered for 30 seconds” from re-arming risk before operator reviews. Manual reset:Events
Escalation:DCG (Don’t Cross the Guys)
Purpose
Blacklist for symbols that should never be traded (regulatory, reputational, or strategic reasons).Configuration
Events
Threat Model
What We Protect Against
✅ Insider threat: Audit trail tracks all actions✅ Configuration errors: Secure-by-default prevents accidental exposure
✅ Tampering: Hash chain detects modified events
✅ Unauthorized API access: Bearer token required
✅ Secret leakage: Encrypted storage + redaction
What We Don’t Protect Against
❌ Physical access: If attacker has filesystem access, they can readbrain.db❌ Memory dumping: Private keys exist in memory during operation
❌ Side-channel attacks: No constant-time crypto (relies on cryptography library)
❌ DoS: No rate limiting yet (v1.0.0 roadmap item)
❌ MITM: API is HTTP by default (use nginx with TLS in production)
Deployment Recommendations
For production:- Set
B1E55ED_MASTER_PASSWORD(encrypt identity + vault) - Set
B1E55ED_API__AUTH_TOKEN(strong random token, 32+ chars) - Configure
api.cors_origins(explicit allow list) - Run API behind nginx with TLS
- Use filesystem encryption (LUKS, FileVault, etc.)
- Backup
brain.dbregularly (encrypted backups) - Rotate secrets every 90 days
- Monitor audit logs for anomalies
- Set
B1E55ED_DEV_MODE=1(allow plaintext identity) - Set
B1E55ED_INSECURE_OK=1(allow API without auth) - Never use dev mode in production
Security Checklist
Before deploying:-
B1E55ED_MASTER_PASSWORDset (not empty) -
B1E55ED_API__AUTH_TOKENset (32+ chars, random) -
api.cors_originsconfigured (not empty, explicit) -
B1E55ED_DEV_MODEnot set (or set to 0) - TLS enabled (nginx or similar)
- Filesystem encryption enabled
- Backup strategy defined
- Secret rotation policy defined
- Audit log monitoring enabled
- Review audit logs weekly
- Rotate secrets every 90 days
- Backup
brain.dbdaily - Test backup restore monthly
- Update dependencies monthly
- Review kill switch events
- Activate kill switch (level 2 or 3)
- Review audit logs for unauthorized access
- Verify hash chain integrity (
db.verify_hash_chain()) - Rotate compromised secrets
- Review and patch vulnerability
- Document incident in audit log
- Reset kill switch after resolution
Compliance
GDPR considerations:- Events may contain user data (if trading on behalf of users)
- Implement right-to-erasure (delete user events, but preserve hash chain)
- Log data retention policy (default: indefinite, configure per jurisdiction)
- Audit trail (events table)
- Access control (API auth)
- Encryption at rest (master password + filesystem)
- Change management (git commits + event log)
- Not applicable (no credit card processing)
- If added: never store CC numbers in events
Vulnerability Disclosure
Found a security issue?- Don’t open a public GitHub issue
- Do email security contact (define in SECURITY.md)
- Include:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (optional)
- Acknowledgment: 48 hours
- Initial assessment: 7 days
- Fix deployed: 30 days (critical), 90 days (non-critical)
- Public disclosure: After fix deployed + 14 days
References
Last updated: 2026-02-20 (C1: crypto primitive unification)
Crypto primitives reference: See crypto-primitives.md for the single source of truth on all cryptographic choices, migration plan, and threat model.