Skip to main content

CASM: Continuous Attack Surface Monitoring

Project description

CASM

Continuous Attack Surface Monitoring

CASM logo

EASM + Baseline Comparison + Evidence-First

Know your attack surface. Track what changes.

CASM continuously maps your external attack surface and tracks what changed - turning security scanning into security intelligence.

What is CASM?

CASM is an attack surface tracking and analysis system that:

  • 🔍 Discovers - Maps your external attack surface (HTTP, DNS, TLS)
  • Verifies - Checks security configurations and headers
  • 📊 Tracks - Baseline comparison shows exactly what changed
  • 📋 Reports - Evidence-ready compliance reporting (SARIF, Markdown, PDF)

Unlike traditional scanners that give you snapshots, CASM tracks changes over time - answering the critical question: "What's different from last week?"

Principles

  • Authorization-first. Operates only within explicit scope and rate limits.
  • Safe verification by default. No destructive actions, no payloads, no brute force.
  • Evidence-first. Findings are backed by raw, redacted evidence.
  • Modular architecture. Brain (Python) orchestrates, Hands (Go) execute.

Status

Current focus: EASM-style discovery + safe verification + evidence-first reporting.

  • SARIF output for CI integration
  • Evidence JSONL for automation
  • A dual-audience Markdown report (executive + technical) for casm run.
  • PDF reports with a "Changes Since Last Scan" section when a baseline exists.

Safety model

CASM is designed for authorized testing only and enforces:

  • Default dry-run mode
  • Scope guard allowlists (domains, IPs, ports, protocols)
  • Deterministic blocking with reason codes
  • Rate limiting and concurrency caps

Repository layout

brain/: Python orchestration + policy enforcement

  • core/: Domain logic (scope, policy, findings, reporting)
  • ports/: Interfaces (tool gateway, evidence store, publisher)
  • adapters/: Implementations (tool runners)
  • cli/: casm CLI entrypoint
  • tests/: Offline-first unit tests

hands/: Go tools for safe verification

  • cmd/probe/: TCP connect checks
  • cmd/http_verify/: HTTP metadata and header checks
  • cmd/dns_enum/: DNS enumeration (passive + active)
  • pkg/: Shared code

contracts/: JSON schemas + fixtures

  • schemas/: Tool request/response schemas
  • fixtures/: Deterministic fixtures for tests

runs/: Evidence + reports output


Requirements

  • Python 3.11+ recommended
  • Go 1.21+

Setup (recommended: venv)

python3 -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt -r requirements-dev.txt
python -m pip install -e .

Build the Go tools:

make build-hands

Run DNS enumeration:

casm run dns-enum --config scopes/scope.yaml --domain example.com

Run tests:

make test

Run http_verify via CLI:

casm run http-verify --scope scopes/scope.yaml --dry-run=false

Note: casm run http-verify writes evidence.jsonl, results.sarif, and targets.jsonl in runs/<engagement>/<run>/ but does not generate a report yet.

Unified pipeline:

casm run unified --config scopes/scope.yaml --sarif-mode local

Unified pipeline with imported targets (skips probe):

casm run unified --config scopes/scope.yaml --targets-file targets/target02-harness.json --sarif-mode local

Detailed unified report (includes per-endpoint findings):

casm run unified --config scopes/scope.yaml --targets-file targets/target02-harness.json --sarif-mode local --detailed

Diff two runs (SARIF):

casm diff --old runs/<engagement>/<run_id>/results.sarif --new runs/<engagement>/<run_id>/results.sarif

Include unchanged findings in the diff report:

casm diff --old runs/<engagement>/<run_id>/results.sarif --new runs/<engagement>/<run_id>/results.sarif --include-unchanged

Targets file format (JSON harness):

{
  "targets": [
    { "url": "https://127.0.0.1:8443/health", "method": "HEAD" },
    { "url": "https://localhost:8444/headers/none" }
  ]
}

Outputs are written to runs/<engagement>/<run_id>/ by default and include targets.jsonl, evidence.jsonl, results.sarif, and report.md.

Evidence viewer:

casm evidence --path runs/<engagement>/<run_id>/evidence.jsonl --type http_response --tool http_verify --limit 20

Whole-line search (default contains scope):

casm evidence --path runs/<engagement>/<run_id>/evidence.jsonl --contains localhost:8444

Field-limited search (error scope only):

casm evidence --path runs/<engagement>/<run_id>/evidence.jsonl --contains "tls:" --contains-scope error

Show only today's http errors:

casm evidence --path runs/<engagement>/<run_id>/evidence.jsonl --type http_error --since 2026-02-01T00:00:00Z

Show a narrow window around an incident:

casm evidence --path runs/<engagement>/<run_id>/evidence.jsonl --since 2026-02-01T17:34:00Z --until 2026-02-01T17:36:00Z

Timestamps follow RFC3339; if no timezone is provided, UTC is assumed.


Quick Start

# Install from PyPI
pip install g2cv-casm

# Or install from source checkout
pip install -e .

# Scan your infrastructure
casm run unified --config scopes/scope.yaml --targets-file targets/target-harness.example.json

# Compare to previous run
casm diff --old runs/baseline/results.sarif --new runs/current/results.sarif

Evidence model (what you can rely on)

Evidence is written as JSONL (one JSON object per line). Key fields include:

  • engagement_id, run_id
  • tool_name, tool_version
  • type (e.g., tcp_connect, run_result)
  • target (e.g., example.com:443)
  • timestamp (UTC)
  • status (success|timeout|error|blocked)
  • duration_ms
  • data (structured, redacted)
  • data.canonical_url (stable, normalized URL for comparisons)
  • data.finding_fingerprints (stable identifiers for findings tied to the event)
  • schema_version (semantic version for evidence schema)
  • SARIF properties.severity is set per rule, and SARIF level maps to that severity
  • SARIF includes properties.schema_version at the top level and per run

A centralized redaction step is applied to evidence data and persisted tool logs to scrub obvious secrets.


Reporting & exports

  • The Markdown report is dual-audience:
    • Executive Summary (metrics + top recommendation)
    • Technical Summary, Scope & Method, Limitations, Assets Observed, Findings, Telemetry
  • Findings are grounded in evidence IDs for traceability.
  • SARIF 2.1.0 export includes normalized findings only (not telemetry-only events).

Migration:

casm migrate --input runs/<engagement>/<run_id> --out runs/<engagement>/<run_id>-migrated

Configuration

Environment defaults are documented in .env.example.

Key scope fields (see scopes/scope.yaml):

  • seed_targets: initial hostnames
  • allowed_domains, allowed_ips
  • allowed_ports, allowed_protocols
  • max_rate, max_concurrency
  • per_attempt_timeout_ms, tool_timeout_ms
  • active_allowed, auth_allowed

Development notes

For development workflow, see CONTRIBUTING.md.

Versioning

Release versioning is tag-driven (vMAJOR.MINOR.PATCH).


License

CASM is licensed under the GNU Affero General Public License Version 3 (AGPLv3).

This means:

  • ✅ Free to use and modify
  • ✅ Free for internal use
  • ✅ Must share modifications if you run CASM as a network service
  • ✅ Commercial licenses available for proprietary use

For commercial licensing inquiries: contact@g2cv.com

Copyright (C) 2026 G2CV Solutions

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

g2cv_casm-0.1.1.tar.gz (142.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

g2cv_casm-0.1.1-py3-none-any.whl (87.3 kB view details)

Uploaded Python 3

File details

Details for the file g2cv_casm-0.1.1.tar.gz.

File metadata

  • Download URL: g2cv_casm-0.1.1.tar.gz
  • Upload date:
  • Size: 142.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for g2cv_casm-0.1.1.tar.gz
Algorithm Hash digest
SHA256 2fe74e86bee86ae5487c6d9e0c121de0a2281697f71fa486c2966ce448b41f25
MD5 fa921c71bfe835ca36241798e6094ce6
BLAKE2b-256 37ab13333d13e16916602cf9a6c46ff090d5acdb4f86342f75f13c6d0d037266

See more details on using hashes here.

File details

Details for the file g2cv_casm-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: g2cv_casm-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 87.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.3

File hashes

Hashes for g2cv_casm-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 207f184863fbdc9d753c3a5272df7eaa6e8f1f2363ab6eaf8b72212ee29a93db
MD5 de726821dc5a87bbb2f66448fddf06ce
BLAKE2b-256 049465f6ed652812cd2eab9cee47463bf4dca3994576b2af376917b6498a9a54

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page