Presidio security-hardened distribution of ScoutSuite — runs the multi-cloud auditor out of process with hardened defaults, report redaction, and a least-privilege deployment model.
Project description
presidio-hardened-scoutsuite
A Presidio security-hardened distribution of ScoutSuite, NCC Group's multi-cloud security auditing tool.
Wrapper, not a fork. ScoutSuite is GPL-2.0. Rather than fork or import it, this project drives the upstream
scoutCLI out of process and wraps it with hardened defaults, report redaction, supply-chain integrity, and a least-privilege deployment model. That keeps the wrapper a separate, non-derivative work — so this code is MIT — while you still run stock, trusted-upstream ScoutSuite underneath. SeeLICENSES/README.md.
What "hardened" means here
| Axis | What you get |
|---|---|
| Runtime credential & data safety | Env scrubbed to cloud creds only; 0700 report dir + umask 0077; secrets redacted out of the report and ScoutSuite's logs; --fail-on-secret gate |
| Report integrity & isolation | Strict CSP + Subresource Integrity on local report assets; remote-reference detection (--fail-on-remote-ref); a signed-able SHA-256 integrity manifest verified offline with presidio-scout-verify |
| Secure-by-default policy | Curated, CIS-aligned AWS baseline ruleset applied by default (high-impact IAM/logging/network controls forced to danger) |
| Supply-chain & build integrity | Hash-pinned requirements.lock, pinned build backend, CycloneDX SBOM, CodeQL, Dependabot, cosign-signed images + SLSA build provenance, reproducible wheel/sdist, a presidio-scout-verify-provenance policy gate for what you pull, a fail-closed preflight that the scout you run is the pinned, vetted ScoutSuite version, and a release vulnerability-scan gate (pip-audit + Trivy + presidio-scout-vuln-gate) with signed SBOM/provenance attestations |
| Hardened deployment | Distroless, non-root, --read-only container; bundled least-privilege AWS audit role (read-only + explicit Deny, MFA + ExternalId trust); hardened Kubernetes Job/CronJob + Helm chart (workload identity, read-only rootfs, dropped caps, seccomp, default-deny NetworkPolicy) |
How it works
presidio-scout aws ──▶ launcher ──▶ [ scout aws … ] ──▶ redact ──▶ report_guard ──▶ report/
(validate (subprocess; (scrub (CSP + integrity
+ harden) env-scoped) secrets) manifest)
- launcher — validates the provider + pass-through flags (fail-closed
allowlist), forces
--no-browserand a locked-down--report-dir, wires in the curated ruleset, and scrubs the environment. - preflight — before any credentials are handed over, a fail-closed gate
confirms the
scouton PATH is the pinned, vetted ScoutSuite version; an unexpected/modified ScoutSuite is refused (override:--allow-unverified-scout). - subprocess — stock ScoutSuite runs with only the cloud credentials it needs.
- redact — credentials are scrubbed out of the report files and ScoutSuite's own output.
- report_guard — a strict CSP and per-asset Subresource Integrity hashes
are injected into the HTML report, network-reaching references are flagged,
and a SHA-256 integrity manifest (
presidio-report-manifest.json, optionally HMAC-signed) is written so the report can be verified later withpresidio-scout-verify.
Install
The wrapper has effectively no runtime dependencies (only the tiny tomli
TOML parser, and only on Python < 3.11; 3.11+ uses the stdlib) and never imports
ScoutSuite. You supply scout yourself (recommended: a pinned virtualenv or the
container).
pip install presidio-hardened-scoutsuite # wrapper only (MIT)
# Convenience extra that also installs ScoutSuite (GPL-2.0) into your env:
pip install 'presidio-hardened-scoutsuite[scoutsuite]'
Or use the hardened container (bundles a pinned ScoutSuite):
docker run --rm --read-only --tmpfs /tmp \
-e AWS_PROFILE=auditor \
-v "$HOME/.aws:/tmp/.aws:ro" \
-v "$PWD/scoutsuite-report:/report" \
ghcr.io/presidio-v/presidio-hardened-scoutsuite:latest \
aws --report-dir /report
CLI usage
presidio-scout aws # audit AWS with the hardened defaults
presidio-scout aws --report-dir ./out # choose the (0700) report directory
presidio-scout aws -- --profile auditor # pass-through flags after '--' (allowlisted)
presidio-scout aws --fail-on-secret # non-zero exit if a secret survives redaction
presidio-scout aws --fail-on-remote-ref # non-zero exit if the report references a remote resource
presidio-scout aws --fail-on-finding danger # exit 4 if any flagged finding is danger (gate a pipeline)
presidio-scout aws --sarif results.sarif # also emit SARIF for GitHub code scanning
presidio-scout aws --waivers waivers.json --fail-on-finding danger # suppress accepted findings
presidio-scout aws --attest run.intoto.json # emit a signed-able run attestation
presidio-scout aws --require-short-lived-creds # refuse to run with long-lived static keys
presidio-scout --profile nightly # apply org defaults from .presidio-scout.toml
presidio-scout aws --no-baseline # use ScoutSuite's default ruleset instead
presidio-scout aws --allow-unverified-scout # run even if scout isn't the pinned version (warns)
presidio-scout aws --dry-run # print the hardened command, run nothing
presidio-scout azure # Azure audit with the hardened Azure baseline
presidio-scout gcp # GCP audit with the hardened GCP baseline
AWS, Azure, and GCP each ship a curated baseline; other providers fall back to ScoutSuite's default ruleset (with a warning) until their baselines land.
Anything after -- is forwarded to ScoutSuite only if it's on the
pass-through allowlist (--profile, --region(s), --services, --skip,
--max-rate, …). Flags the launcher owns (--report-dir, --ruleset,
--no-browser) and unknown flags are rejected with exit code 2 — a new upstream
flag can't silently weaken a run until it's vetted and added.
Exit codes: 0 ok · 2 invalid invocation / scout not found / unverified
ScoutSuite · 3 report guard failure (e.g. --fail-on-secret) · 4 findings
severity threshold exceeded (--fail-on-finding).
Library usage
from presidio_scoutsuite import build_plan, run, redact_report_dir, guard_report
plan = build_plan("aws", "scoutsuite-report", ruleset="src/presidio_scoutsuite/policy/aws-cis.json")
print(plan.redacted_command()) # scout aws --no-browser --report-dir … --ruleset …
result = run(plan) # subprocess.CompletedProcess
redact_report_dir(plan.report_dir) # scrub secrets out of the report
guard = guard_report(plan.report_dir) # CSP + SRI + write integrity manifest
print(len(guard.manifest), "files;", len(guard.sri_hardened), "SRI-pinned")
Report integrity & verification
Every guarded report carries presidio-report-manifest.json: a SHA-256 over
each file plus a self-digest of those hashes. Verify a report offline — no
ScoutSuite, no network — at any later point:
presidio-scout-verify ./scoutsuite-report
# ok verified 214 file(s) in scoutsuite-report
The verifier re-hashes the tree and reports any modified, missing, or
added file, and detects edits to the manifest's own recorded hashes. Exit
codes: 0 verified · 3 tampered/mismatch · 2 no usable manifest.
Signing. Two layers, both optional and independent of the always-on hashes:
- HMAC (pipeline integrity). Set
PRESIDIO_MANIFEST_HMAC_KEYand the manifest gains an HMAC-SHA256 signature; verification on a host with the same key confirms the manifest came from your pipeline. Symmetric — proves provenance within a trust boundary you control, not non-repudiation. - Detached cosign (distribution). For third-party verification, sign the
manifest blob out of band exactly as the release pipeline signs images:
cosign sign-blob scoutsuite-report/presidio-report-manifest.json.
Beyond the manifest, the guard makes the static report safe to open and fully
offline: a strict CSP (default-src 'none', no remote/inline script),
Subresource Integrity on every local <script>/stylesheet (the browser refuses
a tampered local asset), and detection of any network-reaching reference
(--fail-on-remote-ref turns one into a non-zero exit).
Signed run attestation
presidio-scout aws --attest run.intoto.json (or presidio-scout-attest generate) emits an in-toto statement about the run itself: its subject is
the report's integrity manifest (by SHA-256), and its predicate records the
inputs — provider, the curated ruleset's digest, the verified ScoutSuite
version, this wrapper's version, the manifest's content digest, and finding
counts. Sign it as a blob for a complete, portable record:
cosign sign-blob run.intoto.json --output-signature run.intoto.json.sig
presidio-scout-attest verify ./scoutsuite-report run.intoto.json # binding check
This chains the layers: report files → manifest (presidio-scout-verify) →
attestation subject (this) → signature. presidio-scout-attest verify confirms
the statement still describes the report on disk (subject + manifest digest
match); cosign confirms the signature. Together they prove this exact report
was produced by this provider, with this ruleset, by this vetted ScoutSuite.
Gating a pipeline on findings
ScoutSuite writes machine-readable results next to the report; the wrapper reads
that data (it's data, not ScoutSuite code) and turns the flagged findings
(flagged_items > 0) into a severity-ranked model. Use it to fail a pipeline on
the audit result — inline during a run, or after the fact:
presidio-scout aws --fail-on-finding danger # exit 4 if any danger-level finding fired
presidio-scout-findings ./scoutsuite-report # summarize an existing report
presidio-scout-findings ./scoutsuite-report --fail-on warning --format json
# findings [aws]: 7 flagged (danger=2, warning=5)
Levels rank danger > warning; --fail-on <level> trips on anything at or
above it. The gate is fail-closed: if the results data is missing or
unparseable it errors (exit 2) rather than passing a report it never evaluated.
Waiving accepted findings
Findings an org has reviewed and consciously accepted are checked in as data — each with a justification, an owner, and a mandatory expiry — instead of being hidden by weakening the ruleset:
{
"waivers": [
{ "rule": "s3/s3-bucket-world-acl", "resource": "s3.buckets.public-assets",
"justification": "Public static-site bucket, reviewed in TICKET-123",
"owner": "web-platform@example.com", "expires": "2026-12-31" }
]
}
presidio-scout aws --waivers waivers.json (also on presidio-scout-findings
and presidio-scout-export) suppresses matching findings before the gate and
SARIF output. Omit resource (or use "*") to waive the whole finding; a
resource pattern (fnmatch) waives only those resources and the finding
survives with a reduced count if any flagged resource is left unwaived.
Fail-closed: a malformed/missing waiver file errors, and an expired
waiver stops suppressing — the finding resurfaces (and is reported) — so risk
can't be hidden indefinitely.
GitHub code scanning (SARIF)
Export the flagged findings as SARIF 2.1.0 so they surface as code-scanning
alerts (tracked and triageable in the Security tab) — inline during a run
(--sarif PATH) or from an existing report (presidio-scout-export):
# .github/workflows/cloud-audit.yml (excerpt)
- run: presidio-scout aws --report-dir ./report --sarif results.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
danger maps to SARIF error (security-severity 8.0 / high), warning to
warning (4.0 / medium); each flagged resource becomes a result with a stable
fingerprint so GitHub tracks the same alert across runs.
Compliance mapping (CIS / NIST 800-53 / SOC 2)
Express the audit as control failures, not just raw findings.
presidio-scout-compliance maps each flagged finding to the controls it breaks
across CIS, NIST SP 800-53 Rev. 5, and the SOC 2 Trust Services Criteria, using
curated, checked-in mappings (policy/<provider>.controls.json):
presidio-scout-compliance ./report # per-control summary
presidio-scout-compliance ./report --framework cis --format json
presidio-scout-compliance ./report --fail-on-unmapped # exit 4 if a finding has no mapping
The mappings are validated fail-closed against the rule manifest (a mapping
that names a rule the pinned ScoutSuite doesn't ship errors in CI), and a flagged
finding with no mapping is reported as unmapped rather than silently dropped.
AWS Security Hub (ASFF)
Send findings to Security Hub as ASFF (BatchImportFindings input), enriched
with the compliance controls as Compliance.RelatedRequirements — inline
(--asff PATH) or from an existing report (presidio-scout-asff):
presidio-scout aws --report-dir ./report \
--asff findings.asff.json --aws-account-id 123456789012 --aws-region us-east-1
aws securityhub batch-import-findings --findings file://findings.asff.json
danger maps to HIGH (Normalized 70), warning to MEDIUM (40); each flagged
resource becomes one ASFF finding with a stable Id.
Tracking drift between runs
Gating on the absolute set of findings is noisy when there's a known,
already-triaged backlog. presidio-scout-diff compares a baseline report to
a current one and reports only what changed — so a pipeline can block
regressions while ignoring pre-existing findings:
presidio-scout-diff ./baseline-report ./scoutsuite-report --fail-on-new-finding danger
# drift: +1 new finding(s), +2 new resource(s); -3 resolved finding(s), -0 resolved resource(s)
It diffs at resource granularity, distinguishing a brand-new finding from an
existing finding that started flagging an additional resource, and from
resolved findings/resources. --fail-on-new-finding {any,warning,danger} exits
4 when a newly flagged occurrence is at or above the chosen severity
(--format json for the full structured delta).
Verifying what you pull
Release artifacts carry SLSA build provenance (the container image is
cosign-signed with provenance: mode=max; the PyPI wheel ships attestations),
and the wheel/sdist are a reproducible function of the source.
A signature only proves an attestation is authentic — you still have to check
it says the right thing. presidio-scout-verify-provenance is that policy
gate, run after cosign has cryptographically verified the attestation:
# 1. cosign verifies the signature + transparency-log entry (crypto + network)
cosign verify-attestation --type slsaprovenance \
--certificate-identity-regexp '^https://github.com/presidio-v/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/presidio-v/presidio-hardened-scoutsuite@sha256:DIGEST \
--output text > prov.jsonl
# 2. presidio enforces the policy: built by this repo's CI, from this source,
# for this exact digest (exit 0 verified · 3 policy mismatch · 2 unparseable)
presidio-scout-verify-provenance prov.jsonl --digest sha256:DIGEST
It understands both SLSA provenance v0.2 (buildx) and v1 (slsa-github-generator)
predicates — and reads a bare statement, a DSSE envelope, cosign's JSON-Lines, or
the output of gh attestation verify --format json — and checks the builder
identity, source repository, predicate type, and that the artifact
digest is actually attested. Override the expected source/builder with
--source-uri / --builder-id-prefix.
Container image. The released image is multi-arch (linux/amd64 +
linux/arm64) with timestamps pinned to the tagged commit (reproducible
digests), cosign-signed, and carries GitHub-signed SLSA build provenance. The
release pipeline re-verifies the freshly published image end-to-end before the
run is marked good; you can do the same:
cosign verify ghcr.io/presidio-v/presidio-hardened-scoutsuite@sha256:DIGEST \
--certificate-identity-regexp '^https://github.com/presidio-v/.*release\.yml@refs/tags/v' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
gh attestation verify oci://ghcr.io/presidio-v/presidio-hardened-scoutsuite@sha256:DIGEST \
--repo presidio-v/presidio-hardened-scoutsuite --format json \
| presidio-scout-verify-provenance - --digest sha256:DIGEST
# a signed CycloneDX SBOM is attached too:
gh attestation verify oci://ghcr.io/presidio-v/presidio-hardened-scoutsuite@sha256:DIGEST \
--repo presidio-v/presidio-hardened-scoutsuite --predicate-type https://cyclonedx.org/bom
Vulnerability gate. Before a release is accepted, the locked dependency tree
is audited (pip-audit) and the published image is scanned (Trivy); the scan is
gated by presidio-scout-vuln-gate, which fails closed on any fixable
vulnerability at or above a chosen severity. It reads a Trivy or Grype JSON
report, so you can run the same gate locally:
trivy image --format json ghcr.io/presidio-v/presidio-hardened-scoutsuite:vX > scan.json
presidio-scout-vuln-gate scan.json --fail-on critical --ignore-unfixed # exit 4 if any remain
Reproducible build. Builds are pinned to the tagged commit's timestamp
(SOURCE_DATE_EPOCH), so anyone can rebuild from the same commit and confirm
the wheel is byte-identical to what was published — and CI fails the
reproducible-build job if two builds diverge:
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) python -m build
sha256sum dist/*.whl # compare against the published wheel's digest
(The .tar.gz sdist is reproducible at the content level; its gzip container
carries an mtime that isn't part of the archived files, so compare it with
gzip -dc dist/*.tar.gz | sha256sum rather than the raw bytes — which is exactly
what the CI gate does.)
Least-privilege audit identities
ScoutSuite needs broad read-only access. Bundled, ready-to-apply identities grant exactly that and nothing else, per cloud:
- AWS (
iam/aws/) — the two managed read-only policies, a supplemental read policy with an explicitDenyon any non-read action, and a trust policy requiring MFA + a randomExternalId. - Azure (
iam/azure/) —Reader+Security Reader(or a custom*/readrole with nodataActions, so secret/key values stay unreadable), plus minimal directory read for the Azure AD findings. - GCP (
iam/gcp/) —roles/viewer+roles/iam.securityReviewer(or a custom role listing only*.list/*.getpermissions), assumed via service-account impersonation over a downloaded key.
Keyless / short-lived credentials
The wrapper doesn't broker credentials itself — ScoutSuite's bundled cloud SDKs
already resolve assumed roles, OIDC, impersonation, and managed identity. What it
adds is a fail-closed preflight: presidio-scout … --require-short-lived-creds
refuses to run when the (scrubbed) environment carries a long-lived static
secret — an AWS access key with no session token, a downloaded GCP
service-account key, or an Azure client secret — pushing you onto short-lived
credentials that pair with the bundled audit roles. Without the flag, a static
secret is allowed but warned about. (An "unknown" posture — e.g. an
AWS_PROFILE that may itself assume a role — never blocks.)
Recommended keyless setups:
- AWS — a profile that assumes the audit role (
role_arn+source_profilemfa_serial+external_id) so the SDK vends temporary creds; or, in CI, GitHub OIDC →AWS_ROLE_ARN+AWS_WEB_IDENTITY_TOKEN_FILE(no stored keys).
- GCP — service-account impersonation
(
CLOUDSDK_AUTH_IMPERSONATE_SERVICE_ACCOUNT) or Workload Identity Federation (external_account), never a downloaded key. - Azure — managed identity (
IDENTITY_ENDPOINT/MSI_ENDPOINT, passed through to the child) or workload-identity federation (AZURE_FEDERATED_TOKEN_FILE), not a client secret.
# CI: GitHub OIDC → assume the AWS audit role, then run with no long-lived keys
permissions: { id-token: write, contents: read }
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::<acct>:role/presidio-scoutsuite-auditor
aws-region: us-east-1
- run: presidio-scout aws --report-dir ./report --require-short-lived-creds
Org config & profiles
Check in your hardened defaults once instead of repeating flags in every
pipeline. A .presidio-scout.toml in the repo root (auto-discovered, or pass
--config) supplies defaults; a [profiles.<name>] table overlays them with
--profile; and explicit CLI flags always win over both.
# .presidio-scout.toml
[defaults]
provider = "aws"
require-short-lived-creds = true
fail-on-secret = true
waivers = "security/scout-waivers.json"
[profiles.nightly]
fail-on-finding = "danger"
sarif = "scoutsuite-report/results.sarif"
presidio-scout --profile nightly # provider + gates come from the config
presidio-scout-policy validate # fail-closed check of the org config
presidio-scout-policy show --profile nightly # print the resolved settings
presidio-scout-policy validate rejects unknown sections/keys, wrong types, and
out-of-range values (an unknown provider or severity), so a typo in org policy
fails loudly. See .presidio-scout.toml.example.
Keep ScoutSuite current (upgrade automation)
The pinned ScoutSuite version underpins every gate — the install-integrity
preflight, the hash-pinned lockfile, and the rule inventory the baselines
validate against. That version is declared in several files that must agree;
presidio-scout-upgrade makes coherence a fail-closed gate and bumps reviewable.
presidio-scout-upgrade check # all pin sites must agree (exit 4 on drift)
presidio-scout-upgrade current # the authoritative pinned version
presidio-scout-upgrade plan --to 5.15.0 # ordered, reviewable bump steps
presidio-scout-upgrade apply --to 5.15.0 # apply the offline text pins only
apply does only the deterministic in-repo edits (the scoutsuite extra and the
install-integrity constant); regenerating the hash-pinned requirements.lock
(needs PyPI) and the rule manifests (needs the installed ScoutSuite) is done by
the scheduled scout-upgrade workflow,
which runs the whole sequence, all gates, and opens a PR — nothing merges without
review. The pin-coherence CI job runs presidio-scout-upgrade check on every
push so the pin sites can never silently drift.
Run in Kubernetes
Hardened in-cluster manifests and a Helm chart live under
deploy/: a one-shot Job or scheduled CronJob that runs the
signed image as a least-privilege workload-identity ServiceAccount (no
long-lived keys), with readOnlyRootFilesystem, all capabilities dropped,
seccompProfile: RuntimeDefault, automountServiceAccountToken: false, a
default-deny NetworkPolicy (egress only DNS + 443), and --fail-on-finding danger so a finding fails the Job.
kubectl apply -f deploy/kubernetes/ # annotate serviceaccount.yaml for your cloud first
# or, with Helm:
helm install nightly deploy/helm/presidio-scout \
--set provider=aws --set schedule="0 6 * * *" \
--set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=arn:aws:iam::<acct>:role/presidio-scoutsuite-auditor
See deploy/kubernetes/README.md for per-cloud
workload-identity annotations (IRSA / GKE WI / Azure WI) and NetworkPolicy
tightening.
Curated rulesets
Curated baselines ship for AWS, Azure, and GCP under
src/presidio_scoutsuite/policy/
(aws-cis.json, azure-cis.json, gcp-cis.json). Each enables a CIS-aligned
subset of ScoutSuite's findings and elevates the high-impact ones to danger.
Override with --ruleset PATH or opt out with --no-baseline.
A ruleset's keys are the filenames of finding rules that live inside
ScoutSuite. If a baseline names a rule the pinned ScoutSuite doesn't ship (a typo
or an upstream rename), ScoutSuite silently drops that control. To catch that,
each provider ships a rule-name inventory (policy/<provider>.rules.txt) tracking
the pinned upstream version, and a validator checks the baselines against it:
presidio-scout-validate # offline: baselines ⊆ checked-in manifests (runs in CI)
presidio-scout-validate --source installed # release: baselines ⊆ the installed ScoutSuite
CI runs the offline check on every push; the release pipeline runs the
installed check against the pinned ScoutSuite so the manifest can't drift from
upstream unnoticed. Regenerate the manifests from an installed ScoutSuite with
presidio-scout-validate --regenerate --source installed (the upgrade workflow
does this automatically on a version bump).
Roadmap
| Version | Highlights |
|---|---|
| 0.1.0 | Out-of-process hardened launcher, report redaction + guard, AWS-first curated ruleset + least-privilege IAM, hardened container, full supply-chain posture |
| 0.2.0 | Azure + GCP curated baselines & least-privilege IAM; ruleset rule-name validation against the pinned ScoutSuite (offline manifest in CI, installed-source drift check at release) |
| 0.3.0 | Deeper report guard — Subresource Integrity on local assets, offline-viewer (remote-reference) enforcement, and a signed-able, offline-verifiable report manifest (presidio-scout-verify) |
| 0.4.0 | SLSA build-provenance policy verification (presidio-scout-verify-provenance, v0.2 + v1) and a reproducible wheel/sdist with a reproducible-build CI gate |
| 0.5.0 | ScoutSuite install-integrity gate — fail-closed preflight that the scout you run is the pinned, vetted version (--allow-unverified-scout to override); real hash-pinned requirements.lock; pinned build backend |
| 0.6.0 | Findings model + severity gate — presidio-scout --fail-on-finding danger|warning and the standalone presidio-scout-findings, parsed from the report data (fail-closed; exit 4) |
| 0.7.0 | SARIF export + GitHub code-scanning — presidio-scout-export and presidio-scout --sarif PATH emit SARIF 2.1.0 (severity-mapped, per-resource, stable fingerprints) |
| 0.8.0 | Waivers / exceptions framework — checked-in JSON waivers (justification + owner + expiry; resource-level globs), applied to the gate/SARIF via --waivers; expired/malformed waivers fail closed |
| 0.9.0 | Signed run attestation — in-toto statement binding run inputs (provider, ruleset digest, ScoutSuite version) to the report-manifest digest; presidio-scout --attest + presidio-scout-attest generate/verify |
| 0.10.0 | Drift detection / run diff — presidio-scout-diff compares two reports at resource granularity (new vs resolved findings), with --fail-on-new-finding {any,warning,danger} |
| 0.11.0 | Reproducible, multi-arch (amd64+arm64) container; GitHub-signed image provenance; a release verify-image gate that re-checks the signature + provenance (cosign + presidio-scout-verify-provenance) end-to-end |
| 0.12.0 | Keyless / short-lived credentials — a fail-closed --require-short-lived-creds preflight that rejects long-lived static secrets, keyless/managed-identity env passthrough, and OIDC/assume-role/impersonation setup docs (chose configuration + preflight over in-wrapper brokering) |
| 0.13.0 | Kubernetes deployment — hardened Job/CronJob + Helm chart (workload identity, read-only rootfs, dropped caps, seccomp, default-deny NetworkPolicy) under deploy/ |
| 0.14.0 | Vulnerability-scan gate (pip-audit + Trivy + presidio-scout-vuln-gate, fail-closed on fixable findings) + signed CycloneDX SBOM attestation verified alongside provenance at release |
| 0.15.0 | Org policy profiles / config — .presidio-scout.toml defaults + named profiles applied as CLI defaults, validated by presidio-scout-policy |
| 0.16.0 | ScoutSuite upgrade automation — presidio-scout-upgrade (fail-closed pin-coherence gate + reviewable bump planner/applier), --regenerate for the rule manifests, a pin-coherence CI gate, and a scheduled workflow that bumps the lockfile + manifests and opens a PR |
| 0.17.0 | Compliance mapping + ASFF export — presidio-scout-compliance maps findings to CIS / NIST 800-53 / SOC 2 controls (validated fail-closed against the manifest); presidio-scout-asff / --asff emit AWS Security Hub findings enriched with the mapped controls |
| 0.18.0 | Verified & extended provider baselines — every AWS/Azure/GCP baseline, manifest, and compliance-map rule name reconciled against the real ScoutSuite 5.14.0 source (correcting names that never existed upstream) and expanded (AWS 34 / Azure 26 / GCP 27 curated rules, incl. GKE) |
See PRESIDIO-REQ.md for the per-version rationale,
dependencies, and open design questions.
Running tests
pip install -e ".[dev]"
pytest --cov=presidio_scoutsuite --cov-report=term-missing
ruff check . && ruff format --check .
Tests run without ScoutSuite installed — the subprocess boundary is injected.
Project structure
presidio-hardened-scoutsuite/
├── src/presidio_scoutsuite/
│ ├── launcher.py # build/run the hardened scout subprocess
│ ├── redact.py # secret detection + in-place redaction
│ ├── report_guard.py # CSP + SRI injection, remote-ref detection, manifest write
│ ├── manifest.py # integrity-manifest shape, self-digest, HMAC signing
│ ├── verify.py # offline report verification (presidio-scout-verify)
│ ├── provenance.py # SLSA provenance policy gate (presidio-scout-verify-provenance)
│ ├── scout_integrity.py # pinned-ScoutSuite preflight gate
│ ├── findings.py # findings model + severity gate (presidio-scout-findings)
│ ├── sarif.py # SARIF 2.1.0 export for code scanning (presidio-scout-export)
│ ├── compliance.py # CIS/NIST/SOC2 control mapping (presidio-scout-compliance)
│ ├── asff.py # AWS Security Hub ASFF export (presidio-scout-asff)
│ ├── waivers.py # expiring findings waivers / exceptions (--waivers)
│ ├── attestation.py # in-toto run attestation (presidio-scout-attest)
│ ├── diff.py # drift detection between two runs (presidio-scout-diff)
│ ├── credentials.py # short-lived-credential preflight (--require-short-lived-creds)
│ ├── vuln.py # Trivy/Grype vulnerability gate (presidio-scout-vuln-gate)
│ ├── config.py # .presidio-scout.toml org config (presidio-scout-policy)
│ ├── ruleset.py # baseline rule-name validation (presidio-scout-validate)
│ ├── upgrade.py # ScoutSuite pin-coherence gate + bump tooling (presidio-scout-upgrade)
│ ├── cli.py # presidio-scout entrypoint
│ ├── errors.py # exception hierarchy
│ └── policy/ # curated baselines + rule manifests + provenance-policy.json
├── iam/{aws,azure,gcp}/ # least-privilege audit identities per cloud
├── deploy/ # hardened Kubernetes manifests + Helm chart
├── .presidio-scout.toml.example # org config / profiles example
├── tests/
├── Dockerfile # distroless, non-root
├── requirements.lock # hash-pinned runtime tree (incl. ScoutSuite)
├── .github/workflows/ # ci, codeql, sbom, release (cosign + provenance)
├── LICENSE # MIT (this wrapper)
└── LICENSES/README.md # GPL-2.0 notice for bundled ScoutSuite
License
MIT for this wrapper — see LICENSE. It bundles/installs ScoutSuite (GPL-2.0-only) separately; see LICENSES/README.md.
Security
See SECURITY.md.
SDLC
Developed under the Presidio hardened-family SDLC: https://github.com/presidio-v/presidio-hardened-docs/blob/main/sdlc/sdlc-report.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file presidio_hardened_scoutsuite-0.18.0.tar.gz.
File metadata
- Download URL: presidio_hardened_scoutsuite-0.18.0.tar.gz
- Upload date:
- Size: 211.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
df27ae7656eb5db37fab4b1fefd5d7595de956bd7d5352be35955c31dfc4ac2a
|
|
| MD5 |
a540d4c7e6657493c4784cc606128248
|
|
| BLAKE2b-256 |
d76610a00ad3b97db533851835e15f9b55de471b7832104fcddb59561a280a72
|
File details
Details for the file presidio_hardened_scoutsuite-0.18.0-py3-none-any.whl.
File metadata
- Download URL: presidio_hardened_scoutsuite-0.18.0-py3-none-any.whl
- Upload date:
- Size: 94.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85b2f7b7e132864fc04eb59918e9e05c173a9e71ecc4fe0a28a15e497174a228
|
|
| MD5 |
8a1c8a0d8e28643b7a60f937ac4bb131
|
|
| BLAKE2b-256 |
a1bd1ccdd940bf811ffbc739853064852434769f7e7d1ff17a3b28aa765fd274
|