ExecutorMetrics.get_stats picked the p95 element with
int(n * 0.95), which collapses to the last index (the maximum)
for any batch of 20 or fewer requests, so the reported p95 was
actually the worst-case latency for typical scan batches. Use
ceil(n * 0.95) - 1, the standard nearest-rank index.
record_failure ignored the half_open state: the minimum-sample gate
(total >= 10) and the success counter meant a failure during
probation neither re-opened the circuit nor prevented it from
closing. One failure followed by three successes closed the circuit
with the failure forgotten. Trip back to open on the first half-open
failure, with fresh counters.
PIIDetector and SandboxEscapeDetector were wired directly in
probe_actor/refusal.py and the refusal classifier manager was populated from
a hardcoded list, so the only way to toggle a bundled detector or add an
organization-specific signature was to patch the module.
Add a DetectorRegistry mapping plugin names to factories, assembled from an
agentic_security.toml [detectors] section via build_from_config. Custom
detectors load by import path ("pkg.module:ClassName"). refusal.py gains
build_refusal_manager(config=None) reading the [detectors] table; all public
symbols are preserved. Built-in leak detectors ship registered but disabled,
so default refusal_heuristic behaviour is unchanged.
Closes#82
Signed-off-by: Devam Shah <devamshah91@gmail.com>
CORS: drop allow_credentials=True. With allow_origins=['*'] Starlette reflects
the request Origin and emits Access-Control-Allow-Credentials: true on any
credentialed request — a reflect-any-origin hole. The app authenticates with
Bearer tokens in the Authorization header, so credentialed CORS was never needed.
/icons/{icon_name}: validate against a strict allowlist (re.fullmatch
[A-Za-z0-9._-]+\.png) and assert the resolved path stays inside ICONS_DIR before
any filesystem write or outbound fetch. Closes the path-traversal / arbitrary-write
(CWE-22) and controlled-URL (CWE-73) surface on the unsanitized icon_name.
Adds CORS middleware tests and icon-name validation tests (traversal, encoded
slash, null byte, trailing newline, wrong extension).
Closes#298
Signed-off-by: Devam Shah <devamshah91@gmail.com>
Closes#307
Agno was imported by nothing, had undefined-variable bugs,
and was not a declared dependency.
Removed:
- agentic_security/agents/ (operator_agno.py)
- docs/mcp_agno_integration.md
- .gitignore reference to operator_agno.py
No agno references remain in source code.
Pre-existing test failures (missing tabulate module) confirmed
unrelated to this change via git stash verification.