fix(security): F14 (Astra P1) — KI-Datenrichtlinie deckt JSON-Strings, Provider-Compliance und Tool-Antworten ab
Check Cross-Plugin Imports / check (push) Waiting to run

Vorher (Astra): (1) enforce_data_policy filterte nur dict-Inhalte — ein
JSON-String mit smtp_password passierte ungefiltert (Astra-Repro). (2)
agent_runner rief die Policy mit db=None auf — Provider-Compliance
(Datenresidenz/erlaubte Datenklassen) wurde NIE geladen. (3)
Werkzeugantworten entstehen INNERHALB der ReAct-Schleife — die Policy
lief nur davor, Tool-Ergebnisse erreichten den Provider ungefiltert.

Fix:
- data_policy.py: _filter_json_string_content — JSON-serialisierte
  Strings werden geparst, durch dieselbe dict-Filterung geleitet und
  zurueckserialisiert; Nicht-JSON-Strings bleiben unveraendert
- agent_runner.py: echte DB-Session (Factory + Tenant-Kontext) statt
  db=None — Provider-Compliance wird tatsaechlich geladen
- agent_loop.py: _filter_observation — jede Tool-Observation wird
  VOR dem Feed-Back in die LLM-Konversation durch die
  SENSITIVE_FIELDS-Filterung geleitet (JSON geparst, sensible Felder
  entfernt, zurueckserialisiert)

Abnahme (Astra): Gesperrte Felder fehlen am Provider-Eingang sowohl im
Startkontext (durch echte Compliance-Session) als auch nach
Werkzeugaufrufen (Observation-Filter) — erfuellt.

Verifikation: test_agent_loop + test_phase_f_agents 57 passed/3 skipped
(dokumentierte F11-Verweise), Syntax + ruff clean.
This commit is contained in:
Agent Zero
2026-09-18 12:04:58 +02:00
parent c9a5a6e198
commit fdc4e36d14
3 changed files with 106 additions and 6 deletions
@@ -238,13 +238,22 @@ async def run_agent(
)
# ── Enforce data policy: filter sensitive fields from messages (Punkt 4) ──
# F14 (Astra P1): pass a REAL DB session so provider compliance
# (data residency / allowed data classes) is actually loaded —
# previously db=None silently skipped the compliance check.
from app.ai.data_policy import enforce_data_policy
messages = await enforce_data_policy(
db=None,
tenant_id=agent.tenant_id,
messages=messages,
agent_definition=agent,
)
from app.core.db import get_session_factory as _dp_factory
from app.core.db import set_tenant_context as _dp_set_tenant
_factory = _dp_factory()
async with _factory() as _dp_db:
await _dp_set_tenant(_dp_db, agent.tenant_id)
messages = await enforce_data_policy(
db=_dp_db,
tenant_id=agent.tenant_id,
messages=messages,
agent_definition=agent,
)
react_result: ReActResult = await asyncio.wait_for(
run_react_loop(