diff --git a/agent/boundary_logs_test.go b/agent/boundary_logs_test.go index bb6ee3d166..0cc8a7264f 100644 --- a/agent/boundary_logs_test.go +++ b/agent/boundary_logs_test.go @@ -78,9 +78,11 @@ func TestBoundaryLogs_EndToEnd(t *testing.T) { sink := &logSink{} logger := slog.Make(sink) workspaceID := uuid.New() + templateID := uuid.New() reporter := &agentapi.BoundaryLogsAPI{ Log: logger, WorkspaceID: workspaceID, + TemplateID: templateID, } ctx, cancel := context.WithCancel(context.Background()) @@ -123,6 +125,7 @@ func TestBoundaryLogs_EndToEnd(t *testing.T) { require.Equal(t, "boundary_request", entry.Message) require.Equal(t, "allow", getField(entry.Fields, "decision")) require.Equal(t, workspaceID.String(), getField(entry.Fields, "workspace_id")) + require.Equal(t, templateID.String(), getField(entry.Fields, "template_id")) require.Equal(t, "GET", getField(entry.Fields, "http_method")) require.Equal(t, "https://example.com/allowed", getField(entry.Fields, "http_url")) require.Equal(t, "*.example.com", getField(entry.Fields, "matched_rule")) @@ -155,6 +158,7 @@ func TestBoundaryLogs_EndToEnd(t *testing.T) { require.Equal(t, "boundary_request", entry.Message) require.Equal(t, "deny", getField(entry.Fields, "decision")) require.Equal(t, workspaceID.String(), getField(entry.Fields, "workspace_id")) + require.Equal(t, templateID.String(), getField(entry.Fields, "template_id")) require.Equal(t, "POST", getField(entry.Fields, "http_method")) require.Equal(t, "https://blocked.com/denied", getField(entry.Fields, "http_url")) require.Equal(t, nil, getField(entry.Fields, "matched_rule")) diff --git a/coderd/agentapi/api.go b/coderd/agentapi/api.go index 57c2a24b62..79dafa8d83 100644 --- a/coderd/agentapi/api.go +++ b/coderd/agentapi/api.go @@ -223,6 +223,7 @@ func New(opts Options, workspace database.Workspace) *API { api.BoundaryLogsAPI = &BoundaryLogsAPI{ Log: opts.Log, WorkspaceID: opts.WorkspaceID, + TemplateID: workspace.TemplateID, } // Start background cache refresh loop to handle workspace changes diff --git a/coderd/agentapi/boundary_logs.go b/coderd/agentapi/boundary_logs.go index cea5a900cb..5285c94086 100644 --- a/coderd/agentapi/boundary_logs.go +++ b/coderd/agentapi/boundary_logs.go @@ -13,6 +13,7 @@ import ( type BoundaryLogsAPI struct { Log slog.Logger WorkspaceID uuid.UUID + TemplateID uuid.UUID } func (a *BoundaryLogsAPI) ReportBoundaryLogs(ctx context.Context, req *agentproto.ReportBoundaryLogsRequest) (*agentproto.ReportBoundaryLogsResponse, error) { @@ -33,6 +34,7 @@ func (a *BoundaryLogsAPI) ReportBoundaryLogs(ctx context.Context, req *agentprot fields := []slog.Field{ slog.F("decision", allowBoolToString(l.Allowed)), slog.F("workspace_id", a.WorkspaceID.String()), + slog.F("template_id", a.TemplateID.String()), slog.F("http_method", r.HttpRequest.Method), slog.F("http_url", r.HttpRequest.Url), slog.F("event_time", logTime.Format(time.RFC3339Nano)), diff --git a/docs/ai-coder/boundary/agent-boundary.md b/docs/ai-coder/boundary/agent-boundary.md index 9deb5df229..0be17cbc6b 100644 --- a/docs/ai-coder/boundary/agent-boundary.md +++ b/docs/ai-coder/boundary/agent-boundary.md @@ -133,6 +133,7 @@ Each boundary audit log entry includes: | `workspace_id` | The UUID of the workspace where the request originated | | `workspace_name` | The name of the workspace where the request originated | | `owner` | The owner of the workspace where the request originated | +| `template_id` | The UUID of the template that the workspace was created from | | `http_method` | The HTTP method used (GET, POST, PUT, DELETE, etc.) | | `http_url` | The fully qualified URL that was requested | | `event_time` | Timestamp when boundary processed the request (RFC3339 format) |