Skip to main content

Security Hardening

Hardening checklist and guidance for production CoreCube deployments.

TLS / HTTPS

Required for production. The session cookie is only marked Secure when CoreCube is served over HTTPS. Security headers such as HSTS are not emitted by the application — set them at your TLS-terminating reverse proxy.

  • Deploy a reverse proxy (nginx, Caddy, Traefik) in front of CoreCube for TLS termination
  • Use a valid certificate (Let's Encrypt via Caddy is the simplest option)
  • Minimum TLS 1.2; prefer TLS 1.3
  • Caddy automatically manages TLS — see Reverse Proxy

Admin Console access restriction

Restrict admin console access to specific IP ranges at the reverse proxy level:

location /admin {
allow 10.0.0.0/8;
allow 192.168.0.0/16;
deny all;
proxy_pass http://localhost:7400;
}

The /v1 API and /mcp endpoints should remain accessible — they authenticate via API keys.

Encryption key management

The encryption key protects all connector credentials and LLM API keys at rest.

CoreCube reads the key from the ENCRYPTION_KEY environment variable, which must be a 64-character hex string (256 bits). If ENCRYPTION_KEY is unset, it falls back to a key file at DATA_DIR/encryption.key; if that file is also missing, it auto-generates a key and writes it there with mode 0600.

There is no ENCRYPTION_KEY_FILE

CoreCube does not expand a _FILE indirection variable. Pointing ENCRYPTION_KEY_FILE at a Docker/Kubernetes secret has no effect — the app sees no ENCRYPTION_KEY, silently auto-generates a throwaway key, and your existing credentials become permanently undecryptable on the next redeploy.

Best practices:

  • Set ENCRYPTION_KEY directly to a 64-character hex string (generate one with openssl rand -hex 32). Source it into the environment from your secret manager.
  • Alternatively, pre-create DATA_DIR/encryption.key containing the hex key with file permissions 0600 before the first start, and keep that file on the persistent data volume.
  • Back up the key separately from the data volume. Key loss makes all credentials permanently unreadable.
  • Key rotation is a manual operation (decrypt with the old key, re-encrypt with the new one). There is no built-in rotation command.
# Provide the key via the environment, sourced from your secret manager
environment:
ENCRYPTION_KEY: ${ENCRYPTION_KEY} # 64-char hex, e.g. openssl rand -hex 32

Docker security

The CoreCube image runs the server as a non-root user and uses tini for signal handling. The remaining controls below (read_only, cap_drop) are not image defaults — you supply them in your Compose file.

ControlSettingSource
UserNon-root bun user — the entrypoint runs as root only to fix /data ownership, then drops to bun via su-execImage default
Signal handlingtini as init process (ENTRYPOINT)Image default
FilesystemRead-only root filesystem (read_only: true)Operator-supplied (Compose)
CapabilitiesDrop all capabilities (cap_drop: ALL)Operator-supplied (Compose)
Data directoryExplicit writable volume for DATA_DIROperator-supplied (Compose)

Add these to your Docker Compose service:

services:
corecube:
read_only: true
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp
volumes:
- corecube-data:/data

PostgreSQL security

  • Enforce SSL: add ?sslmode=require to PGVECTOR_URL, PGVECTOR_APP_URL, and PGVECTOR_MAINTENANCE_URL.
  • Use a dedicated bootstrap/admin role for PGVECTOR_URL; do not point it at the built-in postgres superuser in production.
  • Use the restricted corecube_app role for PGVECTOR_APP_URL. Query/retrieval traffic uses this pool and is subject to RLS.
  • Use the restricted corecube_maintenance role for PGVECTOR_MAINTENANCE_URL. Background cleanup and repair jobs use this pool when they need cross-scope knowledge access.
  • Keep the bootstrap/admin, app, and maintenance pools separate so request-path traffic cannot bypass RLS policies or perform DDL.
postgresql://corecube:password@pgvector:5432/corecube?sslmode=require
postgresql://corecube_app:password@pgvector:5432/corecube?sslmode=require
postgresql://corecube_maintenance:password@pgvector:5432/corecube?sslmode=require

Network isolation

Keep PostgreSQL and CoreCube Inference on an internal Docker network — not exposed to the host:

networks:
internal:
internal: true

services:
corecube:
networks: [internal, default]
ports:
- '7400:7400' # Only CoreCube exposed

pgvector:
networks: [internal]
# No ports exposed

Default credential change

Change immediately

The default credentials (admin@example.com / changeme123) must be changed immediately after first login.

  1. Log in to the Admin Console
  2. Click your profile icon → Profile
  3. Update your email and password
  4. Navigate to Settings and update any remaining defaults

Password policy

CoreCube enforces a single rule: passwords must be at least 8 characters. No complexity requirement (uppercase, digit, or symbol) is applied. If you need stronger passwords, enforce them through your own operational policy.

API key hygiene

  • Create separate API keys per client application — do not share keys
  • Set an expiration date on keys that are used temporarily
  • Revoke keys immediately when a client is decommissioned
  • Use service keys for shared frontends (OpenWebUI) so per-user permissions apply
  • Review key usage in Admin Console → API Keys → Usage

Session management

By default a session has a 30-day absolute lifetime and a 60-minute idle timeout. Activity extends the idle window but never the absolute lifetime. For higher-security environments, shorten both:

SESSION_MAX_LIFETIME_HOURS=8
SESSION_IDLE_TIMEOUT_MINUTES=30

Changing a user's password revokes that user's other sessions. A role change revokes sessions only when the role is downgraded to no_access. Admins can revoke a user's sessions from the Admin Console.

Audit log retention

Configure audit log retention in Admin Console → Settings → Audit:

  • Default: 90 days
  • Shorter retention reduces storage but limits forensic analysis
  • Query text storage verbosity: full, truncated, or disabled (for privacy-sensitive environments)

Dependency updates

  • All dependencies are pinned to exact versions in the lockfile
  • Monitor the CoreCube GitHub releases for security updates
  • Apply updates promptly: docker compose pull && docker compose up -d

What v1 does not include

These controls are planned for future releases or EE:

ControlStatus
Backup encryption (AES-256-GCM)Planned (Phase 6)
IP allowlists for admin/APIPlanned
Multi-factor authenticationPlanned (EE)
HSM key storagePlanned (EE)
Cryptographic audit log chainingPlanned (EE)

Until backup encryption is available, store pg_dump backups on encrypted media.

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