Protect private API routes and scope agent data

This commit is contained in:
Hamza Ayed
2026-10-03 00:34:49 +03:00
parent 1c1f662850
commit b0cd825838
17 changed files with 313 additions and 95 deletions
+16 -6
View File
@@ -116,6 +116,7 @@ def initialize_database() -> None:
CREATE TABLE IF NOT EXISTS agent_audit_events (
id TEXT PRIMARY KEY,
user_id TEXT REFERENCES users(id) ON DELETE CASCADE,
tool TEXT NOT NULL,
method TEXT NOT NULL,
status_code INTEGER NOT NULL,
@@ -138,6 +139,14 @@ def initialize_database() -> None:
}
if "password_hash" not in identity_columns:
connection.execute("ALTER TABLE user_identities ADD COLUMN password_hash TEXT")
audit_columns = {
row["name"] for row in connection.execute("PRAGMA table_info(agent_audit_events)")
}
if "user_id" not in audit_columns:
connection.execute("ALTER TABLE agent_audit_events ADD COLUMN user_id TEXT REFERENCES users(id) ON DELETE CASCADE")
connection.execute(
"CREATE INDEX IF NOT EXISTS idx_agent_audit_user_created ON agent_audit_events(user_id, created_at DESC)"
)
def ensure_user(user_id: str) -> None:
@@ -351,29 +360,30 @@ def record_agent_audit_event(
method: str,
status_code: int,
duration_ms: int,
user_id: str | None,
) -> None:
"""Record agent route metadata only; never persist prompts or file contents."""
with _connect() as connection:
connection.execute(
"""
INSERT INTO agent_audit_events(id, tool, method, status_code, duration_ms)
VALUES (?, ?, ?, ?, ?)
INSERT INTO agent_audit_events(id, user_id, tool, method, status_code, duration_ms)
VALUES (?, ?, ?, ?, ?, ?)
""",
(event_id, tool, method, status_code, duration_ms),
(event_id, user_id, tool, method, status_code, duration_ms),
)
def list_agent_audit_events(limit: int = 50) -> list[dict[str, Any]]:
def list_agent_audit_events(user_id: str, limit: int = 50) -> list[dict[str, Any]]:
bounded_limit = max(1, min(limit, 200))
with _connect() as connection:
rows = connection.execute(
"""
SELECT id, tool, method, status_code, duration_ms, created_at
FROM agent_audit_events
FROM agent_audit_events WHERE user_id=?
ORDER BY created_at DESC, rowid DESC
LIMIT ?
""",
(bounded_limit,),
(user_id, bounded_limit),
).fetchall()
return [dict(row) for row in rows]