feat: add GET /api/v2/agent-firewall/sessions/{id}/logs endpoint (#24816)

Add a `GET /api/v2/agent-firewall/sessions/{id}/logs` endpoint that
returns agent firewall audit logs for a given session, sorted by
sequence number ascending.

The endpoint supports `seq_after` and `seq_before` (exclusive bounds)
and `limit` query parameters. This enables the frontend to fetch exactly
the firewall events that fall between two AI Bridge interceptions within
a thread, as described in FR 4 of the Boundary/Bridge correlation RFC.

Authorization reuses the `boundary_log` RBAC resource (owner and auditor
can read; members cannot). Returns 404 for unauthorized users to avoid
leaking existence information.

The endpoint is enterprise-only, gated behind `FeatureBoundary`
entitlement, matching the session endpoint from #24814.

Depends on #24814

> [!NOTE]
> This PR was authored by Coder Agents.
This commit is contained in:
Sas Swart
2026-06-22 13:56:29 +02:00
committed by GitHub
parent c0b8fa9418
commit 335d6bda1b
13 changed files with 829 additions and 8 deletions
+2 -2
View File
@@ -1146,8 +1146,8 @@ type sqlcQuerier interface {
ListAIBridgeUserPromptsByInterceptionIDs(ctx context.Context, interceptionIds []uuid.UUID) ([]AIBridgeUserPrompt, error)
ListAIGatewayKeys(ctx context.Context) ([]ListAIGatewayKeysRow, error)
// Lists boundary logs for a session, sorted by sequence number ascending.
// Supports optional exclusive sequence number bounds (seq_after, seq_before)
// for fetching events between two known interceptions.
// Supports an inclusive lower bound (seq_after) and an exclusive upper bound
// (seq_before) for fetching events between two known interceptions.
ListBoundaryLogsBySessionID(ctx context.Context, arg ListBoundaryLogsBySessionIDParams) ([]BoundaryLog, error)
// Lists a chat's pinned context resources, ordered deterministically by
// source.
+3 -3
View File
@@ -3892,7 +3892,7 @@ FROM boundary_logs
WHERE
session_id = $1
AND CASE
WHEN $2::int IS NOT NULL THEN sequence_number > $2
WHEN $2::int IS NOT NULL THEN sequence_number >= $2
ELSE true
END
AND CASE
@@ -3911,8 +3911,8 @@ type ListBoundaryLogsBySessionIDParams struct {
}
// Lists boundary logs for a session, sorted by sequence number ascending.
// Supports optional exclusive sequence number bounds (seq_after, seq_before)
// for fetching events between two known interceptions.
// Supports an inclusive lower bound (seq_after) and an exclusive upper bound
// (seq_before) for fetching events between two known interceptions.
func (q *sqlQuerier) ListBoundaryLogsBySessionID(ctx context.Context, arg ListBoundaryLogsBySessionIDParams) ([]BoundaryLog, error) {
rows, err := q.db.QueryContext(ctx, listBoundaryLogsBySessionID,
arg.SessionID,
+3 -3
View File
@@ -64,14 +64,14 @@ SELECT * FROM boundary_logs WHERE id = @id;
-- name: ListBoundaryLogsBySessionID :many
-- Lists boundary logs for a session, sorted by sequence number ascending.
-- Supports optional exclusive sequence number bounds (seq_after, seq_before)
-- for fetching events between two known interceptions.
-- Supports an inclusive lower bound (seq_after) and an exclusive upper bound
-- (seq_before) for fetching events between two known interceptions.
SELECT *
FROM boundary_logs
WHERE
session_id = @session_id
AND CASE
WHEN sqlc.narg('seq_after')::int IS NOT NULL THEN sequence_number > sqlc.narg('seq_after')
WHEN sqlc.narg('seq_after')::int IS NOT NULL THEN sequence_number >= sqlc.narg('seq_after')
ELSE true
END
AND CASE