Skip to content

Latest commit

 

History

History
484 lines (362 loc) · 64.5 KB

security.md

File metadata and controls

484 lines (362 loc) · 64.5 KB

Security Policy

Table of Contents


Reporting a Vulnerability

If you discover a security vulnerability in AIC, please report it responsibly.

GitHub Security Advisories (preferred): Report a vulnerability

Email: jatbas@gmail.com — use when GitHub is not an option.

Please include:

  • Description of the vulnerability and its potential impact
  • Steps to reproduce (or a proof-of-concept if available)
  • AIC version, Node version, OS, and editor (if relevant)
  • Any suggested mitigation or fix

Do NOT:

  • Open a public GitHub issue for security vulnerabilities
  • Share details publicly before a fix is available
  • Exploit the vulnerability beyond what is needed for a proof-of-concept

Response timeline:

  • Acknowledgment: Within 48 hours
  • Assessment: Within 5 business days
  • Fix release: Within 30 days for critical issues, 90 days for non-critical
  • Disclosure: Coordinated with the reporter. We aim to publish a security advisory within 7 days of the fix release.

Severity Classification

AIC classifies vulnerabilities using the following scheme, aligned with CVSS v3.1 severity ranges:

Severity CVSS range AIC definition Response Examples
Critical 9.0–10.0 Exploitable remotely or locally with no user interaction; leads to arbitrary code execution, full data exfiltration, or secret leakage to an external endpoint Fix within 30 days; out-of-band patch release Context Guard bypass allowing secrets to reach the model endpoint; RCE via crafted rule pack or MCP payload
High 7.0–8.9 Exploitable with minimal user interaction or requires local access; leads to partial secret exposure, prompt injection bypass, or privilege escalation within AIC Fix within 30 days Prompt injection pattern evasion that causes the model to execute attacker instructions; SQLite injection via crafted config
Medium 4.0–6.9 Requires specific conditions or user misconfiguration; leads to information disclosure, denial of service, or weakened security posture Fix within 90 days Telemetry payload containing unintended metadata; RepoMap cache poisoning via symlink; crash on malformed config
Low 0.1–3.9 Minimal impact; defense-in-depth hardening opportunity; requires unlikely conditions Fix in next scheduled release Timing side-channel in cache lookup; verbose error message revealing internal path; minor false-negative in secret scanner

When a report does not include a CVSS score, the AIC maintainers assign one during the assessment phase and share it with the reporter.

Safe Harbor

We consider security research conducted in good faith to be authorized. We will not pursue legal action against researchers who:

  • Make a good-faith effort to avoid privacy violations, data destruction, and service disruption
  • Only interact with accounts they own or with explicit permission of the account holder
  • Report vulnerabilities through the process described above
  • Allow reasonable time for a fix before any public disclosure

Scope

In scope

Component Description
@jatbas/aic The MCP server package (npm)
Context Guard All scanner implementations (secret, exclusion, prompt injection)
SQLite storage Local database schema, migrations, and data handling
Telemetry endpoint (design) Intended sink for future opt-in anonymous aggregates — not contacted by the shipped @jatbas/aic client; server-side design and ops scope
Configuration aic.config.json parsing, validation, and schema migration
Rule pack loading Built-in and project-level rule pack resolution
Published releases Any artifact published to npm (current package: @jatbas/aic)

Out of scope

Component Reason
Third-party model providers OpenAI, Anthropic, and Ollama APIs are outside AIC's control. Report issues to those providers directly.
Editor plugins / extensions Cursor, Claude Code, and other editors have their own security policies
User-authored rule packs Custom JSON files in aic-rules/ (advanced) are authored and controlled by the project owner
User-configured model endpoints Custom endpoints set via model.endpoint in config are the user's responsibility

Security Architecture

AIC is a local-first tool. All compilation processing runs on the developer's machine. No source code, prompts, or file paths are transmitted to AIC-operated telemetry or analytics endpoints from the shipped MCP package. The only fixed outbound request is an npm registry GET for version metadata (no repository content) — see Update check (version notification).

┌────────────────────────────────────────────────────────────┐
│  Developer's Machine (trust boundary)                      │
│                                                            │
│  ┌──────────┐    stdio    ┌──────────────────────┐         │
│  │  Editor  │◄───────────►│   AIC MCP Server     │         │
│  │ (Cursor, │   (local    │   ┌────────────────┐ │         │
│  │  Claude  │    IPC)     │   │ Context Guard  │ │         │
│  │  Code)   │             │   │ (filters       │ │         │
│  └──────────┘             │   │  secrets from  │ │         │
│                           │   │  compiled ctx) │ │         │
│                           │   └────────────────┘ │         │
│                           │   ┌────────────────┐ │         │
│                           │   │ SQLite (.aic/) │ │         │
│                           │   │ 0700 perms     │ │         │
│                           │   │ gitignored     │ │         │
│                           │   └────────────────┘ │         │
│                           └──────────┬───────────┘         │
│                                      │                     │
└──────────────────────────────────────┼─────────────────────┘
                                       │
              ┌────────────────────────┼────────────────────┐
              │  External (crosses trust boundary)          │
              │                                             │
              │ ┌──────────────────┐  ┌───────────────────┐ │
              │ │ Model endpoint   │  │telemetry.aic.dev  │ │
              │ │ (future executor │  │ (future outbound; │ │
              │ │  path only)      │  │  no client ships) │ │
              │ │ Guarded content  │  │ design: no paths) │ │
              │ └──────────────────┘  └───────────────────┘ │
              │                                             │
              └─────────────────────────────────────────────┘

Key trust boundaries:

Boundary What crosses it Protection
Editor ↔ AIC Intent string, compiled prompt stdio transport (local IPC, no network). Integration hooks may start a short-lived local child with argv-only execFileSync("npx", …) (no shell parsing of server paths) that runs the AIC server entrypoint; JSON-RPC on that pipe is still stdio-local (no network). See Cursor integration layer and Claude Code integration layer §4.1.
AIC → Model endpoint Compiled prompt (Guard-filtered) Only when a model adapter is configured. Context Guard excludes secrets and injections from the compiled context. aic_compile never contacts any external service.
AIC → Telemetry host Anonymous aggregate metrics (design) Shipped: no HTTP client to AIC telemetry. When implemented: opt-in only; enum/numeric payloads; TLS. See Telemetry Endpoint Threat Model and Anonymous Telemetry.

For the full architectural specification, see Project Plan §13.


Context Guard

Context Guard (pipeline Step 5) scans every selected file before it reaches the Content Transformer (Step 5.5) or the prompt assembler. It excludes secrets, credentials, excluded paths, and prompt injection patterns from the compiled context that AIC returns to the editor.

Scope of protection: Context Guard controls what AIC includes in its compiled prompt. It does not control what the model or editor does independently — models can still read files directly through editor-provided tools (including read_file and Shell). AIC's role is to ensure that bulk context injection does not carry sensitive content; direct file access is governed by the editor's own permission model (including .cursorignore).

Scanner Finding type What it detects
ExclusionScanner excluded-file File path matches a never-include pattern
SecretScanner secret File content matches a known secret regex
PromptInjectionScanner prompt-injection Instruction-override and special-token patterns on all selected non-markdown files
MarkdownInstructionScanner prompt-injection Same instruction-pattern pass, limited to .md, .mdc, .mdx
CommandInjectionScanner command-injection Shell-like patterns (command substitution, backticks, pipe chains) on non-markdown files; markdown paths are handled by MarkdownInstructionScanner, BLOCK

Never-include path patterns (always active, not overridable): .env, .env.*, *.pem, *.key, *.pfx, *.p12, *secret*, *credential*, *password*, *.cert

Secret patterns (6 regex patterns): AWS keys, GitHub tokens, Stripe keys, generic named API keys in assignment form (api_key = "..."), JWTs (eyJ...), and SSH/TLS private key headers (-----BEGIN ... PRIVATE KEY-----).

Behavior on detection:

  • A file is removed from the compiled context when any scanner reports a BLOCK severity finding on that path (exclusions, secrets, command-injection patterns, and the BLOCK-tier instruction patterns). WARN findings (some instruction-pattern matches) are logged but the file can still pass through if nothing blocks it
  • The pipeline never fails due to Guard findings — it filters and continues
  • All findings are logged in CompilationMeta.guard and visible via aic_inspect
  • If all selected files are blocked, the pipeline returns empty context with guard.passed: false

False-positive mitigation: The allow list is loaded from aic.config.json (guard.allowPatterns). Paths matching those globs skip content scanners; never-include paths (.env, *.pem, *.key, and the other globs listed under Never-include path patterns above) stay mandatory blocks and cannot be overridden. See Implementation Spec — Step 5 and Project Plan §8.4.

Full pattern tables: Project Plan §8.4.


Prompt Injection Prevention

AIC defends against prompt injection at multiple layers:

Risk Mitigation
User intent contains injection AIC treats the intent as opaque text placed inside a structured template, not interpolated into system instructions
Source code contains injection Context Guard runs instruction and command-injection scanners; BLOCK-level matches exclude the file; WARN-level instruction matches are logged but the file may remain in context
Rule pack injection Rule packs are local JSON files controlled by the developer — no remote loading in the shipped implementation
Prompt structure hardening Context is encapsulated in clearly delimited code blocks; the constraints section is always placed after context

Prompt injection pattern categories (shipped):

Category Example match Purpose
Instruction override "Ignore all previous instructions" Classic instruction-override attack
Persona hijack "You are now a helpful assistant that..." Attempts to redefine the model's role
Fake system prompt header system: you are a code reviewer Embedded system prompt in source code
Constraint override "Do not follow any other rules" Direct constraint override attempt
OpenAI chat markup <|system|>, <|im_start|> Model-specific special token injection
Llama/Mistral tokens [INST] new instructions [/INST] Instruction token injection for open-weight models

False-positive mitigation: These patterns target adversarial strings that have no legitimate reason to appear in production source code. Paths matching guard.allowPatterns in aic.config.json skip content scanners. The scanner logs the matched pattern in GuardFinding.pattern to help diagnose false positives.

Full regex patterns: Project Plan §8.4.


API Key Handling

Rule Implementation
Never store API keys in config Config references env var names (apiKeyEnv: "OPENAI_API_KEY"), never actual keys
Never log API keys All logging sanitizes env var values; keys replaced with ***
Never cache API keys Cache stores compiled prompts + metadata only; no credentials
Never include keys in telemetry No API keys in SQLite. telemetry_events aggregate columns are numeric counts; compilation_log stores intent (free text) and optional selection_trace_json (path/score metadata — not file bodies)

Data Handling

Data type Stored locally? Sent externally?
Source code Cache only under project .aic/cache/ (gitignored) Never in the current MCP-only package
Prompts / intents compilation_log.intent (global ~/.aic/aic.sqlite) Never
File paths guard_findings.file, cache_metadata.file_path, and repo-relative paths inside compilation_log.selection_trace_json (selection trace JSON) Never
API keys Never stored Not used by the current MCP-only package
Guard findings guard_findings table (SQLite) Never
Anonymous telemetry (outbound) anonymous_telemetry_log table (schema in 001-consolidated-schema.ts) No shipped writer — table reserved for a future queue. Privacy design: no code, paths, or prompts. See below.

Other local path columns: The same database also stores absolute paths in projects.project_root, repomap_cache.project_root, and transform-cache tables (file_path and similar). Same rules apply: local only, never sent to AIC servers. Baseline DDL: shared/src/storage/migrations/001-consolidated-schema.ts; later migrations (including 003-compilation-selection-trace.ts for compilation_log.selection_trace_json) live in the same directory.

External API response validation

AIC treats all data received from external endpoints as untrusted. For every outbound GET request:

  • The response is accepted only when the Content-Type header indicates JSON (application/json and compatible application/*+json values). Responses with a missing or non-JSON Content-Type are discarded without parsing.
  • Response body size is bounded (100 KB ceiling for the npm registry client) and a timeout applies. Excess or slow responses are discarded.
  • Only expected fields are read. The client uses a strict contract: it reads a fixed set of keys and ignores the rest. Invalid or missing structure yields a safe default (no update message).
  • The npm registry does not sign packument metadata; authenticity of the response is not cryptographically verified. Validation is limited to format, size, and schema.

Update check (version notification)

  • Data source: GET https://registry.npmjs.org/<package> (fixed URL).
  • Validate and bound: Timeout 2s, max response body 100 KB, version string must match semver regex and max 32 chars; invalid data yields no update.
  • Content-Type: The response is accepted only when the Content-Type header includes application/json. Other types are discarded without parsing.
  • Strict response contract: Only the dist-tags.latest field is read from the packument. Missing or invalid structure (dist-tags not an object, latest not a string) yields no update.
  • No code/prompt injection: Only fixed-format message with validated version; install link from our code only.
  • Writes only under .aic/: version-check-cache.json, update-available.txt; no user/registry input in paths.
  • No SSRF: Fixed registry URL.
  • Cache: Validate version strings when reading cache before use.
  • HTTPS only, default TLS verification.
  • No sensitive data sent to registry.

Data Leakage Prevention

Risk Mitigation
Telemetry leaks source code compilation_log / telemetry_events store metrics and local diagnostics — never selected file contents in those tables. compilation_log.intent is free text; optional selection_trace_json stores structured path/score metadata for transparency (not file bodies). Paths also appear in guard_findings, cache_metadata, repomap_cache, and other SQLite tables that store path-shaped strings. See Project Plan §9.1 and Implementation Spec — Selection trace.
Cache contains sensitive code Cache is stored in .aic/cache/ (gitignored, 0700 permissions); never uploaded; user controls TTL via config
repo_id reveals project path repo_id is a SHA-256 hash of the absolute path — irreversible, cannot be used to identify the project
Model endpoint receives code aic_compile never contacts any external service. Context Guard excludes secrets and credentials from the compiled context AIC returns to the editor.
SQLite database contains prompts MCP server uses global ~/.aic/aic.sqlite (0700 on ~/.aic/). Stores per-project compilation rows (intents, counts, tokens, optional selection-trace JSON with paths/scores). Project .aic/ holds cache and last-compiled-prompt.txt — never pushed to AIC servers.

For the full threat/mitigation analysis, see Project Plan §13 — Data Leakage Prevention.


.aic/ Directory Security

AIC uses ~/.aic/ for the global SQLite database (aic.sqlite) and <projectRoot>/.aic/ for per-project cache, compiled-prompt artifact, and related files. Both are treated as sensitive:

  • Auto-gitignored: Bootstrap appends the AIC ignore manifest (shared/src/storage/aic-ignore-entries.json, including .aic/ and related paths) to .gitignore, .eslintignore, and .prettierignore on first-time init. Project .aic/ and cache paths stay out of version control.
  • Permissions: Global ~/.aic/ is created with 0700 (owner-only). Project .aic/ is created with restricted permissions for cache writes.
  • Paths: Writes use fixed filenames under .aic/ (database, cache keys, last-compiled-prompt.txt). Do not point .aic/ at untrusted locations.
  • Symlink and path containment: Project .aic/ is resolved and contained under the project root before trusted writes (ensureAicDir / joinUnderProjectAic in shared/src/bootstrap/ensure-aic-dir.ts). Opening the global database can require the resolved aic.sqlite path to stay inside the resolved ~/.aic directory (openDatabase / openDatabaseReadOnly in shared/src/storage/open-database.ts).
  • Integration temp files: Cursor beforeSubmitPrompt and Claude Code hooks that stage prompt fragments under os.tmpdir() create new POSIX files with mode 0o600 (owner read/write only).
  • Cursor compile gate: The preToolUse compile gate is always active by default. An emergency bypass requires both "devMode": true and "skipCompileGate": true in aic.config.json (installation.md). The gate uses failClosed: true — hook crashes deny rather than allow. This bypass is local workflow configuration for emergencies only, not a substitute for Context Guard on compiled context.

Anonymous Telemetry

Shipped vs designed: The global database includes an anonymous_telemetry_log table (see shared/src/storage/migrations/001-consolidated-schema.ts). There is no shipped TypeScript code that inserts into that table or performs HTTPS POST to a telemetry host — see Implementation Spec §4d — Anonymous Telemetry. The minimal aic.config.json loader (shared/src/config/load-config-from-file.ts) does not define telemetry.anonymousUsage or related keys.

Compile telemetry (local, separate topic): On each successful aic_compile when the project is not disabled, the handler writes compilation_log and telemetry_events rows (metrics and local diagnostics). That path is not gated by a telemetry.enabled flag in the minimal loader. Details: Project Plan §9.1, Implementation Spec — Step 10.

Target behaviour (outbound anonymous aggregates — when implemented): A future client would send only enum and numeric aggregates — never file paths, file content, raw prompts, intents, project names, API keys, user identifiers, or PII. Intended payload shape and endpoint threat model remain design requirements below; they are not assertions about current binaries.

Privacy guarantees for outbound payloads (mandatory, non-negotiable — design):

Rule Enforcement (target)
No file paths Payload schema — no string fields for paths
No file content Only numeric aggregates and enum values
No prompts or intents Aggregate metrics only — not free-text intent
No project names Not included in schema
No persistent user ID Each payload independent; no session tracking
No IP logging Telemetry endpoint should not log client IPs
HTTPS only TLS for any outbound POST

Inspecting the queue table (when populated): If a future release writes rows, you would inspect anonymous_telemetry_log in ~/.aic/aic.sqlite. Today the table is typically empty:

sqlite3 ~/.aic/aic.sqlite "SELECT created_at, status, payload_json FROM anonymous_telemetry_log ORDER BY created_at DESC LIMIT 5;"

Batching (target): A future sender might batch HTTPS requests (at most once per 5 minutes), remove rows after successful delivery, and drop payloads when the endpoint is unreachable — not shipped behaviour today.

Normative shipped-state notes: Implementation Spec §4d. Threat model for the endpoint: Telemetry Endpoint Threat Model below.


Telemetry Endpoint Threat Model

The telemetry endpoint described below is a design target only — it does not exist today and the shipped @jatbas/aic package contains no code that contacts it. The design is documented here so the threat model is established before any implementation ships. See Anonymous Telemetry and Implementation Spec §4d.

Threat Mitigation
Payload injection (fake telemetry) Strict JSON schema validation — reject payloads that don't match the typed schema. Rate-limit by IP (10 req/min). Analytics-grade data only — never used for security decisions.
DDoS CDN/WAF (Cloudflare). Rate limiting. Write-only endpoint with minimal attack value.
Man-in-the-middle TLS only (HTTPS). No plaintext fallback.
Endpoint impersonation URL hardcoded in AIC binary. Override only via explicit config change.
Data value if breached Minimal — no PII, no code, no paths, no prompts. Worst case: polluted analytics.

Design principle: If the telemetry endpoint goes down, AIC continues working normally. If it's compromised, no user data is at risk.

Full threat model: Project Plan §13 — Telemetry Endpoint Security.


MCP Server Top 10 Coverage

Mapping of AIC against the CSA MCP Server Top 10 Security Risks and the MCP Security Best Practices spec.

# Risk AIC Status AIC Controls Notes
MCP-01 Prompt Injection Covered Context Guard (6 pattern categories), PromptInjectionScanner, MarkdownInstructionScanner, CommandInjectionScanner, structural prompt template (intent is opaque, code in delimited blocks, constraints after context) See Prompt Injection Prevention
MCP-02 Confused Deputy N/A AIC is a local stdio server with no OAuth, no delegated auth, no multi-user. Single-user. Would apply if AIC added HTTP transport or multi-user auth (future major release)
MCP-03 Tool Poisoning N/A AIC exposes 9 tools (aic_compile, aic_inspect, aic_projects, aic_quality_report, aic_status, aic_last, aic_model_test, aic_chat_summary, aic_compile_spec). No dynamic tool loading, no third-party tool registry, no remote tool discovery. Fixed tool set compiled into the binary
MCP-04 Credential & Token Exposure Covered Config references env var names only (never values). Log sanitization replaces secrets with ***. Context Guard excludes .env, *.pem, *.key from compiled context. compiledPrompt omitted from aic_last response (optional top-level selection is path/score metadata only). No API keys in SQLite or cache. See API Key Handling
MCP-05 Insecure Server Configuration Covered MCP tools use stdio (local IPC). projectRoot/configPath path containment rejects traversal and blocks projectRoot = user home (os.homedir()). Global ~/.aic/ created at 0700. Project workspace: AIC ignore manifest appended to .gitignore / .eslintignore / .prettierignore on init (includes .aic/). Zod validation at boundary. Server performs a fixed outbound GET to the npm registry shortly after start for version check (not user-controlled). See .aic/ Directory Security
MCP-06 Supply Chain Attacks Covered (shipped) Lockfile committed and verified. CI runs OSV Scanner (google/osv-scanner-action@v1) on pnpm-lock.yaml. Exact version pinning (no ^). Minimal runtime deps. Rule packs are local JSON only — no remote loading in the shipped code. SBOM, signed npm releases, Dependabot/Snyk planned for near-term releases
MCP-07 Excessive Permissions Covered No shell exec, no user-chosen URLs, no arbitrary path read/write. aic_compile persists compilations, cache, and related metadata; other tools query status or log invocations only where implemented. Path containment limits tool args to safe project roots. Principle of least privilege by design
MCP-08 Data Exfiltration Covered aic_compile never sends compiled context to AIC servers. Local compilation_log / telemetry_events rows stay in ~/.aic/aic.sqlite; no shipped anonymous outbound client. compiledPrompt omitted from aic_last response; optional selection exposes structured trace metadata (paths/scores), not prompt text. aic_inspect JSON omits per-file resolvedContent on selectedFiles (metadata-only trace; avoids response self-flooding). tool_invocation_log records aic_compile, aic_inspect, aic_chat_summary, and aic_compile_spec (parameter shape only). See Data Leakage Prevention and Anonymous Telemetry
MCP-09 Context Spoofing Covered Intent is treated as opaque text (never interpolated into system instructions). Zod schema validation at boundary. Intent control-char strip removes \x00-\x08, \x0B-\x1F. conversationId/modelId constrained to printable ASCII with max length. See Prompt Injection Prevention
MCP-10 Insecure Communication Covered stdio transport only — local IPC, no network. No plaintext fallback. If HTTP transport is added later, mutual TLS or token auth required

Honorable Mentions coverage:

Risk AIC Status AIC Controls
Insufficient Logging Covered tool_invocation_log records aic_compile, aic_inspect, aic_chat_summary, and aic_compile_spec with params_shape (typeof-only). compilation_log and guard_findings provide compilation audit trail.
Resource Exhaustion (DoS) Covered 30s compilation timeout via Promise.race. Intent capped at 10,000 chars. configPath capped at 4,096 chars.
Input Validation Failures Covered Zod schemas validate all MCP handler inputs. Path containment guards reject traversal and home-directory misuse (projectRoot must be a project path, not os.homedir()). conversationId/modelId regex-constrained to printable ASCII.
Session Management Covered Session tracking with startSession/stopSession. Shutdown handler for graceful cleanup. Crashed session backfill on startup.

MCP Transport & Rule Pack Security

Attack surface Current state (shipped) Future hardening
MCP transport stdio only — local IPC, no network exposure If HTTP transport is added (v2.x target), require mutual TLS or token auth
Rule pack loading Local JSON files only — no remote URLs in the shipped code Remote rule packs (v2.x target): signature verification (ed25519)
Config extends URL Not implemented in the shipped code v2.x target: HTTPS only, URL allowlist, response schema validation
SQLite access Local file with 0700 directory permissions v2.x target: optional SQLCipher encryption for at-rest protection

MCP Tool Approval Requirements

Both Cursor and Claude Code require explicit user approval before MCP tools run. All nine AIC tools (aic_compile, aic_inspect, aic_projects, aic_quality_report, aic_status, aic_last, aic_model_test, aic_chat_summary, aic_compile_spec) need approval where the editor enforces per-tool consent. aic_compile (and typically aic_inspect) must be allowed for full compilation and guard inspection.

Editor Approval mechanism If not approved
Cursor MCP indicator shows an approval prompt on first invocation. User clicks "Always allow" per tool. Reviewable in Settings → MCP. Tool calls silently fail. Trigger rule detects this and notifies the user.
Claude Code Runtime permission prompt, --allowedTools CLI flag, or .mcp.json permissions configuration. Tool calls rejected. Trigger rule detects this and notifies the user.

Risk: If the user denies or never approves aic_compile, the MCP server may still run but the model gets no compiled context — no file selection, no Context Guard on that path, no context compilation.

Mitigation: The trigger rule (.cursor/rules/AIC.mdc for Cursor; .claude/CLAUDE.md for Claude Code) includes a fallback: if aic_compile is unavailable, the model tells the user how to enable it in MCP settings. Installation and Best practices describe approving aic_compile and aic_inspect during setup. The MCP server process is unaffected; the block is at the editor between the model and the server.


Supply Chain Security

Control When Implementation
Lockfile integrity Shipped pnpm-lock.yaml committed and verified in CI
Dependency audit Shipped CI runs OSV Scanner (google/osv-scanner-action@v1) on pnpm-lock.yaml on every PR; findings fail the workflow step
Minimal dependencies Ongoing Core (@jatbas/aic-core): better-sqlite3, zod, tiktoken, typescript, fast-glob, ignore, diff, commander, plus web-tree-sitter and Tree-sitter grammars. MCP package adds @modelcontextprotocol/sdk and zod. Exact pins in published package.json files.
Automated scanning Planned Dependabot or Snyk for continuous vulnerability monitoring
SBOM generation Planned CycloneDX SBOM generated on every release, published alongside npm package
Signed releases Planned npm --provenance flag for tamper-proof publish attestation

Supported Versions

Version Supported
0.x (baseline) ✅ Security fixes backported
< 0.1.0 ❌ Pre-release, no support

Security patches ship as semver patch bumps on the affected release line (0.1.0 → 0.1.1). Critical vulnerabilities receive out-of-band releases regardless of the regular release schedule.


Compliance

AIC's architecture is designed to be technically compliant with GDPR, SOC 2, and ISO 27001 from the start. Formal certifications are pursued when commercially justified — the architecture does not change.

Legal and compliance notice: The tables and status cells in this section describe engineering design choices, documentation posture, and product roadmap targets for discussion purposes. They do not constitute legal advice, regulatory guidance, or a determination that any law, standard, or certification requirement is satisfied.

Symbols such as ✅ or ⚠️ reflect internal engineering assessments, not third-party audits, attestations, or regulator findings.

How AIC is deployed, configured, and used determines outcomes in practice; organizations with compliance obligations should obtain advice from qualified counsel and perform their own assessments (including a data protection impact assessment when mandated by regulation).

Design Principles

Principle How AIC achieves it
Privacy by default No outbound anonymous telemetry client in the shipped package. Compile metrics are local SQLite rows — see Anonymous Telemetry. No PII in metric fields.
Data minimization telemetry_events holds numeric aggregates; compilation_log adds intent and optional selection_trace_json (path/score metadata). All local — not sent to AIC servers by shipped MCP paths
User control Inspect or delete ~/.aic/aic.sqlite. Top-level enabled: false stops new compile rows for that project. Future anonymous opt-in will use an extended config loader — not the minimal schema today.
Local-first All processing on user's machine. No cloud dependency for core functionality.
Transparency Local compile history in ~/.aic/aic.sqlite; anonymous_telemetry_log is schema-only until a sender ships
Security by design Context Guard, API key isolation, .aic/ permissions, no symlink traversal

GDPR Readiness

Requirement Status Implementation
Lawful basis (consent) ✅ No shipped anonymous outbound client; local compile metrics are operational data on the user’s machine — see Anonymous Telemetry
Data minimization ✅ Metric tables use typed fields; compilation_log.intent is local diagnostics — not uploaded by shipped MCP paths
Right to access ✅ Inspect compilation_log / telemetry_events in ~/.aic/aic.sqlite; anonymous_telemetry_log has no application writer today
Right to erasure ✅ Delete ~/.aic/aic.sqlite or disable the project (enabled: false) to stop new compile rows
Right to withdraw consent ✅ N/A for outbound until implemented; local data removable as above
Purpose limitation ⚠️ Outbound not started Shipped MCP path: no anonymous POST. When outbound ships: purpose disclosed in UI/config; see Compliance Roadmap (privacy policy ⚠️ Planned).
Data retention limit ⚠️ Planned Server-side: auto-delete after 90 days
Privacy policy ⚠️ Planned Not yet published — planned for a future release

SOC 2 Readiness

Trust Principle Control Status
Security Local-first; single global DB at ~/.aic/aic.sqlite with project-level isolation via project_id ✅ Baseline
Encryption in transit (TLS) ✅ Baseline (npm registry version check; future anonymous client would use TLS)
Vulnerability management (OSV Scanner on lockfile in CI) ✅ Baseline
Incident response (security.md) ✅ Baseline
Encryption at rest (SQLCipher) ⚠️ v2.x target
Automated scanning (Dependabot/Snyk) ⚠️ Planned
Penetration testing ❌ Enterprise maturity
Availability Works offline, local-first ✅ Baseline
SQLite = single file backup ✅ Baseline
Confidentiality Context Guard data classification ✅ Baseline
No code leaves machine in the current MCP-only package ✅ Baseline
Third-party data sharing ✅ Baseline — no compile context to third parties; anonymous outbound specified, not shipped (Anonymous Telemetry)

Compliance Roadmap

Milestone Deliverables
Baseline (shipped) security.md published. OSV Scanner on pnpm-lock.yaml in CI. Local compile metrics in SQLite; anonymous queue table schema only. Privacy-by-default architecture.
Near-term Privacy policy. SBOM. Signed npm releases. Dependabot/Snyk. OpenSSF Scorecard badge. Server-side 90-day retention policy.
v2.x targets SQLCipher optional encryption. Formal risk register. SOC 2 Type I prep documentation. GDPR DPIA. Rule pack signature verification.
Enterprise SOC 2 Type I audit. ISO 27001 gap assessment. Penetration test. Full ISMS documentation. Formal certifications when commercially justified.

Full compliance readiness mapping (including ISO 27001): Project Plan §25.