Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ body:
options:
- "Library API (`inspect.Scan`, `inspect.NewScanner`, etc.)"
- "MCP (`inspect_scan`, `inspect_scan_dir` tools)"
- "GitHub Action (`.github/action.yml`)"
- "SARIF output"
- "Browser-based checks (`browser/` sub-module)"
- "CVE / dependency database"
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ body:
- "Browser-based / dynamic check (`browser/`)"
- "Output format (JSON, SARIF, JUnit, HTML, terminal)"
- "Configuration (`.inspect.toml`, options)"
- "MCP server / GitHub Action / tooling"
- "MCP server / tooling"
validations:
required: true

Expand Down
79 changes: 0 additions & 79 deletions .github/action.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
run: git clone --depth=1 https://github.com/GrayCodeAI/hawk.git ../hawk
- name: gofumpt diff
run: |
go install mvdan.cc/gofumpt@latest
go install mvdan.cc/gofumpt@v0.10.0
out=$(gofumpt -l .)
if [ -n "$out" ]; then
echo "::error::gofumpt would reformat the following files:"
Expand Down
3 changes: 1 addition & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Website security auditing and crawling library for Go. Crawls sites concurrently

## Design Principles

- **Library + CLI** — importable library with optional `inspect-ci` binary
- **Library** — importable Go library + embeddable MCP server (no CLI binary)
- **No LLM dependency** — pure static analysis on crawled pages
- **Extensible** — custom checks (Go code) + declarative rules (no code required)

Expand All @@ -25,7 +25,6 @@ gofumpt -w . # Format
- `rule.go` — Declarative rule engine (YAML-based)
- `finding.go` — Findings with severity, CWE, and evidence
- `report.go` — Report generation (JSON, SARIF, HTML)
- `cmd/inspect-ci/` — Optional CI binary for pipeline integration

## Conventions

Expand Down
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
quality impact / SARIF compatibility / SSRF & egress safety /
Testing / Checklist.
- `.github/ISSUE_TEMPLATE/bug_report.yml` — surface dropdown
(library API / MCP / SARIF / GitHub Action / browser checks /
CVE database) and false-positive textarea.
(library API / MCP / SARIF / browser checks / CVE database) and
false-positive textarea.
- `.github/ISSUE_TEMPLATE/feature_request.yml` — `kind` selector
covering 8 functional areas (security checks / accessibility /
SEO / performance / browser / output formats / config / tooling)
Expand Down
174 changes: 145 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,179 @@
<p align="center">
<h1 align="center">Inspect</h1>
<p align="center">
<strong>Security vulnerability scanner for code</strong>
<strong>Live website auditor for accessibility, TLS, cookies, and security headers</strong>
</p>
<p align="center">
<a href="https://golang.org/"><img src="https://img.shields.io/badge/Go-1.23+-00ADD8?style=flat-square&logo=go&logoColor=white" alt="Go"></a>
<a href="https://golang.org/"><img src="https://img.shields.io/badge/Go-1.26+-00ADD8?style=flat-square&logo=go&logoColor=white" alt="Go"></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue?style=flat-square" alt="License"></a>
<a href="https://github.com/GrayCodeAI/inspect/actions/workflows/ci.yml"><img src="https://img.shields.io/github/actions/workflow/status/GrayCodeAI/inspect/ci.yml?style=flat-square&label=tests" alt="CI"></a>
</p>
</p>

---

Inspect scans code for security vulnerabilities, anti-patterns, and potential issues. It provides actionable findings with severity ratings and remediation guidance.
## What is inspect

## Features
inspect is a Go library that crawls live **websites** and audits the pages it
finds — broken links, security headers, forms, accessibility, performance, SEO,
TLS, cookies, mixed content, subresource integrity, AI-readiness, and
reachability. It is part of the [hawk](https://github.com/GrayCodeAI/hawk) ecosystem:
hawk wires inspect into its own commands, and inspect also ships an MCP server
so any MCP-compatible agent can run audits.

- **Multi-language support** - Scans Go, Python, JavaScript, TypeScript, and more
- **OWASP coverage** - Detects common vulnerability patterns
- **Custom rules** - Define project-specific security policies
- **CI/CD integration** - Fails builds on critical issues
> **inspect is a Go library (and MCP server), not a CLI.** It ships no `inspect`
> binary of its own — it analyzes running URLs, not source code. Import it
> directly to embed website auditing in your own Go program, or run the MCP
> server to expose it to an agent.

## Quick Start
It crawls concurrently (with rate limiting, robots.txt support, redirect
handling, and SSRF protection), runs each check against the discovered pages,
and returns findings with severity levels. Results can be emitted as SARIF for
the GitHub Security tab.

```bash
go get github.com/GrayCodeAI/inspect
```
## Quick Start

```go
import "github.com/GrayCodeAI/inspect"
import (
"context"
"fmt"

scanner := inspect.NewScanner(
inspect.WithRules(inspect.DefaultRules),
"github.com/GrayCodeAI/inspect"
)

report, err := scanner.Scan(ctx, "./path/to/code")
// One-shot scan with the Standard preset.
report, err := inspect.Scan(ctx, "https://example.com", inspect.Standard)
if err != nil {
// handle error
}
for _, f := range report.Findings {
fmt.Printf("[%s] %s - %s\n", f.Severity, f.Rule, f.Message)
fmt.Printf("[%s] %s: %s\n", f.Severity, f.URL, f.Message)
}
```

Requires Go 1.26+.

For repeated or high-throughput scans, reuse a `Scanner` (safe for concurrent use):

```go
scanner := inspect.NewScanner(inspect.Standard, inspect.WithDepth(3))
r1, _ := scanner.Scan(ctx, "https://site-a.com")
r2, _ := scanner.Scan(ctx, "https://site-b.com")
```

## Features

inspect ships nine built-in checks (registered in `check.DefaultRegistry`). The
six marked **(default)** run in the `Standard`, `Deep`, and `CI` presets; the
remaining three are opt-in via `WithChecks`.

- **Links** *(default)* — crawls and reports broken/unreachable links
- **Security headers** *(default)* — detects missing CSP, HSTS, and related
headers; also audits TLS certificate validity/expiry, cookie `Secure` /
`HttpOnly` / `SameSite` flags, and mixed content on HTTPS pages
- **Forms** *(default)* — form validation checks (CSRF, action URLs)
- **Accessibility (`a11y`)** *(default)* — meta/ARIA checks; optional axe-core
and color-contrast analysis through the `browser` sub-module (headless
Chromium via rod)
- **Performance (`perf`)** *(default)* — resource sizes and render-blocking
resources
- **SEO** *(default)* — meta tags, structured data, and metadata checks
- **SRI** — Subresource Integrity validation
- **AI-ready (`aiready`)** — checks for agent/LLM-friendly metadata
- **Reachability** — host/URL reachability checks
- **Concurrent crawler** — depth limits, rate limiting, robots.txt, redirect
following, and SSRF protection (private IPs blocked by default)
- **SARIF output** — `inspect.GenerateSARIF` emits SARIF 2.1.0 for the GitHub
Security tab
- **MCP server** — expose `inspect_scan` and `inspect_scan_dir` to any agent
- **Extensible** — register custom `Checker` implementations or declarative
`RuleCheck` patterns

## Presets

The default checks are: `links`, `security`, `forms`, `a11y`, `perf`, `seo`.
Add the opt-in checks (`sri`, `aiready`, `reachability`) with `WithChecks`.

| Preset | Behavior |
|---|---|
| `Quick` | Shallow crawl (depth 2), `links` only |
| `Standard` | Balanced crawl (depth 5), the six default checks |
| `Deep` | Exhaustive crawl (no depth limit), the six default checks |
| `SecurityOnly` | Security-related checks only |
| `CI` | Default checks, fail on high severity |

## MCP Server

inspect ships an MCP server (stdio transport) that exposes website auditing to
any MCP-compatible agent:

```go
import inspectmcp "github.com/GrayCodeAI/inspect/mcp"

srv := inspectmcp.New(inspect.Standard)
if err := srv.ServeStdio(); err != nil {
// handle error
}
```

**Tools:**

- `inspect_scan` — crawl a URL and run the configured checks
- `inspect_scan_dir` — serve and scan a local directory of HTML files

## Browser-Rendered Analysis

By default inspect analyzes raw HTTP responses. To analyze JavaScript-rendered
pages and run axe-core accessibility checks, supply a `BrowserEngine` from the
`browser` sub-module:

```go
import "github.com/GrayCodeAI/inspect/browser"

engine, err := browser.New()
if err != nil {
// handle error
}
defer engine.Close()

report, err := inspect.Scan(ctx, "https://example.com",
inspect.Standard,
inspect.WithBrowser(engine),
)
```

## Custom Checks

```go
// Declarative rule — no Go code beyond the struct.
inspect.RegisterRule(inspect.RuleCheck{
RuleName: "x-frame-options",
RuleSeverity: inspect.SeverityHigh,
HeaderMissing: []string{"X-Frame-Options"},
})

// Full Checker implementation, scoped to a single Scanner.
scanner := inspect.NewScanner(inspect.WithCustomChecks(myCheck))
```

## Examples

See the [examples/](examples/) directory for runnable code samples.

## Configuration
## Architecture

Create `.inspect.yaml` to customize scanning:
See [docs/architecture.md](docs/architecture.md) for the package layout and data flow.

```yaml
rules:
- name: no-hardcoded-secrets
severity: critical
- name: sql-injection
severity: high
ignore:
- vendor/
- testdata/
```
## Ecosystem

inspect is part of the hawk ecosystem:

| Component | Repository | Purpose |
|---|---|---|
| **hawk** | [GrayCodeAI/hawk](https://github.com/GrayCodeAI/hawk) | AI coding agent |
| **eyrie** | [GrayCodeAI/eyrie](https://github.com/GrayCodeAI/eyrie) | LLM provider runtime |
| **yaad** | [GrayCodeAI/yaad](https://github.com/GrayCodeAI/yaad) | Graph-based memory |
| **inspect** | This repo | Website audit library + MCP server |

## Contributing

Expand Down
Loading
Loading