Skip to main content

Passive attack-surface visibility and client-ready security reports for small businesses.

Project description

SentinelDeck

Passive attack-surface radar for small businesses, agencies, and security consultants.
One safe scan turns a domain into a clear risk grade, structured JSON, and a client-ready report.

Scan any domain you are authorised to assess in one line. Nothing to install:

pipx run sentineldeck scan example.com        # or:  uvx sentineldeck scan example.com

Prefer a permanent install? pip install -U sentineldeck, then sentineldeck scan example.com.

SentinelDeck scanning a domain: grade, findings, and a copy-paste fix

Testing tests
Code quality security pre-commit
Code style ruff typed
Package pypi downloads status python license
Safety passive security policy

SentinelDeck inspects the public-facing posture of a domain across DNS, HTTP, TLS, email authentication, and its certificate-transparency footprint, using only the kind of normal lookups any browser or mail server would make. There is no intrusive scanning, no exploitation, and nothing a domain owner would not expect. The result is a risk score, an A to F grade, and a set of prioritised findings, each with a concrete copy-paste fix.

It is built for the people who need that picture fast: an agency qualifying a prospect, a consultant producing a client report, or a small team checking its own footprint.

Contents

Features

Passive and safe by design

Only standard DNS, HTTP, TLS, and email lookups, the same requests any browser or mail server makes. Run it against any domain you are authorised to assess.

Accurate, with a confidence model

DNS is resolved in-process and certificates are parsed directly. Any check that cannot be confirmed is marked unverified and kept out of the score, so a client never sees a guess presented as fact.

Five surfaces in one pass

DNS hygiene, HTTP security headers, TLS certificate quality, email authentication, and domain registration intelligence, scored together into a single picture.

Clear risk score and grade

Every finding is weighted by severity into a 0 to 100 risk score and an A to F grade, each paired with a prioritised, plain-language remediation step.

Copy-paste remediation

Every finding ships the exact fix, not just advice: the precise DNS record, HTTP header, or server config that resolves it, each with an authoritative reference. Carried in both the JSON and the HTML report.

Interactive remediation simulator

The HTML report lets a client tick off the fixes they plan to make and watch the projected score and grade climb live, with one-click "quick wins" that picks the shortest path to grade A.

Attack-surface mapping

Reads certificate transparency logs to discover the domain's public subdomains, flags potentially sensitive names (dev, staging, admin, vpn), and detects dangling CNAMEs an attacker could take over.

Monitoring and alerts

Diff any two scans, or run the monitor command on a schedule to scan, compare against the last run, and post a webhook alert (Slack, Discord, or custom) the moment a domain's posture regresses.

Report-ready outputs

Structured JSON for automation, a polished dark and red HTML report for clients, a shareable score card, an embeddable grade badge, and an HTML change report.

Resilient by design

Two certificate-transparency sources (crt.sh with a CertSpotter fallback) and a DNS-over-HTTPS fallback for blocked networks, so a scan keeps working where a naive tool would silently fail.

What it checks

Area Checks
DNS Resolution, CAA issuance control, DNSSEC, nameserver redundancy, IPv6 (AAAA) readiness, DANE/TLSA
HTTP HTTPS reachability, HTTP to HTTPS redirect, security headers + value quality, CORS policy, cookie flags + SameSite, Cross-Origin-Opener-Policy, security.txt, version disclosure
TLS Trust and failure reason (expired, self-signed, hostname mismatch, untrusted), expiry, protocol version, key strength, signature algorithm, hostname match
Email MX, SPF (policy, multiple records, 10-lookup limit), DMARC (policy, subdomain policy, enforcement coverage), DKIM (presence + key strength), MTA-STS (record + policy validation), TLS-RPT, BIMI
Domain Registrar, registration age, and expiry via RDAP
Subdomains Public subdomain discovery via certificate transparency (crt.sh, CertSpotter), sensitive-name flagging, and dangling-CNAME takeover detection

Every issue is scored by severity into a 0 to 100 risk score and an A to F grade.

Installation

SentinelDeck requires Python 3.10 or newer.

From PyPI:

pip install -U sentineldeck

From source:

git clone https://github.com/sanmaxdev/SentinelDeck.git
cd SentinelDeck
python3 -m venv .venv
. .venv/bin/activate            # Windows: .venv\Scripts\activate
pip install -e .

Either way, this puts the sentineldeck command on your path. To verify:

sentineldeck --version

For development, install the dev extras (pytest and ruff):

pip install -e ".[dev]"

Usage

Run sentineldeck with no arguments at any time for a colored overview of the commands and examples.

Scan a domain and write a JSON report:

sentineldeck scan example.com --output reports/example.json

An interactive scan streams each surface as it is checked, and the absolute path of every file it writes is printed when the scan finishes. You can render the client-ready HTML report in the same step:

sentineldeck scan example.com --html reports/example.html

List every check, or get the copy-paste fix for a single finding, without running a scan:

sentineldeck checks
sentineldeck explain dmarc-missing

Accept findings you have already reviewed so they stop affecting the score, by listing their ids in a suppressions file:

sentineldeck scan example.com --suppress .sentineldeck-ignore

Each line is a finding id (globs allowed, e.g. subdomain-takeover:*), and # starts a comment. Accepted findings still appear under "Accepted" in the report but are kept out of the risk score, so a known and accepted risk does not drag the grade down on every re-scan.

Render a client-ready HTML report, a shareable score card, and a badge. The HTML report includes the attack-surface map and the interactive remediation simulator:

sentineldeck report reports/example.json \
  --html reports/example.html \
  --svg  reports/example-card.svg \
  --badge reports/example-badge.svg

Track how a domain's posture changes between two scans:

sentineldeck diff reports/example-may.json reports/example-june.json \
  --html reports/example-change.html

The diff command shows what is new, what was resolved, score and grade movement, and any severity escalations. It exits non-zero with --exit-code when the posture regresses (a new high or critical finding, or a higher score), so it drops straight into a cron job or CI step for scheduled monitoring.

Watch a domain on a schedule and get alerted when it regresses:

sentineldeck monitor example.com --webhook https://hooks.slack.com/services/...

The monitor command scans, compares against the previous run (stored under .sentineldeck/ by default), and saves the new report as the latest, so a cron job or scheduled task becomes a standing watch. With --webhook it posts an alert (Slack, Discord, or any custom endpoint) when the posture regresses. The first run establishes a baseline; use --alert-on change to hear about any change, and --exit-code to fail a job on regression.

Useful flags: --pretty prints the full JSON to stdout, --timeout bounds the HTTP and TLS probes, and diff --json or diff -o emit the structured delta.

Example output

{
  "target": "example.com",
  "risk_score": 27,
  "grade": "B",
  "findings": [
    { "id": "dmarc-missing", "severity": "medium", "confidence": "confirmed", "...": "..." }
  ]
}

How it works

src/sentineldeck/
├── scanner.py          # runs every probe concurrently and assembles the report
├── scanners/           # one module per surface: dns, dns_hygiene, tls, http_headers,
│                       #   email_security, domain_intel, subdomains, takeover
├── risk/scoring.py     # turns raw check results into scored findings
├── remediation.py      # maps each finding to a concrete copy-paste fix
├── diff.py             # compares two reports into a structured change delta
├── monitor.py          # scan, compare to the last run, and persist state
├── alerts.py           # webhook delivery on regression
├── reporters/          # json, html, svg (card + badge), and diff renderers
└── models.py           # Finding and ScanReport data models

Each scanner is independent and keeps its network call injectable, so the whole suite is tested offline with mocked DNS, HTTP, and certificate-transparency data.

Development

pip install -e ".[dev]"
ruff check .
pytest -q

Optionally enable the pre-commit hooks so linting runs on every commit:

pip install pre-commit && pre-commit install

CI runs ruff and the full test suite on Python 3.10, 3.11, and 3.12, and CodeQL scans the codebase for security issues on every push.

Safety model

SentinelDeck is passive-first. It performs only normal DNS lookups and standard HTTP and TLS metadata requests against the supplied domain, plus public certificate-transparency queries. It does not probe, fuzz, or exploit anything. Use it only on domains you own or are authorised to assess.

Support

License

MIT

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

sentineldeck-0.4.0.tar.gz (76.8 kB view details)

Uploaded Source

Built Distribution

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

sentineldeck-0.4.0-py3-none-any.whl (66.7 kB view details)

Uploaded Python 3

File details

Details for the file sentineldeck-0.4.0.tar.gz.

File metadata

  • Download URL: sentineldeck-0.4.0.tar.gz
  • Upload date:
  • Size: 76.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sentineldeck-0.4.0.tar.gz
Algorithm Hash digest
SHA256 6be3d2219dc127b126c16221b364e959ec5104e748d89f70b79c8a8a6c5010e0
MD5 7693fe9c24e659ca2250643391566929
BLAKE2b-256 c1a87f4cc82c9d340c2cf4c691f9cd87acd13c726b484959a4582b95e1d57753

See more details on using hashes here.

Provenance

The following attestation bundles were made for sentineldeck-0.4.0.tar.gz:

Publisher: publish.yml on sanmaxdev/SentinelDeck

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sentineldeck-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: sentineldeck-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 66.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for sentineldeck-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 9a4952f9deb8114bc9d1ba48826a8261184c4f6ac74abfae89a2ebe3a99f7c4a
MD5 120cc130ff84c388a640f79c33d88194
BLAKE2b-256 ed8376873a5d44ac7a9013cc8fd53d133bd9fb413656e699b583ccf5fb7042d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for sentineldeck-0.4.0-py3-none-any.whl:

Publisher: publish.yml on sanmaxdev/SentinelDeck

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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