npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@stelnyx/secgate

v0.2.14

Published

Tiny security gate for CI/CD — orchestrates Semgrep, Gitleaks, osv-scanner, Trivy, and npm audit with a premium HTML report.

Downloads

319

Readme

SecGate

A single-command security gate for CI/CD.

Semgrep · Gitleaks · osv-scanner · Trivy · npm audit One command. One report. One exit code.


SecGate orchestrates five industry-standard security scanners — Semgrep, Gitleaks, osv-scanner, Trivy, and npm audit — behind a single command. It normalizes their output into one report and fails the pipeline on CRITICAL or HIGH findings. No account. No telemetry. No data leaves your machine — except for the vulnerability lookups the wrapped scanners perform (see Network access).

Honest positioning. SecGate is a triage accelerator, not a defect oracle. Dogfooded against a 2,628-file production codebase: 1,858 → 46 actionable findings — 98% noise demoted. The wrapped scanners are each noisy in isolation (industry estimate: ~70% of raw SAST/SCA output is signal-less). SecGate's job is to surface what's actionable and demote the rest — see What we demote (and why).

Status. Early release (v0.2.14). Releases publish from GitHub Actions with npm trusted publishing and provenance. Report vulnerabilities via SECURITY.md.

Accuracy contract. SecGate's aggregation pipeline is deterministic — same inputs produce JSON-byte-identical findings, score, and gate status across every run. Two test suites lock the contract:

  • test/determinism.mjs — JSON byte-equality across reruns, order-stable dedup, override + ignore applied identically.
  • test/golden-secgate.mjs — hand-crafted 11-finding fixture; expected counts, score (22), and gate status are inline so any change surfaces in code review.

Full pipeline spec lives in docs/aggregation.md.


Security Score

Every run now produces a Security Score (0–100) in addition to the binary PASS/FAIL gate. The score is deterministic: same findings → same score every time.

Security Score: 62 / 100   ████████████░░░░░░░░  rule v1

  Semgrep      97 / 100   ███████████████████░
  Gitleaks     75 / 100   ███████████████░░░░░
  npm audit    90 / 100   ██████████████████░░
  osv-scanner 100 / 100   ████████████████████
  Trivy        62 / 100   ████████████░░░░░░░░

Penalty per finding: CRITICAL −25 · HIGH −10 · MEDIUM −3 · LOW −1 · INFO/UNKNOWN 0. Floor: 0. Color thresholds: green ≥ 90, amber ≥ 70, red < 70. The binary gate (exit 1 on CRITICAL/HIGH) is unchanged. securityScore and toolScores are also written to secgate-v7-report.json for CI dashboards and trend tracking.


TL;DR

npx @stelnyx/secgate .

Runs all five scanners against the current directory, writes a JSON report, a self-contained HTML report, and (optionally) SARIF. Exit 0 on clean, 1 on CRITICAL/HIGH findings. That's the whole product.


What it does today

SecGate wraps five existing open-source scanners, runs them against a directory, and produces:

  • One normalized JSON report across every scanner
  • One self-contained HTML report with per-scanner tabs, dark mode, zero external assets
  • One SARIF 2.1.0 file ready for GitHub Code Scanning upload
  • One exit code1 when CRITICAL or HIGH findings are present; blocks CI

SecGate does not ship its own analysis engine. Every finding originates from one of the five underlying tools. The value is orchestration, normalization, and a single exit code.


Scanners

| Scanner | Category | Notes | |---------------|---------------------------|-----------------------------------------------------------------------| | Semgrep | SAST (static code) | OSS ruleset. 10+ languages. Extend via customSemgrepRules. Local. | | Gitleaks | Secrets & credentials | Working tree + git history (when .git/ present). Secrets redacted. Local. | | npm audit | Node dependencies (SCA) | Runs when package.json present. Queries the npm registry advisory API (network). | | osv-scanner | Polyglot SCA | npm, PyPI, Go, Cargo, Maven, RubyGems, Packagist, NuGet, Pub. Queries the OSV.dev API (network). | | Trivy | IaC + License + Image | Terraform, Kubernetes, Dockerfile, CloudFormation. Base-image CVEs. Downloads its vuln DB; pulls image layers for image scans (network). |

Missing scanner binaries are skipped gracefully and noted in the report. No scanner is required; SecGate uses whatever is on $PATH.


Network access

SecGate itself makes no network calls — no telemetry, no account, no phone-home, and the report is written to local files. But three of the five wrapped scanners need the internet to do their job:

| Scanner | Network use | |---------|-------------| | Semgrep | None — runs its ruleset against your files. | | Gitleaks | None — scans your working tree and git history locally. | | npm audit | Queries the npm registry's advisory API for your dependency tree. | | osv-scanner | Queries the OSV.dev API for advisories matching your dependency manifests. | | Trivy | Downloads/updates its vulnerability database; pulls image layers when scanning container images. |

So "no telemetry" is exact; "fully air-gapped" is not — run SecGate offline and npm audit, osv-scanner, and Trivy will degrade or skip (which SecGate reports). On first run, osv-scanner and Trivy may download vulnerability databases; SecGate prints a one-line note before starting those scanners so the initial delay is not mistaken for a hang. A first-class offline mode (skip the network scanners, or point them at a local DB mirror) is tracked in the issue backlog.


What we demote (and why)

The HTML report has two confidence profiles:

  • curated (default) — actionable findings render inline. Known-noisy patterns get demoted to a collapsed Informational block. The exit code (0/1) is unchanged — demotion is presentation-only, not policy.
  • strict — every finding renders inline with no demotion. Use for compliance audits or when tuning the curated rule list.

Curated profile demotes:

| Pattern | Why demoted | |---------|-------------| | License findings (type: license from Trivy) | Trivy flags every dep license (MIT, Apache-2.0, LGPL, etc.) as a finding. License posture is governance/legal, not security — belongs in its own pane, not next to CVEs. | | Trivy base-image OS CVEs at LOW/MEDIUM (scanMode: image or signature: trivy-image:*) | Rarely reachable from a Node/Python/Go app runtime (apt-secure, libtinfo, perl-base). CRITICAL/HIGH still surface inline. | | CVEs >5 years old, severity != CRITICAL | If upstream hasn't shipped a fix in 5+ years, exploitability is bounded. | | UNKNOWN severity findings | Scanner couldn't classify — surfaced for audit, not blocked. | | html.security.audit.missing-integrity | Fires on every <script src> without an SRI hash, including inline favicon SVGs. Real CDN-MITM risk is covered by HSTS / COEP on most modern stacks. | | path-join-resolve-traversal Semgrep rule | Common false positive in CLI tools that legitimately resolve user-supplied paths against a known root. |

Real-world impact: dogfood scan of a 2,628-file CirrusTranslate codebase: 1858 → 46 actionable findings (98% noise demoted). Of the 46: 2 CRITICAL + 36 HIGH + 8 LOW. Triageable in one sitting instead of a wall of license rows + base-image CVEs.

Findings are never dropped by curated demotion — they're re-classified for display ordering. Suppressed findings (inline # secgate:ignore comments) get their own collapsed block with per-rule counts for audit trail.

Toggle via .secgate.config.json:

{ "profile": "curated" }   // or "strict"

Or via CLI:

secgate . --profile strict

Positioning

SecGate is not a SOC platform, a compliance tool, or a vulnerability management system. It is a CI gate that aggregates scanner output and fails the build when something critical is found.

| Alternative | When to pick it instead of SecGate | |--------------------|-----------------------------------------------------------------| | Trivy standalone | You only scan containers and don't need SAST or secrets. | | Semgrep OSS | You only need SAST with custom rules. | | Snyk | You need a managed vuln DB, triage UX, Jira sync — and budget.| | Aikido | You want SaaS dashboards and are OK with a hosted account. |

SecGate's niche: zero-config orchestration, local output only, MIT. If you need SaaS-grade triage or compliance workflow, buy Snyk or Aikido. Full matrix: docs/comparison.md.


Prerequisites

Node.js >=18. External scanners are optional — install only the ones you want to run.

# macOS
brew install semgrep gitleaks osv-scanner trivy

# Linux
pip install semgrep
# gitleaks:    https://github.com/gitleaks/gitleaks#installing
# osv-scanner: https://github.com/google/osv-scanner#installation
# trivy:       https://aquasecurity.github.io/trivy/latest/getting-started/installation/

Install

From npm (recommended)

npm install -g @stelnyx/secgate

One-shot via npx (no install)

npx @stelnyx/secgate .

From source

git clone https://github.com/Stelnyx/SecGate.git
cd SecGate
npm install
chmod +x secgate.js
sudo ln -sf "$(pwd)/secgate.js" /usr/local/bin/secgate

Usage

# Scan current directory (dry-run, default)
secgate .

# Scan with auto-remediation (npm audit fix only — see warning below)
secgate . --apply

# Scan with debug output
secgate . --debug

# Scan specific path
secgate /path/to/project

# Write reports to a custom directory (default: the target)
secgate /path/to/project --output-dir /tmp/reports

# Strip absolute paths from the report (auto-on when CI=true)
secgate /path/to/project --strip-paths

# Show all findings inline (skip curated demotion)
secgate . --profile strict

# Raise bounded-walk limits for an unusually large single project
secgate . --max-files 50000 --max-depth 32

# Override workspace detection when you intentionally scan many sub-projects
secgate /path/to/workspace --allow-workspace

# Version / help
secgate --version
secgate --help

SecGate is designed for a single project target. Before launching external scanners, it performs a bounded preflight walk that skips dependency, VCS, vendor, and build-output directories (node_modules, .git, dist, build, coverage, vendor, and common package-manager caches). Symlinks are skipped, large files are not parsed, and the walk is capped by --max-files, --max-depth, --max-file-size, and --walk-timeout-ms. If the target looks like a workspace with multiple sub-projects and no root package.json, SecGate exits with a clear message unless --allow-workspace is supplied.

Exit codes

| Code | Meaning | |:----:|----------------------------------------------------| | 0 | PASS — no CRITICAL or HIGH findings | | 1 | FAIL — CRITICAL or HIGH findings present | | 2 | Invalid target or CLI error |


Security — --apply in untrusted repos

--apply executes remediations (npm audit fix) inside the scanned repo. Treat this as code execution against the target. Only use it on code you trust.

Hardening already in place:

  • Every npm invocation under --apply passes --ignore-scripts — malicious preinstall / postinstall scripts in the target's package.json (or its dependencies) are not executed.
  • --apply is gated: refuses to run unless SECGATE_CONFIRM_APPLY=1 is set (CI / non-interactive) or the user types y at an interactive TTY prompt.
  • Every --apply execution is recorded in the report's auditLog field and mirrored to stderr with timestamp and target.

Operator guidance:

  • Do not run --apply against untrusted or newly cloned third-party repos. Run dry-run first, review, decide.
  • In CI, prefer dry-run (secgate .) and rely on the exit code to gate. If you must --apply, do it inside an isolated, ephemeral runner with SECGATE_CONFIRM_APPLY=1.
  • Report files default to the target directory. Use --output-dir to redirect; a warning is printed to stderr when cwd !== target.
  • In CI, --strip-paths is auto-enabled to prevent host paths leaking into uploaded artifacts.

Configuration

Create .secgate.config.json in your scan target directory. All fields are optional.

{
  "profile": "curated",
  "failOn": ["critical", "high"],
  "scanners": {
    "semgrep": true,
    "gitleaks": true,
    "npm": true,
    "osv": true,
    "trivy": false
  },
  "severityOverrides": [
    { "rule": "npm-audit.lodash", "severity": "LOW" },
    { "rule": "trivy-DS*", "severity": "MEDIUM" }
  ],
  "ignore": ["CVE-2024-12345", "npm:some-old-package*"],
  "baselineFile": ".secgate-baseline.json",
  "customSemgrepRules": "./rules/"
}

A fully-commented example config lives at .secgate.config.example.json — copy into your repo as .secgate.config.json and edit.

JSON Schema: docs/config.schema.json

Field reference

| Field | Type | Default | Description | |----------------------|-----------------|----------------------------|-----------------------------------------------------------------------------| | profile | string | "curated" | HTML report confidence profile: "curated" or "strict" (see demotion table) | | failOn | string[] | ["critical","high"] | Severity tiers that cause exit 1 | | scanners | object | all true | Set any scanner to false to skip it | | severityOverrides | array | [] | Override severity for matching signatures (glob * supported) | | ignore | string[] | [] | Drop findings whose signature matches (glob * supported) | | baselineFile | string | .secgate-baseline.json | Path to baseline file (relative to target) | | customSemgrepRules | string\|null | null | Extra --config=<path> passed to semgrep |

Precedence

CLI flag  >  .secgate.config.json  >  built-in defaults
  • --baseline and --update-baseline are CLI-only (no config equivalent).
  • Missing config file: silent, defaults apply. Invalid JSON: error logged, defaults apply.

Baseline workflow

# 1. Accept current state as baseline
secgate . --update-baseline

# 2. On subsequent runs, fail only on net-new findings
secgate . --baseline

Commit .secgate-baseline.json to your repo. Baselined findings appear in reports with a baseline marker and are excluded from the fail-gate.

Inline suppression

Add a comment on the flagged line or the line immediately above:

// secgate:ignore <rule-id>
db.query(userInput);

db.execute(sql); // secgate:ignore my.rule.id

/* secgate:ignore my.rule.id */
dangerousCall();

Suppressed findings are excluded from counters. The report's suppressions section records per-rule counts for audit.


CI / CD

GitHub Actions — minimal

# .github/workflows/secgate.yml
- name: Run SecGate
  run: npx @stelnyx/secgate .
  # exits 1 on CRITICAL or HIGH findings — blocks the pipeline

Non-blocking (report only)

- name: Run SecGate
  run: npx @stelnyx/secgate . || true

- name: Upload report
  uses: actions/upload-artifact@v4
  with:
    name: secgate-report
    path: |
      secgate-v7-report.json
      *.html

As a composite GitHub Action

A composite action is published at .github/actions/secgate/ in this repo.

- name: SecGate Security Gate
  id: secgate
  uses: Stelnyx/SecGate/.github/actions/secgate@main
  with:
    target: "."
    apply: "false"
    fail-on: "critical,high"
    format: "json,html,sarif"

- name: Upload HTML + JSON
  if: always()
  uses: actions/upload-artifact@v4
  with:
    name: secgate-report
    path: |
      secgate-v7-report.json
      *.html

- name: Upload SARIF to Code Scanning
  if: always() && steps.secgate.outputs.sarif-path != ''
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: ${{ steps.secgate.outputs.sarif-path }}
    category: secgate

Action inputs

| Input | Default | Description | |-----------|------------------|----------------------------------------------------------| | target | . | Directory to scan | | apply | false | Execute fixable remediations | | fail-on | critical,high | Severity levels that fail the step | | format | json,html | Output formats — comma-separated: json, html, sarif|

Action outputs

| Output | Description | |---------------|---------------------------------------------------------------| | report-path | Path to secgate-v7-report.json | | sarif-path | Path to <repo>.sarif.json (set only when format includes SARIF) |

Pin to a full commit SHA for production workflows:

uses: Stelnyx/SecGate/.github/actions/secgate@<full-sha>

See .github/workflows/example-secgate.yml for a complete reference workflow.

Releasing SecGate

Package releases are published by the Publish GitHub Actions workflow when a GitHub Release is published. The workflow uses npm trusted publishing through OIDC, so there is no npm token in GitHub secrets and no local publish step.

Release summary: bump the npm version, commit and push main, push a matching vX.Y.Z tag, create a GitHub Release from that tag, then confirm the dependency guard, workflow, and npm provenance badge. The release path runs npm run check:deps to block accidental file:, link:, or workspace: dependencies before publish. See CONTRIBUTING.md for the exact checklist and npm Trusted Publisher settings.


SARIF output

SecGate emits SARIF 2.1.0 alongside JSON and HTML. SARIF is the standard format consumed by GitHub Code Scanning, GitLab SAST, and other platforms.

secgate . --format sarif
# writes: secgate-v7-report.json, <repo>.html, <repo>.sarif.json

The --format flag accepts a comma-separated list. sarif is additive — JSON and HTML are always written:

secgate . --format json,html,sarif   # same as above
secgate . --format sarif             # also writes JSON + HTML

SARIF structure

  • One runs[] entry per scanner: semgrep, gitleaks, npm, osv, trivy, trivyImage (6 total).
  • Each finding maps to a result with ruleId = signature, level derived from severity, and locations[].physicalLocation when file/line data is present.
  • properties["security-severity"] carries a CVSS-style score for GitHub's sort order: CRITICAL = 9.5, HIGH = 7.5, MEDIUM = 5, LOW = 2, UNKNOWN = 0.

Upload to GitHub Code Scanning

- name: Run SecGate
  id: secgate
  run: npx @stelnyx/secgate . --format sarif

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  if: always()
  with:
    sarif_file: <repo-name>.sarif.json
    category: secgate

Report output

Each run writes:

  • secgate-v7-report.json — machine-readable, schema below.
  • <repo-name>.html — self-contained HTML report with per-scanner tabs, dark mode, zero external assets. Filename derived from the target directory name.
  • <repo-name>.sarif.json — SARIF 2.1.0 file (only when --format sarif is passed).

JSON schema

{
  "version": "0.2.13",
  "timestamp": "ISO 8601",
  "target": "/absolute/path",
  "mode": "dry-run | apply",
  "status": "PASS | FAIL",
  "summary": {
    "critical": 0,
    "high": 0,
    "medium": 0,
    "low": 0,
    "unknown": 0
  },
  "tools": {
    "semgrep":    "ran | clean | skipped | error | pending",
    "gitleaks":   "ran | clean | skipped | error | pending",
    "npm":        "ran | clean | skipped | error | pending",
    "osv":        "ran | clean | skipped | error | pending",
    "trivy":      "ran | clean | skipped | error | pending",
    "trivyImage": "ran | clean | skipped | error | pending"
  },
  "findings": [
    {
      "tool": "gitleaks | semgrep | npm | osv | trivy | trivyImage",
      "type": "secret | code | dependency | iac | license",
      "severity": "CRITICAL | HIGH | MEDIUM | LOW | UNKNOWN",
      "signature": "rule or package ID",
      "message": "description",
      "file": "relative or absolute path, or null",
      "line": 42,
      "col": 5,
      "endLine": 42,
      "fixable": false,
      "fixableBy": "auto | manual | null"
    }
  ],
  "intelligence": {
    "riskScore": 0,
    "attackSurface": ["secret", "dependency", "iac", "license", "code"],
    "reasoning": [{ "issue": "...", "why": "..." }],
    "recommendations": ["..."]
  },
  "remediation": {
    "plan": [{
      "issue": "...",
      "patch": {
        "action": "...",
        "cmd": "display string or null",
        "exec": { "binary": "npm", "args": ["audit", "fix", "--ignore-scripts"], "cwd": "..." }
      }
    }],
    "stagedChanges": [],
    "executed": [],
    "blocked": [],
    "confidence": 100
  },
  "auditLog": [
    {
      "timestamp": "ISO 8601",
      "event": "apply_start | apply_confirmed | apply_exec | apply_ok | apply_fail",
      "target": "target path or repo basename (if --strip-paths)"
    }
  ]
}

Severity tiers

Every finding is normalized to one of five tiers at the addFinding() ingress:

| Tier | Meaning | |-------------|------------------------------------------------------------------------------------------| | CRITICAL| Exploitable now — secrets, CVSS ≥ 9, hardcoded-credential SAST rules | | HIGH | High-impact — CVSS 7.0–8.9, Semgrep ERROR, rated HIGH upstream | | MEDIUM | Meaningful — CVSS 4.0–6.9, WARNING, MODERATE | | LOW | Informational — CVSS < 4.0, INFO, NOTE | | UNKNOWN | Upstream provided no severity or an unrecognized value — surfaced rather than miscounted |

Fixability

  • fixableBy: "auto"patch() returns an executable command; --apply will run it (currently only npm audit fix).
  • fixableBy: "manual" — a patch exists but requires human action (upgrade, rotate, refactor).
  • fixable: true mirrors fixableBy === "auto" for CI convenience.

Tool states

| State | Meaning | |-------------|------------------------------------------------------------------------------| | ran | Tool executed, findings present | | clean | Tool executed, no findings | | skipped | Tool not installed, or target not applicable (no package.json, no lockfile)| | error | Tool produced output that could not be parsed — re-run with --debug | | pending | Tool did not run (should not appear in final reports) |


Risk scoring

Findings are scored with static weights applied at ingress:

| Severity | Weight | |----------|:------:| | CRITICAL | 10 | | HIGH | 6 | | MEDIUM | 3 | | LOW | 1 |

The riskScore in the report is the sum of these weights across all findings. This is a heuristic count, not CVSS, not EPSS, not exploit-probability modeling. Use it to compare runs of the same repo over time — not as an absolute posture score.

Note — two scores, two purposes. riskScore (here) is an unbounded raw weight kept for backward compatibility with early CI dashboards. The user-facing Security Score (0–100) at the top of this README is the deterministic 0–100 posture metric introduced in v0.2.x and is the one to surface in new dashboards.


Documentation

| Doc | What's in it | |--------------------------------------------------------|--------------------------------------------------------------------------------| | CHANGELOG.md | Version history — Added / Changed / Fixed / Security per release | | OPEN-CORE.md | OSS core boundary and paid extension roadmap | | docs/aggregation.md | Aggregation pipeline contract: pipeline stages, score formula, gate rule | | docs/comparison.md | Feature matrix vs Snyk / Trivy / Semgrep / Aikido | | docs/coverage.md | Scanner-to-category matrix, explicit gaps | | docs/tuning.md | Thresholds, baselines, suppression, CI vs local defaults | | docs/threat-model.md | STRIDE analysis, trust boundaries, mitigations | | docs/adr/ | Architecture decision records | | SECURITY.md | Vulnerability reporting, SLA, coordinated disclosure, supply-chain trust | | CONTRIBUTING.md | Dev setup, branch + commit conventions, PR checklist |


Product vision

SecGate is the open-source input layer for a broader security workflow. The core CLI — scan orchestration, SARIF output, baselines, suppressions, HTML report — stays MIT-licensed and free, forever. Future paid extensions may add hosted dashboards, org-wide policy management, compliance evidence packs, and multi-repo aggregation for teams that need more than a local gate. Those do not exist today. The OSS boundary is defined in OPEN-CORE.md.


Tiers (planned)

Status: today's CLI is MIT, single tier — npx @stelnyx/secgate . runs the full scan, no flags, no gates. The table below is the planned tier model that aligns SecGate with LuxScope and LuxFaber — same engine at every tier, paid tiers add presentation, persistence, and governance. recon ships today. standard / enterprise arrive when the hosted-link service lands.

| Tier | Scanners | Findings | HTML report | Hosted shareable link | Branded cover | Trend storage | |---|---|---|---|---|---|---| | recon | all 5 (Semgrep · Gitleaks · npm audit · osv-scanner · Trivy) | all (curated + strict profiles) | yes (self-contained) | no | no | no | | standard | all 5 | all | yes | yes (persistent URL) | no | yes (per-repo history) | | enterprise | all 5 + custom rule packs | all | yes | yes | yes (logo, client, accent color) | yes (org-wide rollup) |

recon is full local analysis — same scanners, same findings, same SARIF output as paid tiers. Paid tier value is persistence, sharing, and governance, not analysis depth. The CLI does not gate any scanner output by tier — every CVE, every secret, every IaC misconfig surfaces in recon. The MIT core boundary is defined in OPEN-CORE.md.


Contributing

See CONTRIBUTING.md. Report vulnerabilities privately per SECURITY.mddo not open public issues for security reports.


License

MIT — © Stelnyx