Epic: Secure secret delivery to provisioned containers #129
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The Cameleer3 server orchestrates Docker containers for customer apps (SaaS mode). Currently, all secrets are passed as plaintext environment variables —
customEnvVarsstored as unencrypted JSONB in PostgreSQL, passed to the Docker API asKEY=VALUEstrings viaDeploymentExecutor.buildEnvVars().Current Flow
Exposure Points
container_configandresolved_configJSONB columns store secrets unencrypteddocker inspect <container>shows all env vars in plaintextGET /api/v1/apps/{slug}returnscontainerConfigwithcustomEnvVarsunmaskeddeployments.resolved_configpersists a copy of all resolved config including secretsCAMELEER_AGENT_AUTH_TOKENacross all containersTarget Platforms
Scope
Evaluate and select the most secure, practical approach for delivering secrets to provisioned containers across all three platforms. Each option is tracked as a separate issue with detailed research.
Options Evaluated
createContainerCmd; K8s good as Phase 2Recommended Strategy
Layer 1 — Encryption at rest (#131): Implement first
Encrypt
customEnvVarsvalues in PostgreSQL with AES-256-GCM (Google Tink). Independent encryption key. Protects against DB dumps, backups, SQL injection. Satisfies SOC2/GDPR. 2-3 days effort.Layer 2 — Bootstrap callback (#135): Primary delivery mechanism
One-time token per container, agent fetches secrets via HTTP at startup. Eliminates docker inspect exposure, adds tamper detection and audit trail. OWASP ranks this as "best" delivery approach. 3-4 days effort.
Layer 3 (future) — Platform-native enhancement (#130 K8s part)
When on K8s, use native Secrets with volume mounts via fabric8 client. Forward-compatible with the callback pattern.
Layer 4 (if needed) — External vault (#132)
If dynamic credentials or enterprise-grade audit becomes necessary, deploy Infisical (low ops burden) or OpenBao (Vault-grade power, true open source).
Complementary Improvements (regardless of chosen option)
customEnvVarsat rest in PostgreSQL (AES-256-GCM)resolved_configJSONB on deployment records*_SECRET,*_PASSWORD,*_TOKEN,*_KEYfrom API responses and logsDecision Criteria
Affected Code
DeploymentExecutor.buildEnvVars()— env var assemblyDockerRuntimeOrchestrator.startContainer()— Docker API callConfigMerger.resolve()— 3-layer config mergeContainerRequest/ResolvedContainerConfig— data recordsPostgresAppRepository/PostgresEnvironmentRepository— JSONB storageAppController/EnvironmentAdminController— API endpointsContainerLogForwarder— log streaming without redaction