Skip to content

Part VII — Threat intelligence and red team

Threat-intelligence watch ✅ {#S20}

On init/update, agentteams pulls live threat feeds and folds them into the security agent's watch, alongside a static knowledge baseline shipped in source. Fetches are guarded: an exact-match HTTPS host allowlist (checked on the effective, post-redirect URL host), per-host response size bounds, and IDNA normalization (agentteams/security_refs.py:42-70; render/fetch at agentteams/security_refs.py:710-917).

Source Kind
CISA KEV live (www.cisa.gov)
FIRST EPSS live (api.first.org)
MITRE CVE live (cveawg.mitre.org)
NVD CVSS live, optional, rate-limited (services.nvd.nist.gov)
OSV.dev live, package-level — only when tools are given (api.osv.dev)
OWASP LLM Top 10 (2025) static (+ a static source registry)

It renders six intel-bearing placeholders (current threats, prevention playbook, LLM threats, OSV packages, the full watch JSON, the source registry) plus freshness fields and a payload digest (agentteams/security_feed_render.py:21-144). The snapshot is "valid as of Generated at… not a static authoritative baseline."

Freshness TTL = 24h. Stale cache / fetch-failed-no-cache / offline-no-cache / age > 24h / unparseable timestamp sets status stale, prepends a stale-data banner, and feeds the S12 gate. The payload digest is computed last, over the six placeholders, so a relabelled timestamp cannot fake freshness (S12) — the digest bind ties freshness to content.

Honest ceiling. The watch reports what upstream feeds said at fetch time, stamped provisional-by-time; a run older than its TTL is treated as stale, not trusted. The allowlist and size bounds harden the fetch against a redirecting or oversized upstream; they do not vouch for the correctness of what a legitimate feed returns.

Source. agentteams/security_refs.py:42-70,710-917; agentteams/security_feed_render.py:21-144; agentteams/templates/universal/security-vulnerability-watch.reference.template.md.

Red-team methodology ✅ {#S21}

The red team is a cycle that audits its own audit — it measures the actual controls in this repo against stated attacker tiers and records a per-probe outcome.

Run it:

agentteams --redteam                    # exit 2 = broken instrument OUTRANKS exit 1 = finding
agentteams --redteam-freshness-check    # is the standing run current?
agentteams --accept-probe-baseline      # record a new probe baseline (refused under --dry-run)

The exit-code ordering is the operator-facing contract: exit 2 (the instrument itself is broken) outranks exit 1 (a finding exists) — a red team that cannot trust its own tooling must report that first. --accept-probe-baseline is a write and is refused under --dry-run (a dry run must not half-perform it).

Seven-phase cycle (agentteams/redteam/cycle.py:1-215): Attack → Review → Plan → Audit-plan → Implement → Evaluate the red team → Remediate, re-entering phase 1 until two consecutive rounds find nothing new. A standing/scheduled run does phases 1, 2, 6 only — measure and report, never remediate. Phase 6 — auditing the audit — is what distinguishes it from a test suite.

Attacker tiers (a control is meaningful only against a stated tier):

Tier The attacker
T0 supplies content the agent reads (injected text)
T1 an in-repo agent with write + execute
T2 the operator's own shell

Outcome classes: DEFENDED / PARTIAL / EXPLOITED / DOCUMENTED-LIMIT / OUT-OF-TIER; an unknown outcome raises (a typo is a defect, not a measurement) (agentteams/redteam/registry.py:36-55; agentteams/redteam/runner.py:39-79).

Probes attack an isolated copy and assert the live tree is byte-identical after; the merge is a measurement (RESTORED/PRESERVED/REFUSED), not a safety net. Counts refuse to exist without a denominator and a canonical population source — the type-level fix for the defect that once hid 719 exposed agents.

Phase-6 self-audit — F-1..F-6 (agentteams/redteam/selfaudit.py:33-101):

ID Failure mode it catches
F-1 a verifier that always passes
F-2 a fix wired to one of two call sites
F-3 hand-rolling what the tool provides
F-4 a coverage claim with an unexamined denominator
F-5 a probe that got blinder, not better
F-6 accepting a weakness with no ledger diff

Honest ceiling. The cycle measures the controls that exist against the tiers it states; it cannot measure an attack no probe expresses or a tier no probe targets. F-1..F-6 are named failure modes, not a proof of their own absence, and the byte-identity assertion tells you what happened to the copy — not that every future attack leaves the tree untouched.

Source. agentteams/templates/universal/redteam-methodology.reference.template.md:22-239; agentteams/redteam/registry.py:36-55; agentteams/redteam/runner.py:39-79; agentteams/redteam/selfaudit.py:33-101; agentteams/redteam/cycle.py:1-215.


Sources for Part VII. agentteams/security_refs.py; agentteams/security_feed_render.py; agentteams/templates/universal/security-vulnerability-watch.reference.template.md; agentteams/templates/universal/redteam-methodology.reference.template.md; agentteams/redteam/registry.py; agentteams/redteam/runner.py; agentteams/redteam/selfaudit.py; agentteams/redteam/cycle.py.