feat: general-purpose compliance event reporting from filter scripts#371
feat: general-purpose compliance event reporting from filter scripts#371lonelycode merged 7 commits intomainfrom
Conversation
…pts (#370) Filter scripts can now report compliance events (redactions, rewrites, PII detection, silent failures, etc.) by setting compliance_events in their Tengo output object. Events flow through the analytics pipeline and are stored for compliance reporting. Key changes: - New ComplianceEventOutput type in ScriptOutput for script-reported events - Tengo extraction logic with severity validation and event_type requirement - Async analytics pipeline (RecordComplianceEvents) following existing patterns - New aistudio_compliance_events_total Prometheus metric - Recording at all 6 filter execution sites (proxy/chat request/response) - ComplianceEvent model with GORM auto-migration - Enterprise compliance service GetComplianceEvents with filtering/aggregation - GET /compliance/events API endpoint - gRPC edge→control flow via AnalyticsPulse proto with ComplianceEventProto - Microgateway pulse plugin buffering and batch transmission - Control server receives and stores edge compliance events Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Martin Buhr seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account. You have signed the CLA already but the status is still pending? Let us recheck it. |
|
This pull request introduces a general-purpose compliance event reporting system, enabling filter scripts to flag custom, compliance-relevant activities. These events are processed through the full analytics pipeline, from script output to a new database model, transmitted via gRPC from edge gateways, and made available through a new Files Changed AnalysisThis is a significant feature implementation, reflected in the 30 files changed with 2041 additions and only 104 deletions. The changes span the entire application stack, indicating a full vertical slice of functionality.
Architecture & Impact AssessmentWhat this PR accomplishesThis PR provides a flexible and powerful framework for detailed compliance auditing. It allows developers to define and report any relevant event from within a filter script (e.g., PII redaction, content rewrites, silent failures), providing rich, contextual data that goes far beyond simple block/allow decisions. This creates a detailed audit trail for actions taken by the AI gateway's policies. Key technical changes introduced
Data Flow DiagramsequenceDiagram
participant Script as "Tengo Script"
participant FilterHost as "Filter Host (Proxy/Chat)"
participant Analytics as "Analytics Service (Edge)"
participant PulsePlugin as "Pulse Plugin (Edge)"
participant ControlPlane as "Control Plane (gRPC Server)"
participant DB as "Database"
participant API as "API Server"
FilterHost->>Script: Execute script
Script-->>FilterHost: Return output with `compliance_events`
FilterHost->>Analytics: RecordComplianceEvents()
Analytics->>PulsePlugin: BufferComplianceEvents()
loop Every X seconds
PulsePlugin->>ControlPlane: SendAnalyticsPulse(gRPC)
end
ControlPlane->>Analytics: RecordComplianceEvents()
Analytics->>DB: (Async Batch) INSERT INTO compliance_events
participant User
User->>API: GET /compliance/events
API->>DB: SELECT * FROM compliance_events
DB-->>API: Return events
API-->>User: Return JSON response
Scope Discovery & Context Expansion
Metadata
Powered by Visor from Probelabs Last updated: 2026-04-14T05:24:48.403Z | Triggered by: pr_updated | Commit: a90ca1c 💡 TIP: You can chat with Visor using |
\n\n
Architecture Issues (2)
Performance Issues (2)
Quality Issues (2)
Powered by Visor from Probelabs Last updated: 2026-04-14T05:24:39.175Z | Triggered by: pr_updated | Commit: a90ca1c 💡 TIP: You can chat with Visor using |
Address PR review feedback: - Validate severity query param against whitelist (info/warning/critical) at the API layer as defense-in-depth (GORM already uses parameterized queries, but reject invalid values early with a clear 400 error) - Add tests for invalid severity and SQL injection attempt in severity param - context.Background() in chat session paths matches the established pattern throughout ChatSession (30+ usages) since the struct has no request-scoped context (long-lived WebSocket sessions) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Address PR review feedback on context propagation: - Add ctx/ctxCancel to ChatSession, cancelled on Stop() - Use cs.ctx instead of context.Background() for compliance event recording in chat request, file reference, and tool response filters - Thread ctx through ExecuteResponseFilters for chat response filters - Add max-length validation (100 chars) on event_type query parameter Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The enterprise GetComplianceEvents uses GORM parameterized queries
(db.Where("event_type = ?", val)) so injection attempts are treated
as literal string matches returning 0 results. Added tests proving:
- SQL injection in event_type returns empty results (not an error)
- Oversized event_type (>100 chars) returns 400
The /compliance/events endpoint is already admin-only via the v1
route group middleware chain (AuthMiddleware + AdminOnly) applied
at api/api.go:535-536.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Re: SQL injection concern on func (s *enterpriseService) GetComplianceEvents(startDate, endDate time.Time, appID *uint, eventType *string, severity *string, limit int, offset int) (*compliance.ComplianceEventsData, error) {
query := s.db.Model(&models.ComplianceEvent{}).Where("time_stamp BETWEEN ? AND ?", startDate, endDate)
if appID != nil {
query = query.Where("app_id = ?", *appID)
}
if eventType != nil && *eventType != "" {
query = query.Where("event_type = ?", *eventType)
}
if severity != nil && *severity != "" {
query = query.Where("severity = ?", *severity)
}All user inputs use GORM's Additionally, at the API layer we validate:
|
Points to enterprise feat/370-audit-filter-redactions branch which adds: - ComplianceEvents field to ScriptOutput with Tengo extraction - GetComplianceEvents method on enterprise compliance service Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Re: Missing Application ID in chat session compliance events — The If we want to associate chat sessions with apps in the future, that would require adding an |
Update all pre-provided filter scripts, embedded UI templates, and documentation to demonstrate the compliance_events output field added in #371. Enterprise users now have working examples of governance event reporting in PII redaction, content blocking, and response guardrails. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ion (#372) * docs: add compliance event reporting to filter scripts and documentation Update all pre-provided filter scripts, embedded UI templates, and documentation to demonstrate the compliance_events output field added in #371. Enterprise users now have working examples of governance event reporting in PII redaction, content blocking, and response guardrails. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: standardise compliance event metadata keys across examples Use "matched_pattern" consistently for detected text and "redacted_types" (as an array) for PII redaction scripts, replacing the inconsistent mix of "keyword", "pattern", "patterns". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Martin Buhr <martin@buhr.co> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
GET /compliance/eventsAPI endpoint with filtering by severity, event type, app ID, and paginationCloses #370
How it works
Script developers set
compliance_eventsin their Tengo output object:Changes by layer
Scripting — New
ComplianceEventOutputtype onScriptOutput, Tengo extraction with severity validation, bridge mapping inscripting_ent.goAnalytics —
RecordComplianceEventsonAnalyticsHandlerinterface, async channel+worker inDatabaseHandler,aistudio_compliance_events_totalPrometheus metric, shared context-enrichment helperFilter execution — Recording wired up at all 6 filter sites: proxy request/response, chat request/response, file reference, tool response
Compliance service —
GetComplianceEventswith date range, app ID, event type, severity filtering, aggregation (by_severity, by_type, by_filter), timeline, paginationAPI —
GET /compliance/eventsendpointgRPC edge→control —
ComplianceEventProtomessage inAnalyticsPulse, pulse plugin buffering on edge, control server processing and DB storage on receiptTest plan
🤖 Generated with Claude Code