Security & encryption

TRACE_ENCRYPTION_KEY, tenant isolation, share links, PII masking, Layer 2 sandboxing, and Debugger access controls.

Security & encryption

Trace ingests the most sensitive artifact your QA pipeline produces: full DOM recordings, network bodies, screenshots, video, and console logs from applications that often contain PII-shaped test data. This page covers what you must configure and what Molar enforces by default.

TRACE_ENCRYPTION_KEY

Required for every Trace deployment — local, Docker, and Helm.

What it protects

The encryption key secures at-rest secrets in Trace's settings store:

  • LLM provider API keys (Anthropic BYOK aliases)
  • Integration tokens (Slack, webhook secrets)
  • Encrypted fields in local trace-db.json (standalone)

Provider credentials are stored encrypted and returned by alias only in API responses — never the raw secret.

Format and generation

RequirementValue
Length32 bytes (256 bits)
EncodingHex string (64 hex characters)

Generate:

openssl rand -hex 32
# Example: 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef

Local development

TRACE_ENCRYPTION_KEY=0123456789abcdef0123456789abcdef npm run dev

The standalone README uses a fixed dev key for smoke tests — never use that key in production.

Production

EnvironmentHow to set
Docker Composedeploy/docker-compose.trace.yml → env var
KubernetesSecret TRACE_ENCRYPTION_KEY → pod env (see Helm deployment.yaml)
CartographerPlatform secrets manager + settings sync

Stability: The key must remain stable across restarts. Rotating it invalidates stored provider credentials — plan a re-entry workflow for BYOK keys before rotation.

Startup behavior

If TRACE_ENCRYPTION_KEY is missing or wrong length, the standalone API refuses to start:

TRACE_ENCRYPTION_KEY is required and must be stable

This is intentional fail-closed behavior.


Authentication

Trace uses Molar platform authentication — the same sign-in as app.molar.it. There is no separate Trace IdP.

SurfaceAuth mechanism
Browser dashboardHttpOnly session cookies (Better Auth)
/v1/traces API (browser)dashboard API or shared-session validation to FastAPI
CI / automationOrg-scoped API keys with explicit scopes
Public share /r/{shortId}Unguessable capability URL — no session
MCP / IDEOAuth 2.1 + PKCE (mcp.molar.cloud)

Legacy Cartographer localStorage JWT is being replaced (CART-10-WEB) — do not build new integrations on it.

API key scopes (Trace)

ScopeAllows
traces:readList, detail, events, blob fetch
traces:writePin, restore, ingest
share:writeCreate org-only share links
share:publicCreate public-read links (separate scope)
replays:triggerLayer 2 enqueue
chats:writeDebugger send messages
mender:writePromote to fix

Standalone local tests use x-molar-org header for deterministic tenant scoping — not a production auth mechanism.


Tenant isolation

Prime directive: Every read and write is scoped to org_id from the authenticated principal — never from a client-supplied parameter.

Global blob store risk

Blobs are content-addressed without org prefix for dedup efficiency. SHA-256 of a known payload is computable — the hash is not a secret. Confidentiality depends entirely on the API authorization layer before minting presigned URLs.

Every GET /v1/traces/{id}/blob/{sha256} verifies:

  1. Caller's org owns a trace referencing that blob
  2. Blob SHA is in trace manifest
  3. Presigned URL TTL is short (default 3600s)

Row-level security

Postgres queries include WHERE org_id = :current_org on traces, trace_replays, trace_chats. UUID IDs alone do not grant access.


PropertyDetail
Entropy9-char base62 (~51 bits)
Default visibilityorg-only (opt-in to public-read)
Default expiry7 days (max 90)
Embed/r/{shortId}/embed — no Debugger chat

Risks: Links leak via Slack, Linear, email forwards, referrer headers. If masking missed a field, a forwarded link is a data breach with no login wall.

Mitigations:

  • Mask inputs/text by default in scenario privacy config
  • Hide Debugger + source SHA on external shares
  • Revoke: flip to org-only, delete trace, or wait for expiry
  • Audit log on every share create/revoke

MFA step-up required to create public-read links on some enterprise plans.


PII and privacy defaults

Scenario frontmatter controls capture-time redaction:

privacy:
  mask_inputs: true
  mask_text: ".pii, .email"
  block: ".secrets-panel"
  network_redact:
    - "$.user.email"
    - "$.user.phone"

Org settings → Privacy set defaults for new scenarios.

rrweb maskTextSelector, maskAllInputs, blockSelector applied at record time — redaction cannot be undone in stored blobs.


Layer 2 sandbox

Layer 2 executes customer Docker images and scenario edits — remote code execution by design.

Controls:

  • Isolated worker pool per region
  • NetworkPolicy: no cloud metadata endpoint, no lateral movement to Molar API
  • Unprivileged container user
  • Per-org concurrency and CPU/memory caps
  • Audit: triggered_by, triggered_via, timestamps
  • MFA step-up on replay trigger (enterprise)

Debugger security

RiskControl
Prompt injection from trace contentTool allowlist; no autonomous side effects
Confused deputy via user OAuthGitHub App token for source reads — not login token
Cost exhaustionPer-org monthly Debugger budget (cents)
Cross-tenant exfilObject-level auth on every tool call

Side effects (replay, Mender promote) require deterministic can() + human UI confirmation.


rrweb iframe sandbox

DOM replay runs in a sandboxed iframe:

sandbox="allow-scripts allow-same-origin"

Replayed DOM must not read parent session cookies or access org APIs.


Encryption in transit

TLS 1.2+ everywhere. Presigned S3 URLs are HTTPS-only. SSE-S3 or SSE-KMS at rest on object store (provider-dependent).


Compliance posture

StandardStatus
SOC 2 Type IITarget posture from day one
GDPR / CCPAIn scope — captured traces may contain PII
PCI-DSSOut of scope for cardholder data (Clones simulate payments)
HIPAA / BAAEnterprise annual plans — contact sales

Data export: Settings → Organization → Data & privacy. Retention: Workers & ingestion tier policies.


Audit logging

Security-relevant events emit immutable audit records:

  • Auth success/failure
  • Authorization denials
  • Share link create/revoke
  • Layer 2 trigger
  • Debugger tool calls
  • Export/download
  • Admin retention changes

On-prem: forward to your SIEM via webhook (Settings → Integrations).


Checklist

Action
Set TRACE_ENCRYPTION_KEY from openssl rand -hex 32
Store key in secrets manager — not in git
Enable privacy defaults (mask inputs, network redact)
Restrict share:public scope on CI API keys
Review public share expiry policy
Install GitHub App with minimum repo scope
Set Debugger monthly budget cap

For security reviews or compliance questionnaires, email support@molar.it.