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.

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
HTTP HTTPS reachability, HTTP to HTTPS redirect, security-header presence and value quality, security.txt, cookie flags, 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, MTA-STS, 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 (available once the first release is published, see RELEASING.md):

pip install 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

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.2.0.tar.gz (68.7 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.2.0-py3-none-any.whl (60.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for sentineldeck-0.2.0.tar.gz
Algorithm Hash digest
SHA256 0cad0040349147637ccba080a94acb85f25410968ecd6b32d2f7835645df5ec8
MD5 3788afa98152f8271baca1d5a5f768f8
BLAKE2b-256 9c7db77266275dbc84ee91610208c7276decdd157bcf13ec6a61f57feefd0674

See more details on using hashes here.

Provenance

The following attestation bundles were made for sentineldeck-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: sentineldeck-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 60.6 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 669eb9b6de3a81754ac1b2042b9651a3838dc1d389119b5b68823ac4963c96e9
MD5 c62b2bda123b44acd84d40478efa3f4f
BLAKE2b-256 190ffd51169961136efed0cbadf5c70bc89e5882a20b5399b1d3db4c5e934f04

See more details on using hashes here.

Provenance

The following attestation bundles were made for sentineldeck-0.2.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