{"slug": "agent-harness-defense-v0-2-0-dual-lattice-ifc-for-llm-agent-privilege-escalation", "title": "agent-harness-defense v0.2.0: dual-lattice IFC for LLM agent privilege escalation", "summary": "A developer released agent-harness-defense v0.2.0, an admission layer that enforces a plan-first information-flow policy to prevent instruction-privilege escalation in LLM coding agents. The dual-lattice IFC engine catches prompt injection that heuristic trigger phrases miss, and an independent audit reproduced and fixed a propagation bug before publication.", "body_md": "An open, offline-verifiable admission layer that stops instruction-privilege\n\nescalation in coding agents by enforcing a plan-first information-flow policy.\n\nA research prototype with a rigorous audit — not a turnkey production defense.\n\nLLM coding agents run over untrusted web pages, docs and tool output while\n\nholding authority over security-sensitive resources (deploy keys, CI configs,\n\nsecret stores). Two structural gaps are documented in the literature:\n\nThe harnesses themselves are evaluated across 13 attack objectives in 6 real\n\ncoding-agent frameworks ([arXiv:2608.27299](https://arxiv.org/abs/2608.27299)).\n\n`agent-harness-defense`\n\nis an **admission layer**: before a change is applied,\n\nyou call `run_admission()`\n\nwith an explicit description of what the agent\n\nproposes to do, and it returns a verdict — admit this, deny that, and why. It is\n\n*not* a runtime firewall watching a live agent. It is a library you (or the\n\nharness you integrate) invoke.\n\nThe decision core is a **dual-lattice information-flow control (IFC)** engine.\n\nEach datum in the plan carries two labels:\n\nWhen an action depends on low-integrity data (a repo README, say), the action\n\ninherits that distrust *even if the content contains no trigger word*. That is\n\nexactly what lets it catch prompt injection that the v0.1 heuristic (trigger\n\nphrases) could not see. As a second layer, the v0.1 heuristic (trigger phrases +\n\nforbidden paths) is retained as a **backup signal**, not the primary mechanism.\n\nThe planner emits one `Plan`\n\nper query. `evaluate_plan`\n\napplies a componentwise\n\nlattice join over the `depends_on`\n\ngraph:\n\n`SourceTag`\n\n(SYSTEM / USER / TOOL_RESULT / REPO_TEXT / ENV / DATA) is the\n\nper-fragment origin label. Reads are classified by path: reading repo text\n\nyields UNTRUSTED integrity (the prompt-injection surface); reading a system file\n\nyields SYSTEM.\n\n`write`\n\nthat depends on an untrusted `read`\n\ninherits UNTRUSTED integrity and\nis `write`\n\nsourced from `env.SECRET`\n\nto a public sink is `write`\n\nthat depends only on SYSTEM/USER input is admitted.The public `Signetry/eval`\n\nIPI corpus models the agent *writing the malicious\nartifact to disk*. We add\n\n`INCIDENT_REPORT_INJECTION`\n\n: the plan reads an`README.md`\n\nand writes `incident-report.md`\n\nsourced from `env.SECRET`\n\n,This is verified, not asserted: `test_v01_would_have_missed_this`\n\nre-runs the v0.1\n\nscan over the materialized repo and confirms `escalation_detected is False`\n\n— the\n\neval is non-vacuous. The suite covers 3 scenarios: the 2 Signetry IPI scenarios\n\n(README injection, CLAUDE.md scope expansion) plus this own secret-leak scenario.\n\nEach one has a test proving v0.1 would have let it through and the new engine does not.\n\nAn independent audit (fresh clone, clean venv) reproduced a real defect introduced\n\nduring the build: `_step_initial_label`\n\nreturned `(PUBLIC, SYSTEM)`\n\nfor *every*\n\nread, so propagation through `depends_on`\n\nonly worked via magic prefixes baked\n\ninto `value_source`\n\n. The fix (`_classify_read_path`\n\n) derives the read label from\n\nthe path. A regression test (`test_read_propagates_untrusted_via_depends_on`\n\n) now\n\nfails if the bug returns. The audit also flagged a CI regression the fix caused\n\n(a `bandit`\n\nB108 and a `ruff format`\n\nmiss), both closed before merge.\n\nThis is the part most security posts omit. Stated plainly:\n\n`Plan`\n\n(what the agent will read,\nwrite, and where each value comes from) must be supplied `Plan`\n\nsays step B depends on step A, the engine propagates the label. But nothing\nanalyzes disk to detect \"this file literally cites that other file\" on its own.\nIf the caller declares dependencies wrong, the engine cannot know — which is why\n`assert_plan_matches_materialized`\n\nexists, but it is a `LoopStateMonitor`\n\n— which is still the substring heuristic,\nnot the lattice.`KNOWN_ISSUES.md`\n\ndoes not whitewash\nanything), and a real audit trail where a propagation bug was found and fixed\nbefore publish. That already puts the repo above the median of security projects\nshipped to GitHub without external scrutiny.`Plan`\n\ngenerator) hits a wall, and that\nburns credibility fast.`Plan`\n\nfrom real agent\ncalls. Without it, \"just use it\" is an empty promise.`ifc.py`\n\nto learn how to use it.All claims are reproducible offline. The suite models both Signetry IPI scenarios\n\nfaithfully: the agent's `obey()`\n\nstep *writes the attack artifacts to disk*, so the\n\ndefense is exercised on real materialized state, not a mock. Three guard rails keep\n\nthe eval honest:\n\n`test_admission.py`\n\n) — fails if `obey()`\n\ndoes not land the\nartifact on disk.`assert_plan_matches_materialized`\n\n) — fails if the declared\n`Plan`\n\ndiverges from what the agent actually wrote.`test_eval_catches_regression.py`\n\n) — monkey-patches\n`evaluate_plan`\n\nto admit everything and asserts the guard observes the broken\nboundary.| Gate | Result |\n|---|---|\n`pytest` |\n23 passed (0.29s) |\n`ruff check` |\nclean |\n`ruff format --check` |\nclean |\n`bandit -r agent_harness_defense -ll` |\nclean (B108 suppressed, justified) |\n\nThe package is not on PyPI — install from the repo:\n\n```\ngit clone https://github.com/amurlaniakea/agent-harness-defense\ncd agent-harness-defense\npip install -e \".[dev]\"      # ed-itable install; [dev] pulls pytest/ruff/bandit\npytest                      # 23 tests\nahd eval                   # run bundled IPI + AC-EVAL-1 scenarios\nahd run REPO --plan plan.yaml   # evaluate a declarative Plan\n```\n\n*Última actualización: 2026-08-29 — correcciones de instalación: el paquete no está en PyPI, instalar desde el repo con pip install -e \".[dev]\"; el tag v0.2.0 tiene Release de GitHub con notas.*\n\n*License: AGPL-3.0-or-later — Pedro Sordo Martínez*\n\n*Implementation → independent audit on a clean clone → merge gated on green CI.\nPrototype, not a turnkey defense: read \"What it does NOT do\" before integrating.*", "url": "https://wpnews.pro/news/agent-harness-defense-v0-2-0-dual-lattice-ifc-for-llm-agent-privilege-escalation", "canonical_source": "https://dev.to/magopredator/agent-harness-defense-v020-dual-lattice-ifc-for-llm-agent-privilege-escalation-46jh", "published_at": "2026-08-29 07:23:28+00:00", "updated_at": "2026-08-29 07:48:54.056009+00:00", "lang": "en", "topics": ["ai-safety", "ai-agents", "developer-tools", "artificial-intelligence"], "entities": ["agent-harness-defense", "Signetry"], "alternates": {"html": "https://wpnews.pro/news/agent-harness-defense-v0-2-0-dual-lattice-ifc-for-llm-agent-privilege-escalation", "markdown": "https://wpnews.pro/news/agent-harness-defense-v0-2-0-dual-lattice-ifc-for-llm-agent-privilege-escalation.md", "text": "https://wpnews.pro/news/agent-harness-defense-v0-2-0-dual-lattice-ifc-for-llm-agent-privilege-escalation.txt", "jsonld": "https://wpnews.pro/news/agent-harness-defense-v0-2-0-dual-lattice-ifc-for-llm-agent-privilege-escalation.jsonld"}}