diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ee75bcb --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +.git +.github +.gitignore +*.md +.env +.env.* +Dockerfile +.dockerignore +coverage.out +docs/ +deploy/ +api/ +go.work +go.work.sum diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..1826251 --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# inspect environment variables — copy to .env and fill in +# LLM API key for AI-powered scanning (used by llm_scanner.go) +INSPECT_LLM_API_KEY= +INSPECT_LLM_PROVIDER=openai +# Chromium path override (optional — leave empty to use bundled chromium) +CHROME_PATH= diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..15c8ef6 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,63 @@ +name: Docker + +on: + push: + branches: [main] + tags: ["v*"] + pull_request: + branches: [main] + paths: + - "Dockerfile" + - "**.go" + - "go.mod" + - "go.sum" + +permissions: + contents: read + packages: write + +env: + REGISTRY: ghcr.io + IMAGE_NAME: graycodeai/inspect + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Docker metadata + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} + tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=sha,prefix=sha- + + - name: Build and push + uses: docker/build-push-action@v6 + with: + context: . + push: ${{ github.event_name != 'pull_request' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max + build-args: | + VERSION=${{ github.ref_name }} + COMMIT=${{ github.sha }} + BUILD_DATE=${{ github.event.head_commit.timestamp }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..06a6958 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,39 @@ +FROM golang:1.26.3-alpine AS builder + +RUN apk add --no-cache git ca-certificates chromium tzdata + +WORKDIR /build +COPY go.mod go.sum ./ +RUN go mod download && go mod verify + +COPY . . +ARG VERSION=dev +ARG COMMIT=none +ARG BUILD_DATE=unknown + +RUN CGO_ENABLED=0 GOOS=linux go build -trimpath \ + -ldflags="-s -w \ + -X main.Version=${VERSION} \ + -X main.Commit=${COMMIT} \ + -X main.BuildDate=${BUILD_DATE}" \ + -o inspect-ci ./cmd/inspect-ci + +RUN CGO_ENABLED=0 GOOS=linux go build -trimpath \ + -ldflags="-s -w \ + -X main.Version=${VERSION} \ + -X main.Commit=${COMMIT} \ + -X main.BuildDate=${BUILD_DATE}" \ + -o inspect-action ./cmd/inspect-action + +FROM alpine:3.21 +# chromium is required for browser-based checks +RUN apk add --no-cache ca-certificates tini chromium && \ + adduser -D -u 1000 inspect + +COPY --from=builder /build/inspect-ci /usr/local/bin/inspect-ci +COPY --from=builder /build/inspect-action /usr/local/bin/inspect-action +COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo + +USER inspect +ENTRYPOINT ["tini", "--", "inspect-ci"] +CMD ["--help"] diff --git a/api/openapi.yaml b/api/openapi.yaml new file mode 100644 index 0000000..364cd37 --- /dev/null +++ b/api/openapi.yaml @@ -0,0 +1,81 @@ +openapi: "3.1.0" +info: + title: inspect — Security Auditor Tool Reference + description: | + inspect is a website security, accessibility, and SEO auditor. + It operates as a CLI tool, GitHub Action, and MCP server (stdio). + + This document describes the MCP tool surface as a machine-readable reference. + inspect does NOT expose an HTTP server — all communication is via stdio MCP + or direct Go library calls. + version: "0.1.0" + license: + name: MIT + url: https://github.com/GrayCodeAI/inspect/blob/main/LICENSE + contact: + url: https://github.com/GrayCodeAI/inspect + +# No servers section — inspect has no HTTP API. +# MCP tools are documented below using x-mcp-tool extensions. + +tags: + - name: scan + description: Website scanning tools + - name: report + description: Report generation + +x-mcp-server: + transport: stdio + binary: inspect-ci + start_command: ["inspect-ci", "mcp"] + +x-mcp-tools: + inspect_scan: + description: Crawl a URL and run security, accessibility, SEO, and performance checks + inputSchema: + type: object + required: [url] + properties: + url: + type: string + description: Target URL to scan (must be http:// or https://) + checks: + type: array + items: + type: string + enum: [security, links, forms, a11y, performance, seo] + description: Checks to run (default: all) + depth: + type: integer + default: 3 + description: Maximum crawl depth + concurrency: + type: integer + default: 5 + description: Number of concurrent crawlers + format: + type: string + enum: [text, json, sarif, html, markdown, junit] + default: json + fail_on: + type: string + enum: [info, low, medium, high, critical] + description: Minimum severity that counts as a failure + + inspect_scan_dir: + description: Scan a local directory of HTML files + inputSchema: + type: object + required: [path] + properties: + path: + type: string + description: Absolute path to the HTML directory + checks: + type: array + items: + type: string + format: + type: string + enum: [text, json, sarif, html, markdown] + default: json diff --git a/deploy/docker/docker-compose.yml b/deploy/docker/docker-compose.yml new file mode 100644 index 0000000..ee70f3e --- /dev/null +++ b/deploy/docker/docker-compose.yml @@ -0,0 +1,13 @@ +name: inspect + +services: + inspect: + build: + context: ../../ + dockerfile: Dockerfile + image: ghcr.io/graycodeai/inspect:dev + env_file: + - path: ../../.env.example + required: false + entrypoint: ["inspect-ci"] + command: ["--help"] diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..b4613af --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,140 @@ +