feat(sofiia-console): add internal audit ingest endpoint for trusted services
Adds POST /api/audit/internal authenticated via X-Internal-Service-Token header (SOFIIA_INTERNAL_TOKEN env). Allows matrix-bridge-dagi and other internal services to write audit events without team keys. Reuses existing audit_log() + db layer. Made-with: Cursor
This commit is contained in:
@@ -3783,6 +3783,51 @@ async def api_audit_list(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# ── Internal Audit Ingest (trusted services only) ─────────────────────────────
|
||||||
|
|
||||||
|
_INTERNAL_TOKEN: str = os.getenv("SOFIIA_INTERNAL_TOKEN", "")
|
||||||
|
|
||||||
|
|
||||||
|
class _InternalAuditPayload(BaseModel):
|
||||||
|
event: str
|
||||||
|
operator_id: str = "internal"
|
||||||
|
chat_id: Optional[str] = None
|
||||||
|
node_id: Optional[str] = None
|
||||||
|
agent_id: Optional[str] = None
|
||||||
|
status: str = "ok"
|
||||||
|
error_code: Optional[str] = None
|
||||||
|
duration_ms: Optional[int] = None
|
||||||
|
data: Dict[str, Any] = {}
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/api/audit/internal")
|
||||||
|
async def api_audit_internal_ingest(
|
||||||
|
request: Request,
|
||||||
|
payload: _InternalAuditPayload,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Internal audit ingest for trusted services (e.g. matrix-bridge-dagi).
|
||||||
|
Auth: X-Internal-Service-Token header must match SOFIIA_INTERNAL_TOKEN.
|
||||||
|
Not accessible by team keys or Telegram — internal network only.
|
||||||
|
"""
|
||||||
|
token = request.headers.get("X-Internal-Service-Token", "")
|
||||||
|
if not _INTERNAL_TOKEN or not token or token != _INTERNAL_TOKEN:
|
||||||
|
raise HTTPException(status_code=401, detail="invalid internal token")
|
||||||
|
|
||||||
|
await audit_log(AuditEvent(
|
||||||
|
event=payload.event,
|
||||||
|
operator_id=payload.operator_id,
|
||||||
|
chat_id=payload.chat_id,
|
||||||
|
node_id=payload.node_id,
|
||||||
|
agent_id=payload.agent_id,
|
||||||
|
status=payload.status,
|
||||||
|
error_code=payload.error_code,
|
||||||
|
duration_ms=payload.duration_ms,
|
||||||
|
data=payload.data,
|
||||||
|
))
|
||||||
|
return {"ok": True, "event": payload.event}
|
||||||
|
|
||||||
|
|
||||||
@app.get("/metrics")
|
@app.get("/metrics")
|
||||||
def metrics():
|
def metrics():
|
||||||
data, content_type = render_metrics()
|
data, content_type = render_metrics()
|
||||||
|
|||||||
Reference in New Issue
Block a user