Skip to main content

Security Overview

CoreCube handles organizational knowledge including sensitive documents, credentials, and audit trails. Security is not a feature — it is a prerequisite.

Principles

  1. Defense in depth — No single control is trusted alone. Authentication, authorization, encryption, input validation, and output encoding each operate independently.
  2. Least privilege — Users, API keys, and connectors receive the minimum access required. Default permissions are restrictive.
  3. Fail secure — On error, deny access. A failed scope lookup denies retrieval. A user with no scope assignments accesses zero knowledge.
  4. Auditability — Every security-relevant action is logged: authentication, authorization decisions, credential access, and configuration changes.
  5. No security by obscurity — The CE codebase is open (AGPL-3.0). Security relies on cryptographic primitives and sound design.

Authentication

ControlSpecification
Password hashingbcrypt via Bun.password (cost factor 10)
Password policyMinimum 12 characters. Requires uppercase, lowercase, digit, special character
Brute-force protection5 login attempts/min per IP. Account lockout after 10 consecutive failures (15 min)
Session storageServer-side in SQLite sessions table. Session ID is 256-bit cryptographically random
Session cookiehttpOnly: true, secure: true (production), SameSite: Lax
Session lifetimeConfigurable (default: 7 days). Sliding expiry — refreshed on each request
Session invalidationAll sessions invalidated on password change or role change
Max concurrent sessions10 per user. Oldest evicted when limit is exceeded

Headless API — API key authentication

ControlSpecification
Key formatcc_ prefix + 32 bytes of cryptographic randomness (base62-encoded)
Key storageSHA-256 hash stored. Raw key is never stored, shown only once at creation
Key lookupConstant-time comparison (crypto.timingSafeEqual) to prevent timing attacks
Key expirationOptional expires_at. Expired keys return 401 immediately
Key revocationSetting is_active = 0 immediately invalidates the key

Authorization

Role-based access control (RBAC)

RoleAdmin ConsoleHeadless APIAdmin operations
AdminFull accessVia API keyFull
EditorConnections, knowledge, searchVia API keyNo users or settings
ViewerRead-onlyVia API keyNone
External ClientNoneScoped via API keyNone

Two-dimensional access control

Every connection has a security label = compartment + sensitivity level:

Connection: "Confluence — HR Policies"
Compartment: hr
Sensitivity level: confidential
Security label: hr/confidential

A knowledge scope defines which compartments and maximum sensitivity a user or API key can access:

Scope: "HR Team"
Allowed compartments: [hr, all-staff]
Max sensitivity level: confidential
→ Can access: hr/public, hr/internal, hr/confidential, all-staff/*
→ Cannot access: hr/restricted, finance/*, engineering/*

Access to a chunk requires that the chunk's connection matches both:

  1. Connection's compartment is in the scope's allowed compartments
  2. Connection's sensitivity level is at or below the scope's max sensitivity level

Three-layer enforcement

A failure in any single layer does not compromise data isolation:

Layer 1 — Application-level scope resolution

  • API key → scope → allowed compartments + max sensitivity → allowed connection IDs
  • Evaluated on every request. Scope changes take effect immediately — no caching.

Layer 2 — PostgreSQL Row-Level Security (RLS)

  • RLS policies on documents and evidence_chunks filter by connection_id
  • Every query session sets corecube.allowed_connections before executing search
  • The database rejects unauthorized rows even if application code has a bug
  • RLS cannot be bypassed by SQL injection — enforced by the PostgreSQL engine

Layer 3 — Audit verification

  • Every query logs the compartments and sensitivity levels of accessed sources
  • Periodic automated audit checks verify no query accessed data outside its authorized compartments

Encryption

Credentials at rest

PropertySpecification
AlgorithmAES-256-GCM (authenticated encryption)
Key256-bit key from ENCRYPTION_KEY env var or DATA_DIR/encryption.key
IVUnique 96-bit random IV per encryption operation
Authentication tag128-bit GCM tag
Encrypted fieldsconnections.credentials, connections.webhook_secret, llm_providers.api_key

Data in transit

  • HTTPS required in production for all endpoints
  • PostgreSQL: sslmode=require enforced in production
  • TLS 1.2 minimum, TLS 1.3 preferred

HTTP security headers

All responses include:

HeaderValue
Strict-Transport-Securitymax-age=31536000; includeSubDomains
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
Referrer-Policystrict-origin-when-cross-origin
Permissions-Policycamera=(), microphone=(), geolocation=()
Content-Security-Policydefault-src 'self'; script-src 'self'; ...
Cache-Controlno-store (API responses)

CSRF protection

Admin routes use the double-submit cookie pattern:

  1. Server generates a cryptographically random CSRF token on login, stored in a csrf cookie (SameSite: Strict, httpOnly: false)
  2. Admin UI includes the token in X-CSRF-Token header on every state-changing request
  3. Server validates header value against cookie value. Mismatch → 403

The headless API and MCP endpoint are not affected — they use bearer token authentication, not cookies.


Audit trail

Every security-relevant event is logged:

EventWhat is logged
Login / logoutUser ID, IP, user agent
Failed loginEmail, IP, failure reason
Account lockoutEmail, IP, lockout duration
API key creation/revocationKey ID, prefix, scope, acting admin
User creation/modificationTarget user ID, fields changed, acting admin
Role changeOld role, new role, acting admin
Scope changeConnections added/removed, acting admin
Settings changeSetting key, old/new value (secrets redacted)
Rate limit triggeredIP or key ID, endpoint
Webhook rejectionConnection ID, IP, rejection reason

Audit logs are append-only with configurable retention (default: 90 days). Navigate to Admin Console → Audit Log to search and export.


Scope audit view

Navigate to Admin Console → Scopes → Audit View to answer "Who can see what?"

User/KeyScopeCompartmentsMax LevelDocuments
OpenWebUI (cc_a1b2..)all-staffall-staff, engineeringinternal3,204
Finance Bot (cc_c3d4..)finance-teamfinance, all-staffconfidential892
Exec Assistant (cc_e5f6..)execexecutive, all-staffrestricted1,156

We use cookies for analytics to improve our website. More information in our Privacy Policy.