Skip to content

Security: asq-sheriff/embediq

Security

SECURITY.md

Security Policy

Reporting a Vulnerability

Please report security vulnerabilities privately rather than filing a public GitHub issue. Email the Praglogic security team at aejaz.sheriff@pragmaticlogic.ai with the following, if known:

  • A description of the issue and its impact.
  • Steps to reproduce, or a proof-of-concept.
  • The affected version (package.json version field).
  • Any mitigating factors you are aware of.

We aim to acknowledge reports within two business days and to publish a coordinated fix with credit (unless you request anonymity) within a reasonable window agreed with the reporter.

Supported versions

Security fixes are issued against the most recent minor release. Older minors are supported for 90 days after a new minor ships.

Version Supported
4.0.x
3.7.x ✅ (until 2026-08-25)
3.6.x ✅ (until 2026-07-21)
≤ 3.5.x

Security model at a glance

EmbedIQ is a local, deterministic configuration generator. Its security posture leans on three load-bearing design properties:

  1. Zero-persistence by default. The wizard runs entirely in-process; answers live in volatile memory unless the operator opts in to a server-side session backend. No database, no telemetry, no external service calls.
  2. No LLM dependency in the hot path. All output is produced by pure TypeScript generators. No network requests, no vector databases, no prompt-injection surface. /init-style LLM-powered alternatives cannot offer the same audit guarantees.
  3. Air-gap compatible. The CLI runs offline end-to-end. The web server also runs offline; the only outbound traffic is optional and opt-in (OpenTelemetry export, git PR integration, outbound webhooks).

Threat model & mitigations

Threat Mitigation
Sensitive data leaked into generated config (PHI, PCI, secrets) HooksGenerator emits Python DLP scanners that run before every Claude Code tool call. Patterns come from the domain pack (e.g. MRN / ICD-10 / FHIR for healthcare, PAN / CVV / ABA for finance). Validator rejects generated output missing the expected DLP patterns for the active compliance framework.
Unauthorized access to the web wizard Pluggable auth via EMBEDIQ_AUTH_STRATEGY (Basic, OIDC, reverse-proxy header, demo). Three-tier RBAC: wizard-viewer < wizard-userwizard-contributor < wizard-admin (legacy wizard-user preserved as a contributor-tier alias). Generation, session list, and session dump endpoints require wizard-admin. The demo strategy is admin/user persona-switching for demo recordings — permissive at the middleware level, never for production.
Session hijack Server-side sessions are optional. When enabled, each session is bound to the authenticated user (when auth is on) or to a signed HTTP-only cookie token (embediq_session_owner, HMAC-signed with EMBEDIQ_SESSION_COOKIE_SECRET). Mismatched owners return 403. Optional AES-256-GCM payload encryption via EMBEDIQ_SESSION_DATA_KEY.
Forged answer attribution SerializedAnswer.contributedBy is stamped server-side from the request context on every PATCH /api/sessions/:id. Any contributedBy value in the request body is stripped. Compliance reviewers can prove who provided each answer.
Forged autopilot webhook Autopilot and compliance webhooks optionally require a shared secret via EMBEDIQ_AUTOPILOT_WEBHOOK_SECRET, validated against the X-EmbedIQ-Autopilot-Secret header.
Malicious external domain pack / skill External packs and skills are loaded from user-configured directories (EMBEDIQ_PLUGINS_DIR, EMBEDIQ_SKILLS_DIR). Operators should treat these the same way they treat any node_modules dependency: audit before enabling. EmbedIQ never auto-downloads either.
Destructive shell execution via hooks The built-in command-guard.py hook blocks destructive verbs (rm -rf, git push --force, git reset --hard) unless the user confirms. Strict/lockdown permission tiers add denies for entire tool categories.
Output drift silently corrupting production npm run drift compares a project against expected output. CI can fail builds on detected drift (exit code 1). Autopilot runs the same check on a schedule and records every outcome.
Leaking strategic / internal content to the public surface Every markdown file declares an audience directive (`<!-- audience: public
Supply-chain tampering in generated files Each generated file carries a stamp (`Generated by EmbedIQ v

Data handling

What EmbedIQ does store (only when opted in)

Surface Enable via What lands on disk
Wizard audit trail EMBEDIQ_AUDIT_LOG=/path/to/log.jsonl JSONL: eventType, timestamp, userId?, requestId?, profileSummary?, validationPassed?, fileCount?. No answers, no generated file content.
Server-side sessions EMBEDIQ_SESSION_BACKEND=json-file or database WizardSession records (answers + phase + contributors) under EMBEDIQ_SESSION_DIR (json-file) or at EMBEDIQ_SESSION_DB_URL (database + sqlite driver). AES-256-GCM optional via EMBEDIQ_SESSION_DATA_KEY.
Autopilot schedules + runs EMBEDIQ_AUTOPILOT_ENABLED=true Schedule definitions + the last 500 run records under EMBEDIQ_AUTOPILOT_DIR (default .embediq/autopilot/).
OpenTelemetry traces + metrics EMBEDIQ_OTEL_ENABLED=true Exported via OTLP HTTP to OTEL_EXPORTER_OTLP_ENDPOINT. Traces contain request IDs and user IDs; no question answers.

What EmbedIQ never stores

  • Answer values never leave the process unless a session backend is enabled.
  • No LLM prompts or completions (there are no LLM calls).
  • No telemetry to Praglogic — the project has no phone-home.

Generated files

Output files land in the user-supplied targetDir. EmbedIQ writes only to the managed subtrees listed in docs/reference/generated-files.md; files outside those paths are never touched.

Compliance framework coverage

Built-in domain packs configure enforcement for the frameworks below. See docs/user-guide/04-domain-packs.md for what each pack configures and docs/evaluators/threat-coverage.md for our framework-by-framework coverage report.

  • Healthcare: HIPAA, HITECH, 42 CFR Part 2
  • Finance: PCI-DSS, SOX, GLBA, AML/BSA, FINRA
  • Education: FERPA, COPPA, state student-privacy laws
  • AI governance (cross-industry): NIST AI RMF 1.0, NIST AI 600-1 GenAI Profile
  • Federal (via OSCAL ingestion): NIST 800-53 Rev 5, FedRAMP Low / Moderate / High baselines

Dependency security

  • Runtime dependencies are pinned in package.json and locked in package-lock.json.
  • npm audit runs as part of the release checklist.
  • Optional dependencies (@opentelemetry/*, better-sqlite3) load via import() at runtime; EmbedIQ degrades gracefully when they are not installed.

Cryptographic primitives

  • Session payload encryption: AES-256-GCM (Node crypto standard library). Key: 32 bytes, hex-encoded (64 hex chars), supplied via EMBEDIQ_SESSION_DATA_KEY. Side-by-side key acceptance for zero-downtime rotation: set EMBEDIQ_SESSION_DATA_KEY_PREV to the prior key; reads accept both, writes use the current key (shipped v3.6.1).
  • Audit log integrity (optional): RFC-6962-pattern hash chain via EMBEDIQ_AUDIT_CHAIN_ENABLED=true. Each appended JSONL entry carries prevHash (SHA-256 of the prior entry's canonicalized content); tampering breaks the chain at the modified line. Offline verifier: make verify-audit-log INPUT=path/to/audit.jsonl (exit codes 0 / 1 / 2).
  • Owner-token cookies: HMAC-SHA-256 over a URL-safe base64 random token. Key: 32 bytes, supplied via EMBEDIQ_SESSION_COOKIE_SECRET. Both current and previous keys may be supplied (_PREV suffix) for zero-downtime rotation.
  • No bespoke crypto primitives. No custom KDFs. No rolled implementations.

There aren't any published security advisories