cd /news/developer-tools/building-a-continuous-threat-exposur… · home topics developer-tools article
[ARTICLE · art-118705] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Building a Continuous Threat Exposure Management (CTEM) Program — Open Source, Cloud-Agnostic, and Zero Hidden Cost

A developer has detailed an open-source, cloud-agnostic continuous threat exposure management (CTEM) program that mirrors an attacker's reconnaissance to identify and remediate exposures before they become incidents. The pipeline uses tools like theHarvester, Amass, Nuclei, and TruffleHog, and the developer warns about hidden costs in native cloud posture tools and the importance of verifying open-source tool integrity, citing the March 2026 compromise of Aqua Security's Trivy scanner.

read5 min views1 publishedSep 2, 2026

Most security teams find out they're exposed the same way an attacker does — by scanning. The

difference is who gets there first. This CTEM program flips that timeline: instead of waiting for

a pentest, a bug bounty report, or an incident to reveal what's exposed, it runs the same

reconnaissance an attacker would run — continuously, against your own footprint — and turns the

output into tracked, owned remediation work before it becomes an incident.

The pipeline mirrors an actual attack chain, stage by stage:

Every major cloud provider now ships a native posture-management or "well-architected" tool —

and on paper, that's convenient. In practice, a lot of these tools quietly meter you into

consumption-based pricing for the AI/analysis layer underneath. AWS's Well-Architected Tool

review itself is free, but plug it into Bedrock-backed recommendations or continuous AI-assisted

analysis, and the bill scales with usage in a way that's hard to forecast and easy to lose track

of — a classic hidden-cost trap for a program that's supposed to be about reducing risk, not

opening a new unpredictable line item.

This toolchain takes the opposite approach on purpose:

Tool Category Function
theHarvester
OSINT / Digital Footprint Passive discovery of hosts, emails, and exposure tied to the domain
Amass / Subfinder
Attack Surface Management Enumerate every subdomain forming the external asset inventory
Naabu
Attack Surface Management Identify open ports on discovered hosts
httpx
Attack Surface Management Confirm which hosts are live and fingerprint the tech running
Nuclei
Vulnerability Assessment Detect known CVEs, misconfigurations, and exposed cloud resources via community + custom templates
TruffleHog
Secret / Credential Exposure Find live API keys and credentials leaked in code repositories
ScoutSuite
Cloud Security Posture (CSPM) Audit cloud account configuration against security best practice
BloodHound + AzureHound / AWSHound
Identity & Attack Path Analysis Map privilege-escalation and lateral-movement paths across cloud identity graphs

A word of caution before you run any of this: verify what you trust

In March 2026, Aqua Security's Trivy — one of the most widely used open-source scanners in the cloud-native ecosystem — was itself compromised. A threat actor tracked as TeamPCP force-pushed malicious tags across the trivy, trivy-action, and setup-trivy GitHub repos and published tampered Docker Hub images, turning a trusted security tool into a credential-harvesting weapon inside thousands of CI/CD pipelines. It's a sharp reminder that a CTEM pipeline built entirely on open-source tooling is only as trustworthy as your verification discipline. Ten lessons worth carrying into how you run this stack:

A "security vendor" label is not a trust guarantee — even scanners get compromised

Version tags (@v1, @latest) are mutable and can be force-pushed by anyone with write access

Pin every GitHub Action and container image to an immutable full commit SHA or digest, never a tag

Credential rotation must be atomic — revoke first, then reissue; a staggered rotation window is an open door

Avoid pull_request_target in any workflow that touches forked PR code — it runs with base-repo secrets against untrusted input

Any CI/CD runner that executed a since-compromised action should have every exposed secret treated as burned, not just rotated

Don't trust an artifact because the filename or registry looks official — verify cryptographically, every time

Use short-lived OIDC tokens for cloud access instead of long-lived static credentials in CI/CD

Watch for anomalous tag movement or force-pushes on the dependencies you consume — it's a detectable signal, not just hindsight

Build a culture where your own tooling gets the same scrutiny you'd apply to a stranger's code — trust is earned per-run, not once

Verify before you run: cosign + SLSA provenance

Before any of the binaries or container images in this pipeline touch your infrastructure, verify both the signature and the build provenance:

cosign verify --certificate-identity-regexp "https://github.com/<org>/<repo>" \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  ghcr.io/<org>/<tool>:<version>

slsa-verifier verify-image ghcr.io/<org>/<tool>:<version> \
  --source-uri github.com/<org>/<repo> --source-tag v<version>

If either check fails, stop — don't run it "just this once." That two-command habit, run before every tool in this pipeline gets pulled, is the actual signature of a security engineer who double-checks everything rather than trusting the label on the box.

   git clone <your-repo-link-here>
   cd ctem-pipeline

(Repo link to be added — this is a placeholder for your actual GitHub URL.)

Install prerequisites

Set up the Python virtual environment (see caveat below before you skip this step)

   python3 -m venv ctem-venv
   source ctem-venv/bin/activate      # Windows: ctem-venv\Scripts\activate
   pip install -r requirements.txt
go install -v github.com/owasp-amass/amass/v4/...@master
   go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
   go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@latest
   go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest
   go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
./run_ctem.sh -d yourdomain.com

This chains: theHarvester → Amass/Subfinder → Naabu → httpx → Nuclei, writing results into

a /results

directory as structured JSON for downstream ingestion into your SIEM or a

watchlist/dashboard.

   scout aws --profile readonly-audit
   azurehound list --tenant <tenant-id> -o azurehound-output.json

Import outputs into your BloodHound Neo4j instance to visualize attack paths.

If you run pip install

against your system Python directly, you will very likely hit dependency

conflicts — theHarvester, ScoutSuite, and TruffleHog's Python wrapper each pin different versions

of shared libraries (requests

, boto3

, PyYAML

are common collision points). The symptom is

usually a cryptic ImportError

or version-resolution failure that looks like it's about one tool,

but is actually a transitive dependency clash between two unrelated tools.

Fix: always use an isolated venv per the steps above, and if you still hit an error:

pip install --upgrade pip setuptools wheel
pip install -r requirements.txt --no-cache-dir

If a specific tool's install still fails, isolate it into its own venv rather than fighting

version pins in a shared environment — it costs a few extra seconds of setup and saves hours of

dependency debugging.

This pipeline is designed to be run by anyone with basic CLI familiarity — no dedicated infrastructure, no recurring SaaS bill, and no cloud-vendor lock-in. The goal isn't a fancy dashboard; it's finding what an attacker would find, before they do.

── more in #developer-tools 4 stories · sorted by recency
── more on @aws 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/building-a-continuou…] indexed:0 read:5min 2026-09-02 ·