NomikNomik

Security

Nomik's security model — local-first architecture, threat model, parameterized queries, network isolation, role-scoped access, and built-in security scanning.

Threat Model

Nomik operates as a local sidecar — it never touches production systems. The graph stores metadata about your codebase, not source code.

ThreatRiskMitigation
Graph DB exposed to networkHIGHBind to 127.0.0.1 only, Docker isolation
Credentials in config filesHIGHEnvironment variables, .env in .gitignore
Cypher injection via MCPMEDIUMParameterized queries only (no string concatenation)
Source code in graphNONEGraph stores metadata only — names, paths, line numbers, relationships
Viz dashboard accessLOWLocalhost-only by default
Dependency supply chainMEDIUMnomik audit with blast radius, lockfile pinning

Security Principles

1. No Raw Source Code in the Graph

The graph stores metadata — function names, file paths, line numbers, and relationships. A stolen graph database reveals architecture topology, not implementation details. This makes Nomik compliance-friendly — no PII or secrets are stored in the graph.

2. Parameterized Cypher Only

All graph queries use parameterized values. No string concatenation in Cypher, eliminating injection risk.

Correct — parameterized
session.run('MATCH (n:Function {name: $name}) RETURN n', { name });
Never — injection risk
session.run(`MATCH (n:Function {name: '${name}'}) RETURN n`);

3. Network Isolation

Neo4j is bound to localhost only — no external network access by default.

docker-compose.yml
services:
  neo4j:
    ports:
      - "127.0.0.1:7474:7474"    # Localhost only
      - "127.0.0.1:7687:7687"    # No external access

On Docker Desktop (Windows/macOS), networks: internal: true can block host-to-container port forwarding. The 127.0.0.1 binding is sufficient to prevent external access.

4. Environment-Based Secrets

Credentials are stored in environment variables, never hardcoded.

.env (never committed)
NOMIK_GRAPH_URI=bolt://localhost:7687
NOMIK_GRAPH_USER=neo4j
NOMIK_GRAPH_PASS=nomik_local

5. Role-Scoped MCP Access

The NOMIK_ROLE environment variable restricts which MCP tools the AI assistant can use:

RoleAccess LevelUse Case
dev (default)All 21 toolsFull development access
architectArchitecture tools onlyArchitecture review
securitySecurity/audit tools onlySecurity auditing
pmStats/reporting tools onlyProject management

6. Built-in Security Scanning

Nomik includes multiple security tools that work together:

Dependency audit with blast radius
$ nomik audit

Dependency Audit:

 lodash@4.17.20 Prototype Pollution (HIGH)
  Blast radius: 12 files import lodash
    src/utils/helpers.ts        (_.merge, _.get, _.set)
    src/services/transform.ts   (_.mapValues)
    ... 10 more files

 axios@0.21.0 SSRF Vulnerability (MEDIUM)
  Blast radius: 3 files import axios
    src/services/payment.ts
    src/services/email.ts
    src/services/search.ts

2 vulnerabilities found (1 high, 1 medium)
Quality gate with secret detection
$ nomik guard --ci

Quality Gate Check:
  Dead code:       0 (threshold: 5)   ✓
  God files:       2 (threshold: 3)   ✓
  Duplicates:      1 (threshold: 2)   ✓
  Security issues: 0 (threshold: 0)   ✓

PASSED
Architecture rules
$ nomik rules

 max-security-issues  0 / 0   PASS

Secret detection patterns: AWS keys (AKIA...), GitHub tokens (ghp_), Stripe keys (sk_live_), Slack tokens (xoxb-/xoxp-), SendGrid, Twilio, JWT secrets, private keys (-----BEGIN RSA PRIVATE KEY-----), basic auth URLs (https://user:pass@host).

False positive reduction: Automatically skips comments, test files, mock data, and placeholder values (xxx, example, test, TODO).

7. CI Integration

.github/workflows/security.yml
name: Nomik Security
on: [push, pull_request]
jobs:
  security:
    runs-on: ubuntu-latest
    services:
      neo4j:
        image: neo4j:5-community
        env:
          NEO4J_AUTH: neo4j/nomik_local
        ports:
          - 7687:7687
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 22
      - run: npm install -g @nomik-ai/cli
      - run: nomik scan .
      - run: nomik audit --ci
      - run: nomik rules --ci
      - run: nomik guard --ci

Or use the all-in-one nomik ci command:

Simplified CI
    steps:
      - uses: actions/checkout@v4
      - run: npm install -g @nomik-ai/cli
      - run: nomik ci    # scan → rules → guard → audit

Both nomik audit --ci and nomik guard --ci exit with code 1 on failure, making them suitable for CI pipelines.