diff --git a/audit/multi_auditor.go b/audit/multi_auditor.go index a9be017..91607dc 100644 --- a/audit/multi_auditor.go +++ b/audit/multi_auditor.go @@ -5,6 +5,8 @@ import ( "fmt" "log/slog" "os" + + "github.com/google/uuid" ) // MultiAuditor wraps multiple auditors and sends audit events to all of them. @@ -28,7 +30,7 @@ func (m *MultiAuditor) AuditRequest(req Request) { // provided configuration. It always includes a LogAuditor for stderr logging, // and conditionally adds a SocketAuditor if audit logs are enabled and the // workspace agent's log proxy socket exists. -func SetupAuditor(ctx context.Context, logger *slog.Logger, disableAuditLogs bool, logProxySocketPath string) (Auditor, error) { +func SetupAuditor(ctx context.Context, logger *slog.Logger, disableAuditLogs bool, logProxySocketPath string, sessionID uuid.UUID) (Auditor, error) { stderrAuditor := NewLogAuditor(logger) auditors := []Auditor{stderrAuditor} @@ -48,7 +50,8 @@ func SetupAuditor(ctx context.Context, logger *slog.Logger, disableAuditLogs boo } agentWillProxy := !os.IsNotExist(err) if agentWillProxy { - socketAuditor := NewSocketAuditor(logger, logProxySocketPath) + seq := &SequenceCounter{} + socketAuditor := NewSocketAuditor(logger, logProxySocketPath, sessionID, seq) go socketAuditor.Loop(ctx) auditors = append(auditors, socketAuditor) } else { diff --git a/audit/multi_auditor_test.go b/audit/multi_auditor_test.go index e7f8af9..2293ff8 100644 --- a/audit/multi_auditor_test.go +++ b/audit/multi_auditor_test.go @@ -7,6 +7,8 @@ import ( "os" "path/filepath" "testing" + + "github.com/google/uuid" ) type mockAuditor struct { @@ -25,7 +27,7 @@ func TestSetupAuditor_DisabledAuditLogs(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, nil)) ctx := context.Background() - auditor, err := SetupAuditor(ctx, logger, true, "") + auditor, err := SetupAuditor(ctx, logger, true, "", uuid.New()) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -50,7 +52,7 @@ func TestSetupAuditor_EmptySocketPath(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, nil)) ctx := context.Background() - _, err := SetupAuditor(ctx, logger, false, "") + _, err := SetupAuditor(ctx, logger, false, "", uuid.New()) if err == nil { t.Fatal("expected error for empty socket path, got nil") } @@ -62,7 +64,7 @@ func TestSetupAuditor_SocketDoesNotExist(t *testing.T) { logger := slog.New(slog.NewTextHandler(io.Discard, nil)) ctx := context.Background() - auditor, err := SetupAuditor(ctx, logger, false, "/nonexistent/socket/path") + auditor, err := SetupAuditor(ctx, logger, false, "/nonexistent/socket/path", uuid.New()) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -100,7 +102,7 @@ func TestSetupAuditor_SocketExists(t *testing.T) { t.Fatalf("failed to close temp file: %v", err) } - auditor, err := SetupAuditor(ctx, logger, false, socketPath) + auditor, err := SetupAuditor(ctx, logger, false, socketPath, uuid.New()) if err != nil { t.Fatalf("unexpected error: %v", err) } diff --git a/audit/sequence.go b/audit/sequence.go new file mode 100644 index 0000000..7882dd4 --- /dev/null +++ b/audit/sequence.go @@ -0,0 +1,20 @@ +package audit + +import "sync/atomic" + +// SequenceCounter is a monotonically increasing counter that assigns a +// unique sequence number to every audit event within a single boundary +// session. The counter starts at 0 and is safe for concurrent use by +// both the socket auditor and the proxy. +type SequenceCounter struct { + next atomic.Int32 +} + +// Next returns the next sequence number. The first call returns 0, +// subsequent calls return 1, 2, 3, etc. It is safe for concurrent +// use. +func (c *SequenceCounter) Next() int32 { + // Add returns the new value after incrementing, so subtract 1 + // to produce a zero-based sequence. + return c.next.Add(1) - 1 +} diff --git a/audit/sequence_test.go b/audit/sequence_test.go new file mode 100644 index 0000000..ffe51d3 --- /dev/null +++ b/audit/sequence_test.go @@ -0,0 +1,25 @@ +package audit + +import ( + "testing" +) + +func TestSequenceCounter_StartsAtZero(t *testing.T) { + t.Parallel() + + var c SequenceCounter + if got := c.Next(); got != 0 { + t.Fatalf("first call: got %d, want 0", got) + } +} + +func TestSequenceCounter_Increments(t *testing.T) { + t.Parallel() + + var c SequenceCounter + for i := range int32(100) { + if got := c.Next(); got != i { + t.Fatalf("call %d: got %d, want %d", i, got, i) + } + } +} diff --git a/audit/socket_auditor.go b/audit/socket_auditor.go index 4c8c5d8..afb50a3 100644 --- a/audit/socket_auditor.go +++ b/audit/socket_auditor.go @@ -8,6 +8,7 @@ import ( "sync/atomic" "time" + "github.com/google/uuid" "google.golang.org/protobuf/types/known/timestamppb" "github.com/coder/coder/v2/agent/boundarylogproxy/codec" @@ -34,6 +35,8 @@ type SocketAuditor struct { batchSize int batchTimerDuration time.Duration socketPath string + sessionID uuid.UUID + seq *SequenceCounter droppedChannelFull atomic.Int64 droppedBatchFull atomic.Int64 @@ -45,7 +48,7 @@ type SocketAuditor struct { // NewSocketAuditor creates a new SocketAuditor that sends logs to the agent's // boundary log proxy socket after SocketAuditor.Loop is called. The socket path // is read from EnvAuditSocketPath, falling back to defaultAuditSocketPath. -func NewSocketAuditor(logger *slog.Logger, socketPath string) *SocketAuditor { +func NewSocketAuditor(logger *slog.Logger, socketPath string, sessionID uuid.UUID, seq *SequenceCounter) *SocketAuditor { // This channel buffer size intends to allow enough buffering for bursty // AI agent network requests while a batch is being sent to the workspace // agent. @@ -60,6 +63,8 @@ func NewSocketAuditor(logger *slog.Logger, socketPath string) *SocketAuditor { batchSize: defaultBatchSize, batchTimerDuration: defaultBatchTimerDuration, socketPath: socketPath, + sessionID: sessionID, + seq: seq, } } @@ -77,9 +82,10 @@ func (s *SocketAuditor) AuditRequest(req Request) { } log := &agentproto.BoundaryLog{ - Allowed: req.Allowed, - Time: timestamppb.Now(), - Resource: &agentproto.BoundaryLog_HttpRequest_{HttpRequest: httpReq}, + Allowed: req.Allowed, + Time: timestamppb.Now(), + SequenceNumber: s.seq.Next(), + Resource: &agentproto.BoundaryLog_HttpRequest_{HttpRequest: httpReq}, } select { @@ -100,14 +106,17 @@ type flushErr struct { func (e *flushErr) Error() string { return e.err.Error() } // flush sends the current batch of logs to the given connection. -func flush(conn net.Conn, logs []*agentproto.BoundaryLog) *flushErr { +func flush(conn net.Conn, sessionID uuid.UUID, logs []*agentproto.BoundaryLog) *flushErr { if len(logs) == 0 { return nil } msg := &codec.BoundaryMessage{ Msg: &codec.BoundaryMessage_Logs{ - Logs: &agentproto.ReportBoundaryLogsRequest{Logs: logs}, + Logs: &agentproto.ReportBoundaryLogsRequest{ + Logs: logs, + SessionId: sessionID.String(), + }, }, } if err := codec.WriteMessage(conn, codec.TagV2, msg); err != nil { @@ -188,7 +197,7 @@ func (s *SocketAuditor) Loop(ctx context.Context) { return } - if err := flush(conn, batch); err != nil { + if err := flush(conn, s.sessionID, batch); err != nil { if err.permanent { // Data error: discard batch to avoid infinite retries. s.logger.Warn("dropping batch due to data error on flush attempt", diff --git a/audit/socket_auditor_test.go b/audit/socket_auditor_test.go index 67ebbae..6443781 100644 --- a/audit/socket_auditor_test.go +++ b/audit/socket_auditor_test.go @@ -11,6 +11,8 @@ import ( "testing" "time" + "github.com/google/uuid" + "github.com/coder/coder/v2/agent/boundarylogproxy/codec" agentproto "github.com/coder/coder/v2/agent/proto" ) @@ -33,6 +35,15 @@ func TestSocketAuditor_AuditRequest_QueuesLog(t *testing.T) { if log.Allowed != true { t.Errorf("expected Allowed=true, got %v", log.Allowed) } + if log.Time == nil { + t.Fatal("expected Time to be set") + } + if log.Time.AsTime().IsZero() { + t.Fatal("expected Time to not be the zero time") + } + if log.SequenceNumber != 0 { + t.Errorf("expected first SequenceNumber=0, got %d", log.SequenceNumber) + } httpReq := log.GetHttpRequest() if httpReq == nil { t.Fatal("expected HttpRequest, got nil") @@ -230,6 +241,8 @@ func TestSocketAuditor_Loop_RetriesOnConnectionFailure(t *testing.T) { logCh: make(chan *agentproto.BoundaryLog, 2*defaultBatchSize), batchSize: defaultBatchSize, batchTimerDuration: time.Hour, // Ensure timer doesn't interfere with the test + sessionID: uuid.MustParse("00000000-0000-4000-8000-000000000001"), + seq: &SequenceCounter{}, } // Set up hook to detect flush attempts @@ -349,6 +362,8 @@ func TestSocketAuditor_Loop_ReportsBatchFullDrops(t *testing.T) { logCh: make(chan *agentproto.BoundaryLog, 2*defaultBatchSize), batchSize: defaultBatchSize, batchTimerDuration: time.Hour, + sessionID: uuid.MustParse("00000000-0000-4000-8000-000000000001"), + seq: &SequenceCounter{}, } flushed := make(chan struct{}, 4) @@ -451,17 +466,75 @@ func TestSocketAuditor_Loop_ShutdownFlushIncludesDrops(t *testing.T) { func TestFlush_EmptyBatch(t *testing.T) { t.Parallel() - err := flush(nil, nil) + err := flush(nil, uuid.Nil, nil) if err != nil { t.Errorf("expected nil error for empty batch, got %v", err) } - err = flush(nil, []*agentproto.BoundaryLog{}) + err = flush(nil, uuid.Nil, []*agentproto.BoundaryLog{}) if err != nil { t.Errorf("expected nil error for empty slice, got %v", err) } } +func TestSocketAuditor_AuditRequest_SequenceNumberIncrements(t *testing.T) { + t.Parallel() + + auditor := setupSocketAuditor(t) + + for i := range 5 { + auditor.AuditRequest(Request{Method: "GET", URL: "https://example.com", Allowed: true}) + + select { + case log := <-auditor.logCh: + if log.SequenceNumber != int32(i) { + t.Errorf("request %d: expected SequenceNumber=%d, got %d", i, i, log.SequenceNumber) + } + default: + t.Fatalf("request %d: expected log in channel, got none", i) + } + } +} + +func TestSocketAuditor_Loop_FlushIncludesSessionID(t *testing.T) { + t.Parallel() + + auditor, serverConn := setupTestAuditor(t) + auditor.batchTimerDuration = time.Hour + + cr := newConnReader() + go readFromConn(t, serverConn, cr) + + go auditor.Loop(t.Context()) + + // Fill a batch to trigger a flush. + for i := 0; i < auditor.batchSize; i++ { + auditor.AuditRequest(Request{Method: "GET", URL: "https://example.com", Allowed: true}) + } + + select { + case req := <-cr.logs: + expectedSessionID := uuid.MustParse("00000000-0000-4000-8000-000000000001").String() + if req.SessionId != expectedSessionID { + t.Errorf("expected SessionId=%s, got %q", expectedSessionID, req.SessionId) + } + if len(req.Logs) != auditor.batchSize { + t.Errorf("expected %d logs, got %d", auditor.batchSize, len(req.Logs)) + } + // Verify sequence numbers are monotonically increasing. + for i, log := range req.Logs { + if log.SequenceNumber != int32(i) { + t.Errorf("log %d: expected SequenceNumber=%d, got %d", i, i, log.SequenceNumber) + } + if log.Time == nil { + t.Errorf("log %d: expected Time to be set", i) + } + } + case <-time.After(5 * time.Second): + t.Fatal("timeout waiting for flush") + } +} + // setupSocketAuditor creates a SocketAuditor for tests that only exercise // the queueing behavior (no connection needed). func setupSocketAuditor(t *testing.T) *SocketAuditor { @@ -475,6 +548,8 @@ func setupSocketAuditor(t *testing.T) *SocketAuditor { logCh: make(chan *agentproto.BoundaryLog, 2*defaultBatchSize), batchSize: defaultBatchSize, batchTimerDuration: defaultBatchTimerDuration, + sessionID: uuid.MustParse("00000000-0000-4000-8000-000000000001"), + seq: &SequenceCounter{}, } } @@ -504,6 +579,8 @@ func setupTestAuditor(t *testing.T) (*SocketAuditor, net.Conn) { logCh: make(chan *agentproto.BoundaryLog, 2*defaultBatchSize), batchSize: defaultBatchSize, batchTimerDuration: defaultBatchTimerDuration, + sessionID: uuid.MustParse("00000000-0000-4000-8000-000000000001"), + seq: &SequenceCounter{}, } return auditor, serverConn diff --git a/config/config.go b/config/config.go index d688834..73cdb38 100644 --- a/config/config.go +++ b/config/config.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/coder/serpent" + "github.com/google/uuid" "github.com/spf13/pflag" ) @@ -85,6 +86,11 @@ type AppConfig struct { UserInfo *UserInfo DisableAuditLogs bool LogProxySocketPath string + + // SessionID is a UUIDv4 generated at process startup. It groups + // all audit events produced by this boundary invocation into a + // single session. Set by Run, not by configuration. + SessionID uuid.UUID } func NewAppConfigFromCliConfig(cfg CliConfig, targetCMD []string) (AppConfig, error) { diff --git a/go.mod b/go.mod index 0188e84..a5e4732 100644 --- a/go.mod +++ b/go.mod @@ -1,21 +1,22 @@ module github.com/coder/boundary -go 1.25.7 +go 1.25.9 require ( github.com/cenkalti/backoff/v5 v5.0.3 - github.com/coder/coder/v2 v2.10.1-0.20260303212958-f758443f44ac + github.com/coder/coder/v2 v2.33.0-rc.3.0.20260501075247-b3e1178358f5 github.com/coder/serpent v0.14.0 + github.com/google/uuid v1.6.0 github.com/landlock-lsm/go-landlock v0.0.0-20251103212306-430f8e5cd97c github.com/miekg/dns v1.1.72 github.com/spf13/pflag v1.0.10 github.com/stretchr/testify v1.11.1 - golang.org/x/sys v0.41.0 + golang.org/x/sys v0.43.0 google.golang.org/protobuf v1.36.11 ) require ( - cdr.dev/slog/v3 v3.0.0-rc1 // indirect + cdr.dev/slog/v3 v3.0.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -38,16 +39,16 @@ require ( github.com/rivo/uniseg v0.4.7 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect github.com/zeebo/errs v1.4.0 // indirect - go.opentelemetry.io/otel v1.40.0 // indirect - go.opentelemetry.io/otel/trace v1.40.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect - golang.org/x/crypto v0.48.0 // indirect + golang.org/x/crypto v0.50.0 // indirect golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect - golang.org/x/mod v0.33.0 // indirect - golang.org/x/net v0.50.0 // indirect - golang.org/x/sync v0.19.0 // indirect - golang.org/x/term v0.40.0 // indirect - golang.org/x/tools v0.42.0 // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.53.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/term v0.42.0 // indirect + golang.org/x/tools v0.44.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gopkg.in/yaml.v3 v3.0.1 // indirect kernel.org/pub/linux/libs/security/libcap/psx v1.2.77 // indirect diff --git a/go.sum b/go.sum index d04ae6c..89d4da8 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cdr.dev/slog/v3 v3.0.0-rc1 h1:EN7Zim6GvTpAeHQjI0ERDEfqKbTyXRvgH4UhlzLpvWM= -cdr.dev/slog/v3 v3.0.0-rc1/go.mod h1:iO/OALX1VxlI03mkodCGdVP7pXzd2bRMvu3ePvlJ9ak= +cdr.dev/slog/v3 v3.0.0 h1:kXFUqAqK7ogRKcvo4BnduQVp+Jh0uV1AUKf3NW5FU74= +cdr.dev/slog/v3 v3.0.0/go.mod h1:iO/OALX1VxlI03mkodCGdVP7pXzd2bRMvu3ePvlJ9ak= cloud.google.com/go v0.123.0 h1:2NAUJwPR47q+E35uaJeYoNhuNEM9kM8SjgRgdeOJUSE= cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= @@ -28,14 +28,12 @@ github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMx github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= -github.com/clipperhouse/displaywidth v0.9.0 h1:Qb4KOhYwRiN3viMv1v/3cTBlz3AcAZX3+y9OLhMtAtA= -github.com/clipperhouse/displaywidth v0.9.0/go.mod h1:aCAAqTlh4GIVkhQnJpbL0T/WfcrJXHcj8C0yjYcjOZA= -github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs= -github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA= -github.com/clipperhouse/uax29/v2 v2.5.0 h1:x7T0T4eTHDONxFJsL94uKNKPHrclyFI0lm7+w94cO8U= -github.com/clipperhouse/uax29/v2 v2.5.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= -github.com/coder/coder/v2 v2.10.1-0.20260303212958-f758443f44ac h1:BmOs70CvLwP7dUt245ffapnSfMME0/tmI2M9nMi6O/w= -github.com/coder/coder/v2 v2.10.1-0.20260303212958-f758443f44ac/go.mod h1:ZyamF6ltx68UIQjbzUchKUTedpUIoyQlwCpOk5c+U4E= +github.com/clipperhouse/displaywidth v0.10.0 h1:GhBG8WuerxjFQQYeuZAeVTuyxuX+UraiZGD4HJQ3Y8g= +github.com/clipperhouse/displaywidth v0.10.0/go.mod h1:XqJajYsaiEwkxOj4bowCTMcT1SgvHo9flfF3jQasdbs= +github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos= +github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g= +github.com/coder/coder/v2 v2.33.0-rc.3.0.20260501075247-b3e1178358f5 h1:7V2ZTceP3V8EqYA8kC+3xrRwaZ8SOtgw4b8cElm0rcA= +github.com/coder/coder/v2 v2.33.0-rc.3.0.20260501075247-b3e1178358f5/go.mod h1:w3FcuW2hJS/QnmY7ilsvt0yVpUhlVYdnBozwTkmpkKE= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs= github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0/go.mod h1:5UuS2Ts+nTToAMeOjNlnHFkPahrtDkmpydBen/3wgZc= github.com/coder/serpent v0.14.0 h1:g7vt2zBMp3nWyAvyhvQduaI53Ku65U3wITMi01+/8pU= @@ -131,14 +129,14 @@ github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms= -go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g= -go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g= -go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc= -go.opentelemetry.io/otel/sdk v1.40.0 h1:KHW/jUzgo6wsPh9At46+h4upjtccTmuZCFAc9OJ71f8= -go.opentelemetry.io/otel/sdk v1.40.0/go.mod h1:Ph7EFdYvxq72Y8Li9q8KebuYUr2KoeyHx0DRMKrYBUE= -go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= -go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.uber.org/goleak v1.3.1-0.20240429205332-517bace7cc29 h1:w0QrHuh0hhUZ++UTQaBM2DMdrWQghZ/UsUb+Wb1+8YE= go.uber.org/goleak v1.3.1-0.20240429205332-517bace7cc29/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= @@ -146,14 +144,14 @@ go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= +golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= -golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/mod v0.35.0 h1:Ww1D637e6Pg+Zb2KrWfHQUnH2dQRLBQyAtpr/haaJeM= +golang.org/x/mod v0.35.0/go.mod h1:+GwiRhIInF8wPm+4AoT6L0FA1QWAad3OMdTRx4tFYlU= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -161,15 +159,15 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= -golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= -golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= +golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= +golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= +golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4= -golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -181,16 +179,16 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= -golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY= +golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -198,25 +196,25 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= +golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= -golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c= +golang.org/x/tools v0.44.0/go.mod h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d h1:vsOm753cOAMkt76efriTCDKjpCbK18XGHMJHo0JUKhc= -google.golang.org/genproto v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:0oz9d7g9QLSdv9/lgbIjowW1JoxMbxmBVNe8i6tORJI= -google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d h1:EocjzKLywydp5uZ5tJ79iP6Q0UjDnyiHkGRWxuPBP8s= -google.golang.org/genproto/googleapis/api v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:48U2I+QQUYhsFrg2SY6r+nJzeOtjey7j//WBESw+qyQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d h1:t/LOSXPJ9R0B6fnZNyALBRfZBH0Uy0gT+uR+SJ6syqQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260217215200-42d3e9bedb6d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.79.1 h1:zGhSi45ODB9/p3VAawt9a+O/MULLl9dpizzNNpq7flY= -google.golang.org/grpc v1.79.1/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0= +google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I= +google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7 h1:41r6JMbpzBMen0R/4TZeeAmGXSJC7DftGINUodzTkPI= +google.golang.org/genproto/googleapis/api v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:EIQZ5bFCfRQDV4MhRle7+OgjNtZ6P1PiZBgAKuxXu/Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/landjail/parent.go b/landjail/parent.go index 4cd7796..d399d3d 100644 --- a/landjail/parent.go +++ b/landjail/parent.go @@ -27,7 +27,7 @@ func RunParent(ctx context.Context, logger *slog.Logger, config config.AppConfig ruleEngine := rulesengine.NewRuleEngine(allowRules, logger) // Create auditor - auditor, err := audit.SetupAuditor(ctx, logger, config.DisableAuditLogs, config.LogProxySocketPath) + auditor, err := audit.SetupAuditor(ctx, logger, config.DisableAuditLogs, config.LogProxySocketPath, config.SessionID) if err != nil { return fmt.Errorf("failed to setup auditor: %v", err) } diff --git a/nsjail_manager/parent.go b/nsjail_manager/parent.go index 10554bf..e5d769b 100644 --- a/nsjail_manager/parent.go +++ b/nsjail_manager/parent.go @@ -28,7 +28,7 @@ func RunParent(ctx context.Context, logger *slog.Logger, config config.AppConfig ruleEngine := rulesengine.NewRuleEngine(allowRules, logger) // Create auditor - auditor, err := audit.SetupAuditor(ctx, logger, config.DisableAuditLogs, config.LogProxySocketPath) + auditor, err := audit.SetupAuditor(ctx, logger, config.DisableAuditLogs, config.LogProxySocketPath, config.SessionID) if err != nil { return fmt.Errorf("failed to setup auditor: %v", err) } diff --git a/run/run_linux.go b/run/run_linux.go index f67d82b..5344e79 100644 --- a/run/run_linux.go +++ b/run/run_linux.go @@ -10,9 +10,13 @@ import ( "github.com/coder/boundary/config" "github.com/coder/boundary/landjail" "github.com/coder/boundary/nsjail_manager" + "github.com/google/uuid" ) func Run(ctx context.Context, logger *slog.Logger, cfg config.AppConfig) error { + cfg.SessionID = uuid.New() + logger.Info("boundary session started", "session_id", cfg.SessionID.String()) + switch cfg.JailType { case config.NSJailType: return nsjail_manager.Run(ctx, logger, cfg)