feat: capture, persist, and strip Agent Firewall correlation headers in AI Bridge (#26529)

Wire the Agent Firewall correlation headers
(`X-Coder-Agent-Firewall-Session-Id` and
`X-Coder-Agent-Firewall-Sequence-Number`) through the AI Bridge
interception processor so that each interception is linked to its
originating firewall session.

Closes https://linear.app/codercom/issue/AIGOV-259

> Generated by Coder Agents on behalf of @SasSwart

**Data flow:**
`request header` → `bridge.go` reads + strips → `InterceptionRecord` →
`translator.go` → proto `RecordInterceptionRequest` →
`aibridgedserver.go` → DB
This commit is contained in:
Sas Swart
2026-06-30 14:01:27 +02:00
committed by GitHub
parent 681d77154b
commit d179266cc7
8 changed files with 369 additions and 26 deletions
+10
View File
@@ -20,6 +20,16 @@ const HeaderCoderToken = "X-Coder-AI-Governance-Token" //nolint:gosec // This is
// request forwarded to aibridged for cross-service log correlation.
const HeaderCoderRequestID = "X-Coder-AI-Governance-Request-Id"
// HeaderAgentFirewallSessionID is injected by Agent Firewall on requests
// routed through it. It carries the firewall session UUID so that AI
// Gateway can correlate interceptions with firewall audit events.
const HeaderAgentFirewallSessionID = "X-Coder-Agent-Firewall-Session-Id"
// HeaderAgentFirewallSequenceNumber is injected alongside the session ID
// by Agent Firewall. It carries a monotonically increasing sequence
// number that orders network requests within a single firewall session.
const HeaderAgentFirewallSequenceNumber = "X-Coder-Agent-Firewall-Sequence-Number"
// Copilot provider.
const (
ProviderCopilotBusiness = "copilot-business"
+16 -14
View File
@@ -25,20 +25,22 @@ type recorderTranslation struct {
func (t *recorderTranslation) RecordInterception(ctx context.Context, req *aibridge.InterceptionRecord) error {
_, err := t.client.RecordInterception(ctx, &proto.RecordInterceptionRequest{
Id: req.ID,
ApiKeyId: t.apiKeyID,
InitiatorId: req.InitiatorID,
Provider: req.Provider,
ProviderName: req.ProviderName,
Model: req.Model,
UserAgent: req.UserAgent,
Client: req.Client,
ClientSessionId: req.ClientSessionID,
Metadata: marshalForProto(req.Metadata),
StartedAt: timestamppb.New(req.StartedAt),
CorrelatingToolCallId: req.CorrelatingToolCallID,
CredentialKind: req.CredentialKind,
CredentialHint: req.CredentialHint,
Id: req.ID,
ApiKeyId: t.apiKeyID,
InitiatorId: req.InitiatorID,
Provider: req.Provider,
ProviderName: req.ProviderName,
Model: req.Model,
UserAgent: req.UserAgent,
Client: req.Client,
ClientSessionId: req.ClientSessionID,
Metadata: marshalForProto(req.Metadata),
StartedAt: timestamppb.New(req.StartedAt),
CorrelatingToolCallId: req.CorrelatingToolCallID,
CredentialKind: req.CredentialKind,
CredentialHint: req.CredentialHint,
AgentFirewallSessionId: req.AgentFirewallSessionID,
AgentFirewallSequenceNumber: req.AgentFirewallSequenceNumber,
})
return err
}