Defense in depth and decision architecture
How independent layers come together and the decision happens without erasing legitimate code: three layers that do not depend on one another, severity by corroboration (two independent signals), reversible quarantine instead of deletion, and the idea of the protection coefficient as a sum.
In 30 seconds
Three independent layers: pretool (write-time), daemon (filesystem) and eBPF (kernel backstop on Linux). The decision uses corroboration: one confirmatory signal (Tier A) suffices; heuristic signals (Tier B) need two distinct types to confirm, otherwise they stay Suspicious (logged, kept). On confirmation, the daemon moves to quarantine (reversible), it does not delete. And total protection is the sum of layers, the coefficient, not the count of a feature.
From scratch: defense-in-depth and the trust model
Defense in depth means not relying on a single barrier: if one fails, the next still contains. Corroboration is requiring more than one independent piece of evidence before a costly action: in medicine, two tests; here, two distinct detection methods. Reversibility is preferring the action that can be undone: blocking a write or moving a file can be undone; deleting cannot. These three principles exist to resolve the central tension of a security tool: being hard on the attack without destroying the user's legitimate work.
Why it matters
The cost of being wrong is not symmetric. Letting an attack through is bad; deleting the user's legitimate code over a false positive is often worse, because it breaks trust and destroys work. So the decision was calibrated so that only strong (confirmatory) evidence acts alone, and weak evidence needs company. And when action comes, it is reversible. That is what separates a tool people keep enabled from one they turn off at the first scare.
How it correlates
The independent layers of group 6 and the kernel backstop of group 2 are the three barriers; corroboration uses the signal taxonomy the visitors and the scanner emit; and the source+sink coexistence of group 8 is corroboration baked into a single visitor. Coefficient is the name given to the sum of all this, and it is what the coverage matrix breaks down per layer.
How Nemesis applies it
The decision has two tiers. Tier A (confirmatory) acts alone; Tier B (corroborating) counts distinct types:
📄 .nemesis/nemesis-defender/src/lib.rs:377-437 · Tier A/B e compute_severity
const CONFIRMATORY_VISITORS: &[&str] = &[ // Tier A: 1 hit confirma
"decode_exec", "reverse_shell", "exfil_chain", "taint_tracker",
"unicode_bidi", "ide_config_poisoning", "nemesis_bypass", /* ... */ ];
const CORROBORATING_VISITORS: &[&str] = &[ // Tier B: heurístico, sujeito a FP
"prompt_injection", "self_clean", "time_gated", "high_entropy", /* ... */ ];
// 0 → Clean · 1 tipo → Suspicious (loga, mantém) · 2+ tipos → MaliciousThe daemon is security-only and never handles quality, precisely because its action is irreversible by nature (moving a materialized file), while the pretool blocks writes (reversible):
📄 .nemesis/nemesis-defender/src/lib.rs:216-232 · daemon security-only
// regras de QUALIDADE NUNCA chegam ao daemon: qualidade ⇒ bloquear escrita
// (reversível), JAMAIS deletar arquivo (irreversível). O daemon é SECURITY-ONLY.And confirmed containment is a reversible move, with PENDING holding the session until the human decides to restore or purge:
📄 .nemesis/nemesis-defender/src/quarantine.rs:1-11 · quarentena reversível
//! MOVE para .nemesis/quarantine/ e retém para revisão humana (não deleta).
//! O humano decide: restore (falso-positivo) ou purge (expurga de vez).On Linux, eBPF is the third layer, independent of the hook: the pretool only ensures it is up, but the kernel decision does not depend on the IDE calling anything:
📄 .nemesis/hooks/nemesis-pretool-check-unix.rs:945-981 · eBPF como backstop
Decisions and limits
The count is by distinct types of signal, not by hits, on purpose: several occurrences of the same cause in one file should not escalate to Malicious; what confirms is independent methods agreeing. "Independent" is the architecture's point: if the three layers depended on the same condition, they would be the same barrier repainted. The design ensures the eBPF in the kernel does not depend on the hook and the daemon does not depend on the IDE calling anything.
And Suspicious is not letting it through: it is logged and kept for review. Reversibility applies here too: observing is preferable to deleting when in doubt.
Self-check
▸Why two distinct signals to confirm (instead of a single heuristic)?
Because an isolated heuristic has a false-positive rate; requiring two independent methods to agree lowers the risk of erasing legitimate code. A confirmatory signal (deterministic or multi-condition) is strong enough to act alone.
▸Why quarantine instead of delete?
Because moving is reversible and preserves the evidence for human review; deleting is irreversible. The human decides to restore (if it was a false positive) or purge.
▸What is the protection coefficient?
The sum of the independent layers and their taxonomies (embedded denylist, scanner, visitors, command denylists, eBPF). It is the real measure of coverage, and that is why it does not reduce to the number of visitors.
Further reading
- NIST, defense in depth.
- OWASP Proactive Controls.
- MITRE ATT&CK como taxonomia de técnicas.
Citações verificadas contra o repositório. Voltar ao índice.