From 143ab1a8d62a53ef7ed8159be13a23d99c6a316c Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:03:25 +0000 Subject: [PATCH 01/32] refactor: move IMA operator into internal/attest package Signed-off-by: Dor Serero --- cmd/micromize/root.go | 3 +- internal/attest/ima.go | 260 ++++++++++++++++++++++++++++++++ internal/operators/operators.go | 236 ----------------------------- 3 files changed, 262 insertions(+), 237 deletions(-) create mode 100644 internal/attest/ima.go diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index 61faae5..ec19ed0 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" + "github.com/micromize-dev/micromize/internal/attest" "github.com/micromize-dev/micromize/internal/gadget" k8sclient "github.com/micromize-dev/micromize/internal/k8s" "github.com/micromize-dev/micromize/internal/logger" @@ -115,7 +116,7 @@ func run(ctx context.Context) error { defer runtimeManager.Close() ociHandlerOp := operators.NewOCIHandler() - imaOp := operators.NewImaOperator() + imaOp := attest.NewImaOperator() eventTypeOp := operators.NewEventTypeOperator() outputOp := operators.NewOutputOperator() diff --git a/internal/attest/ima.go b/internal/attest/ima.go new file mode 100644 index 0000000..f775b0e --- /dev/null +++ b/internal/attest/ima.go @@ -0,0 +1,260 @@ +// Copyright The micromize authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package attest + +import ( + "context" + "encoding/hex" + "fmt" + "log/slog" + "math" + "strings" + "sync" + "time" + + "github.com/cilium/ebpf" + "github.com/inspektor-gadget/inspektor-gadget/pkg/datasource" + igoperators "github.com/inspektor-gadget/inspektor-gadget/pkg/operators" + "github.com/inspektor-gadget/inspektor-gadget/pkg/operators/simple" + + "github.com/micromize-dev/micromize/internal/sbom" +) + +// NewImaOperator creates and returns the IMA operator +func NewImaOperator() igoperators.DataOperator { + slog.Debug("Creating IMA operator") + opPriority := math.MaxInt + sbomFetcher := sbom.NewFetcher() + innerMaps := &sync.Map{} // mntns_id -> *ebpf.Map (for cleanup) + + operatorOptions := []simple.Option{ + simple.WithPriority(opPriority), + simple.OnInit(func(gadgetCtx igoperators.GadgetContext) error { + ctx := gadgetCtx.Context() + containersDatasource := gadgetCtx.GetDataSources()["containers"] + if containersDatasource == nil { + slog.Debug("IMA Operator: containers datasource not available, skipping") + return nil + } + + eventTypeField := containersDatasource.GetField("event_type") + if eventTypeField == nil { + return fmt.Errorf("containers datasource missing event_type field") + } + + containerConfigField := containersDatasource.GetField("container_config") + if containerConfigField == nil { + return fmt.Errorf("containers datasource missing container_config field") + } + + containerIDField := containersDatasource.GetField("container_id") + + mntnsIDField := containersDatasource.GetField("mntns_id") + + if err := containersDatasource.Subscribe(func(source datasource.DataSource, data datasource.Data) error { + eventType, err := eventTypeField.String(data) + if err != nil { + return fmt.Errorf("getting event_type value: %w", err) + } + switch eventType { + case "CREATED": + handleContainerCreated(ctx, gadgetCtx, sbomFetcher, innerMaps, containerConfigField, containerIDField, mntnsIDField, data) + case "REMOVED": + handleContainerRemoved(gadgetCtx, innerMaps, mntnsIDField, data) + } + return nil + }, opPriority); err != nil { + return fmt.Errorf("subscribing to containers datasource: %w", err) + } + return nil + }), + } + return simple.New("imaOperator", operatorOptions...) +} + +func handleContainerCreated(ctx context.Context, gadgetCtx igoperators.GadgetContext, fetcher *sbom.Fetcher, innerMaps *sync.Map, configField datasource.FieldAccessor, containerIDField datasource.FieldAccessor, mntnsIDField datasource.FieldAccessor, data datasource.Data) { + ociConfig, err := configField.String(data) + if err != nil { + slog.Debug("Failed to read container_config field", "error", err) + return + } + + imageRef, err := sbom.ImageRefFromOCIConfig(ociConfig) + if err != nil { + slog.Debug("Failed to parse OCI config", "error", err) + return + } + + // Fallback: read image ref from Docker's config.v2.json when + // OCI annotations don't contain the image name (plain Docker). + if imageRef == "" && containerIDField != nil { + containerID, _ := containerIDField.String(data) + imageRef = sbom.ImageRefFromDockerConfig(containerID) + } + + imageRef = sbom.NormalizeImageRef(imageRef) + + fetchCtx, cancel := context.WithTimeout(ctx, 30*time.Second) + defer cancel() + + sbomData, err := fetcher.FetchForImage(fetchCtx, imageRef) + if err != nil { + slog.Error("Failed to fetch SBOM", "error", err) + return + } + if sbomData != nil { + slog.Debug("SBOM fetched for container image", "image", imageRef, "size", len(sbomData)) + + files, err := sbom.ParseFiles(sbomData) + if err != nil { + slog.Error("Failed to parse SBOM files", "error", err) + return + } + for _, f := range files { + slog.Debug("SBOM binary file", "image", imageRef, "file", f.FileName, "sha256", f.SHA256) + } + + if mntnsIDField != nil && len(files) > 0 { + populateExpectedHashes(gadgetCtx, innerMaps, mntnsIDField, data, files) + } + } +} + +// Keep in sync with gadgets/binary-attestation/program.bpf.h +const ( + expectedHashesMapName = "map/expected_hashes" + maxAllowedFileHashes = 512 + sha256HashSize = 32 + maxFilepathLen = 64 +) + +func populateExpectedHashes(gadgetCtx igoperators.GadgetContext, innerMaps *sync.Map, mntnsIDField datasource.FieldAccessor, data datasource.Data, files []sbom.FileInfo) { + outerMapVar, ok := gadgetCtx.GetVar(expectedHashesMapName) + if !ok { + slog.Debug("expected_hashes map not available in gadget context, skipping map population") + return + } + + outerMap, ok := outerMapVar.(*ebpf.Map) + if !ok || outerMap == nil { + slog.Debug("expected_hashes map is not a valid *ebpf.Map, skipping") + return + } + + mntnsID, err := mntnsIDField.Uint64(data) + if err != nil { + slog.Error("Failed to read mntns_id field", "error", err) + return + } + + // Create a new inner map for this mount namespace + innerMapSpec := &ebpf.MapSpec{ + Type: ebpf.Hash, + KeySize: uint32(maxFilepathLen), + ValueSize: uint32(sha256HashSize), + MaxEntries: maxAllowedFileHashes, + } + + innerMap, err := ebpf.NewMap(innerMapSpec) + if err != nil { + slog.Error("Failed to create inner BPF map", "error", err) + return + } + + // Populate the inner map with file hashes from the SBOM + for _, f := range files { + var key [maxFilepathLen]byte + + if len(f.FileName) > maxFilepathLen { + slog.Error("SBOM file path exceeds maximum length", "file", f.FileName, "length", len(f.FileName)) + continue + } + // Normalize SBOM filename to match kernel dentry path format. + // SPDX filenames use "./" prefix (e.g. "./hello"), while the kernel + // returns absolute paths from the mount root (e.g. "/hello"). + name := f.FileName + name = strings.TrimPrefix(name, ".") + if !strings.HasPrefix(name, "/") { + name = "/" + name + } + copy(key[:], name) + + var value [sha256HashSize]byte + decoded, err := hex.DecodeString(f.SHA256) + if err != nil { + slog.Error("Failed to decode SHA256 hash", "file", f.FileName, "error", err) + continue + } + if len(decoded) != sha256HashSize { + slog.Error("Invalid SHA256 hash length", "file", f.FileName, "length", len(decoded)) + continue + } + copy(value[:], decoded) + + if err := innerMap.Put(key, value); err != nil { + slog.Error("Failed to insert entry into inner BPF map", "file", f.FileName, "error", err) + } + } + + // Insert the inner map into the outer map keyed by mntns_id + if err := outerMap.Put(mntnsID, uint32(innerMap.FD())); err != nil { + slog.Error("Failed to insert inner map into expected_hashes", "mntns_id", mntnsID, "error", err) + if err := innerMap.Close(); err != nil { + slog.Error("Failed to close inner BPF map", "mntns_id", mntnsID, "error", err) + } + return + } + + // Track the inner map for cleanup on container removal + innerMaps.Store(mntnsID, innerMap) + + slog.Debug("Populated expected_hashes map", "mntns_id", mntnsID, "entries", len(files)) +} + +func handleContainerRemoved(gadgetCtx igoperators.GadgetContext, innerMaps *sync.Map, mntnsIDField datasource.FieldAccessor, data datasource.Data) { + if mntnsIDField == nil { + slog.Debug("mntns_id field not available, cannot clean up expected_hashes for removed container") + return + } + + mntnsID, err := mntnsIDField.Uint64(data) + if err != nil { + slog.Debug("Failed to read mntns_id on container removal", "error", err) + return + } + + outerMapVar, ok := gadgetCtx.GetVar(expectedHashesMapName) + if !ok { + return + } + outerMap, ok := outerMapVar.(*ebpf.Map) + if !ok || outerMap == nil { + return + } + + if err := outerMap.Delete(mntnsID); err != nil { + slog.Debug("Failed to delete entry from expected_hashes", "mntns_id", mntnsID, "error", err) + } + + if val, loaded := innerMaps.LoadAndDelete(mntnsID); loaded { + if m, ok := val.(*ebpf.Map); ok && m != nil { + if err := m.Close(); err != nil { + slog.Debug("Failed to close inner BPF map on container removal", "mntns_id", mntnsID, "error", err) + } + } + } + + slog.Info("Cleaned up expected_hashes for removed container", "mntns_id", mntnsID) +} diff --git a/internal/operators/operators.go b/internal/operators/operators.go index 0b1719e..27e0222 100644 --- a/internal/operators/operators.go +++ b/internal/operators/operators.go @@ -15,16 +15,9 @@ package operators import ( - "context" - "encoding/hex" "fmt" "log/slog" - "math" - "strings" - "sync" - "time" - "github.com/cilium/ebpf" "github.com/inspektor-gadget/inspektor-gadget/pkg/datasource" api "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-service/api" igoperators "github.com/inspektor-gadget/inspektor-gadget/pkg/operators" @@ -34,8 +27,6 @@ import ( ocihandler "github.com/inspektor-gadget/inspektor-gadget/pkg/operators/oci-handler" "github.com/inspektor-gadget/inspektor-gadget/pkg/operators/simple" "github.com/inspektor-gadget/inspektor-gadget/pkg/utils/host" - - "github.com/micromize-dev/micromize/internal/sbom" ) // DataOperator is an alias for igoperators.DataOperator to avoid direct dependency in main @@ -67,233 +58,6 @@ func NewCLIOperator() igoperators.DataOperator { return clioperator.CLIOperator } -// NewImaOperator creates and returns the IMA operator -func NewImaOperator() igoperators.DataOperator { - slog.Debug("Creating IMA operator") - opPriority := math.MaxInt - sbomFetcher := sbom.NewFetcher() - innerMaps := &sync.Map{} // mntns_id -> *ebpf.Map (for cleanup) - - operatorOptions := []simple.Option{ - simple.WithPriority(opPriority), - simple.OnInit(func(gadgetCtx igoperators.GadgetContext) error { - ctx := gadgetCtx.Context() - containersDatasource := gadgetCtx.GetDataSources()["containers"] - if containersDatasource == nil { - slog.Debug("IMA Operator: containers datasource not available, skipping") - return nil - } - - eventTypeField := containersDatasource.GetField("event_type") - if eventTypeField == nil { - return fmt.Errorf("containers datasource missing event_type field") - } - - containerConfigField := containersDatasource.GetField("container_config") - if containerConfigField == nil { - return fmt.Errorf("containers datasource missing container_config field") - } - - containerIDField := containersDatasource.GetField("container_id") - - mntnsIDField := containersDatasource.GetField("mntns_id") - - if err := containersDatasource.Subscribe(func(source datasource.DataSource, data datasource.Data) error { - eventType, err := eventTypeField.String(data) - if err != nil { - return fmt.Errorf("getting event_type value: %w", err) - } - switch eventType { - case "CREATED": - handleContainerCreated(ctx, gadgetCtx, sbomFetcher, innerMaps, containerConfigField, containerIDField, mntnsIDField, data) - case "REMOVED": - handleContainerRemoved(gadgetCtx, innerMaps, mntnsIDField, data) - } - return nil - }, opPriority); err != nil { - return fmt.Errorf("subscribing to containers datasource: %w", err) - } - return nil - }), - } - return simple.New("imaOperator", operatorOptions...) -} - -func handleContainerCreated(ctx context.Context, gadgetCtx igoperators.GadgetContext, fetcher *sbom.Fetcher, innerMaps *sync.Map, configField datasource.FieldAccessor, containerIDField datasource.FieldAccessor, mntnsIDField datasource.FieldAccessor, data datasource.Data) { - ociConfig, err := configField.String(data) - if err != nil { - slog.Debug("Failed to read container_config field", "error", err) - return - } - - imageRef, err := sbom.ImageRefFromOCIConfig(ociConfig) - if err != nil { - slog.Debug("Failed to parse OCI config", "error", err) - return - } - - // Fallback: read image ref from Docker's config.v2.json when - // OCI annotations don't contain the image name (plain Docker). - if imageRef == "" && containerIDField != nil { - containerID, _ := containerIDField.String(data) - imageRef = sbom.ImageRefFromDockerConfig(containerID) - } - - imageRef = sbom.NormalizeImageRef(imageRef) - - fetchCtx, cancel := context.WithTimeout(ctx, 30*time.Second) - defer cancel() - - sbomData, err := fetcher.FetchForImage(fetchCtx, imageRef) - if err != nil { - slog.Error("Failed to fetch SBOM", "error", err) - return - } - if sbomData != nil { - slog.Debug("SBOM fetched for container image", "image", imageRef, "size", len(sbomData)) - - files, err := sbom.ParseFiles(sbomData) - if err != nil { - slog.Error("Failed to parse SBOM files", "error", err) - return - } - for _, f := range files { - slog.Debug("SBOM binary file", "image", imageRef, "file", f.FileName, "sha256", f.SHA256) - } - - if mntnsIDField != nil && len(files) > 0 { - populateExpectedHashes(gadgetCtx, innerMaps, mntnsIDField, data, files) - } - } -} - -// Keep in sync with gadgets/binary-attestation/program.bpf.h -const ( - expectedHashesMapName = "map/expected_hashes" - maxAllowedFileHashes = 512 - sha256HashSize = 32 - maxFilepathLen = 64 -) - -func populateExpectedHashes(gadgetCtx igoperators.GadgetContext, innerMaps *sync.Map, mntnsIDField datasource.FieldAccessor, data datasource.Data, files []sbom.FileInfo) { - outerMapVar, ok := gadgetCtx.GetVar(expectedHashesMapName) - if !ok { - slog.Debug("expected_hashes map not available in gadget context, skipping map population") - return - } - - outerMap, ok := outerMapVar.(*ebpf.Map) - if !ok || outerMap == nil { - slog.Debug("expected_hashes map is not a valid *ebpf.Map, skipping") - return - } - - mntnsID, err := mntnsIDField.Uint64(data) - if err != nil { - slog.Error("Failed to read mntns_id field", "error", err) - return - } - - // Create a new inner map for this mount namespace - innerMapSpec := &ebpf.MapSpec{ - Type: ebpf.Hash, - KeySize: uint32(maxFilepathLen), - ValueSize: uint32(sha256HashSize), - MaxEntries: maxAllowedFileHashes, - } - - innerMap, err := ebpf.NewMap(innerMapSpec) - if err != nil { - slog.Error("Failed to create inner BPF map", "error", err) - return - } - - // Populate the inner map with file hashes from the SBOM - for _, f := range files { - var key [maxFilepathLen]byte - - if len(f.FileName) > maxFilepathLen { - slog.Error("SBOM file path exceeds maximum length", "file", f.FileName, "length", len(f.FileName)) - continue - } - // Normalize SBOM filename to match kernel dentry path format. - // SPDX filenames use "./" prefix (e.g. "./hello"), while the kernel - // returns absolute paths from the mount root (e.g. "/hello"). - name := f.FileName - name = strings.TrimPrefix(name, ".") - if !strings.HasPrefix(name, "/") { - name = "/" + name - } - copy(key[:], name) - - var value [sha256HashSize]byte - decoded, err := hex.DecodeString(f.SHA256) - if err != nil { - slog.Error("Failed to decode SHA256 hash", "file", f.FileName, "error", err) - continue - } - if len(decoded) != sha256HashSize { - slog.Error("Invalid SHA256 hash length", "file", f.FileName, "length", len(decoded)) - continue - } - copy(value[:], decoded) - - if err := innerMap.Put(key, value); err != nil { - slog.Error("Failed to insert entry into inner BPF map", "file", f.FileName, "error", err) - } - } - - // Insert the inner map into the outer map keyed by mntns_id - if err := outerMap.Put(mntnsID, uint32(innerMap.FD())); err != nil { - slog.Error("Failed to insert inner map into expected_hashes", "mntns_id", mntnsID, "error", err) - if err := innerMap.Close(); err != nil { - slog.Error("Failed to close inner BPF map", "mntns_id", mntnsID, "error", err) - } - return - } - - // Track the inner map for cleanup on container removal - innerMaps.Store(mntnsID, innerMap) - - slog.Debug("Populated expected_hashes map", "mntns_id", mntnsID, "entries", len(files)) -} - -func handleContainerRemoved(gadgetCtx igoperators.GadgetContext, innerMaps *sync.Map, mntnsIDField datasource.FieldAccessor, data datasource.Data) { - if mntnsIDField == nil { - slog.Debug("mntns_id field not available, cannot clean up expected_hashes for removed container") - return - } - - mntnsID, err := mntnsIDField.Uint64(data) - if err != nil { - slog.Debug("Failed to read mntns_id on container removal", "error", err) - return - } - - outerMapVar, ok := gadgetCtx.GetVar(expectedHashesMapName) - if !ok { - return - } - outerMap, ok := outerMapVar.(*ebpf.Map) - if !ok || outerMap == nil { - return - } - - if err := outerMap.Delete(mntnsID); err != nil { - slog.Debug("Failed to delete entry from expected_hashes", "mntns_id", mntnsID, "error", err) - } - - if val, loaded := innerMaps.LoadAndDelete(mntnsID); loaded { - if m, ok := val.(*ebpf.Map); ok && m != nil { - if err := m.Close(); err != nil { - slog.Debug("Failed to close inner BPF map on container removal", "mntns_id", mntnsID, "error", err) - } - } - } - - slog.Info("Cleaned up expected_hashes for removed container", "mntns_id", mntnsID) -} - // Event type constants matching include/micromize/event_types.h const ( eventTypeUnknown = 0 From d954afadbc6e5c964e81029fa602ad280a9b8b89 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:05:13 +0000 Subject: [PATCH 02/32] refactor: rename binary-attestation gadget to sigward Signed-off-by: Dor Serero --- Dockerfile | 2 +- Makefile | 2 +- cmd/micromize/embeds.go | 4 ++-- cmd/micromize/embeds_dev.go | 2 +- cmd/micromize/root.go | 18 +++++++++--------- .../gadget.yaml | 10 +++++----- .../program.bpf.c | 18 +++++++++--------- .../program.bpf.h | 0 include/micromize/event_types.h | 2 +- internal/attest/ima.go | 2 +- 10 files changed, 30 insertions(+), 30 deletions(-) rename gadgets/{binary-attestation => sigward}/gadget.yaml (91%) rename gadgets/{binary-attestation => sigward}/program.bpf.c (87%) rename gadgets/{binary-attestation => sigward}/program.bpf.h (100%) diff --git a/Dockerfile b/Dockerfile index b72953f..d660adc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ COPY gadgets gadgets # Build gadgets RUN mkdir -p build/gadgets && \ - for gadget in fs-restrict cap-restrict ptrace-restrict socket-restrict binary-attestation; do \ + for gadget in fs-restrict cap-restrict ptrace-restrict socket-restrict sigward; do \ echo "Building gadget: $gadget" && \ ig image build \ --local \ diff --git a/Makefile b/Makefile index 9b107d9..fe94761 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ GOARCHS := amd64 arm64 LDFLAGS := -X github.com/inspektor-gadget/inspektor-gadget/internal/version.version=v0.47.0 \ -X main.Version=$(IMAGE_TAG) \ -w -s -extldflags "-static" -GADGETS := fs-restrict cap-restrict ptrace-restrict socket-restrict binary-attestation +GADGETS := fs-restrict cap-restrict ptrace-restrict socket-restrict sigward CONFORM_VERSION ?= v0.1.0-alpha.30 # This version number must be kept in sync with CI workflow lint one. diff --git a/cmd/micromize/embeds.go b/cmd/micromize/embeds.go index 53bcc75..02f9cda 100644 --- a/cmd/micromize/embeds.go +++ b/cmd/micromize/embeds.go @@ -32,5 +32,5 @@ var ptraceRestrictGadgetBytes []byte //go:embed build/socket-restrict.tar var socketRestrictGadgetBytes []byte -//go:embed build/binary-attestation.tar -var binaryAttestationGadgetBytes []byte +//go:embed build/sigward.tar +var sigwardGadgetBytes []byte diff --git a/cmd/micromize/embeds_dev.go b/cmd/micromize/embeds_dev.go index 370e4f3..7614e4c 100644 --- a/cmd/micromize/embeds_dev.go +++ b/cmd/micromize/embeds_dev.go @@ -20,4 +20,4 @@ var fsRestrictGadgetBytes []byte var capRestrictGadgetBytes []byte var ptraceRestrictGadgetBytes []byte var socketRestrictGadgetBytes []byte -var binaryAttestationGadgetBytes []byte +var sigwardGadgetBytes []byte diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index ec19ed0..12b521c 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -36,11 +36,11 @@ import ( ) const ( - fsRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/fs-restrict" - capRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/cap-restrict" - ptraceRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/ptrace-restrict" - socketRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/socket-restrict" - binaryAttestationGadgetImageRepo = "ghcr.io/micromize-dev/micromize/binary-attestation" + fsRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/fs-restrict" + capRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/cap-restrict" + ptraceRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/ptrace-restrict" + socketRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/socket-restrict" + sigwardGadgetImageRepo = "ghcr.io/micromize-dev/micromize/sigward" ) var ( @@ -214,10 +214,10 @@ func run(ctx context.Context) error { }) } - if !disabled["binary-attestation"] { - registry.Register("binary-attestation", &gadget.GadgetConfig{ - Bytes: binaryAttestationGadgetBytes, - ImageName: fmt.Sprintf("%s:%s", binaryAttestationGadgetImageRepo, Version), + if !disabled["sigward"] { + registry.Register("sigward", &gadget.GadgetConfig{ + Bytes: sigwardGadgetBytes, + ImageName: fmt.Sprintf("%s:%s", sigwardGadgetImageRepo, Version), Params: commonParams, }) } diff --git a/gadgets/binary-attestation/gadget.yaml b/gadgets/sigward/gadget.yaml similarity index 91% rename from gadgets/binary-attestation/gadget.yaml rename to gadgets/sigward/gadget.yaml index cd84c89..3ba852c 100644 --- a/gadgets/binary-attestation/gadget.yaml +++ b/gadgets/sigward/gadget.yaml @@ -1,12 +1,12 @@ -name: binary-attestation +name: sigward description: Attest binary and shared object integrity using IMA file hashes -homepageURL: https://github.com/micromize-dev/micromize/tree/main/gadgets/binary-attestation -documentationURL: https://github.com/micromize-dev/micromize/tree/main/gadgets/binary-attestation -sourceURL: https://github.com/micromize-dev/micromize/tree/main/gadgets/binary-attestation +homepageURL: https://github.com/micromize-dev/micromize/tree/main/gadgets/sigward +documentationURL: https://github.com/micromize-dev/micromize/tree/main/gadgets/sigward +sourceURL: https://github.com/micromize-dev/micromize/tree/main/gadgets/sigward annotations: enable-containers-datasource: "true" datasources: - binary_attestation: + sigward: fields: event_type: annotations: diff --git a/gadgets/binary-attestation/program.bpf.c b/gadgets/sigward/program.bpf.c similarity index 87% rename from gadgets/binary-attestation/program.bpf.c rename to gadgets/sigward/program.bpf.c index df6a970..275b204 100644 --- a/gadgets/binary-attestation/program.bpf.c +++ b/gadgets/sigward/program.bpf.c @@ -16,7 +16,7 @@ GADGET_PARAM(enforce); GADGET_TRACER_MAP(events, 1024 * 256); -GADGET_TRACER(binary_attestation, events, event); +GADGET_TRACER(sigward, events, event); // Inner map template: filepath -> sha256 struct { @@ -62,7 +62,7 @@ attest_file(void *ctx, struct file *file, __u32 unattested_event_type, // Look up the expected hash for this file path struct sha256_hash *expected = bpf_map_lookup_elem(inner, &fkey); if (!expected) { - bpf_printk("binary-attestation: Unattested file %s in mntns_id=%llu\n", + bpf_printk("sigward: Unattested file %s in mntns_id=%llu\n", fkey.path, mntns_id); struct event *event; @@ -85,24 +85,24 @@ attest_file(void *ctx, struct file *file, __u32 unattested_event_type, } bpf_printk( - "binary-attestation: Found expected hash for file %s in mntns_id=%llu\n", + "sigward: Found expected hash for file %s in mntns_id=%llu\n", fkey.path, mntns_id); // Calculate the IMA hash of the file struct sha256_hash computed = {}; long ret = bpf_ima_file_hash(file, computed.hash, SHA256_HASH_SIZE); - bpf_printk("binary-attestation: bpf_ima_file_hash returned %ld for %s\n", ret, + bpf_printk("sigward: bpf_ima_file_hash returned %ld for %s\n", ret, fkey.path); if (ret != HASH_ALGO_SHA256) { // IMA did not return a SHA256 hash (e.g., disabled or misconfigured). // Logging so operators can detect that attestation was skipped. - bpf_printk("binary-attestation: IMA hash algorithm (%ld) is not SHA256; " + bpf_printk("sigward: IMA hash algorithm (%ld) is not SHA256; " "skipping attestation for %s in mntns_id=%llu\n", ret, fkey.path, mntns_id); return 0; } - bpf_printk("binary-attestation: Computed hash for file %s in mntns_id=%llu\n", + bpf_printk("sigward: Computed hash for file %s in mntns_id=%llu\n", fkey.path, mntns_id); // Compare computed hash with the expected hash @@ -110,7 +110,7 @@ attest_file(void *ctx, struct file *file, __u32 unattested_event_type, for (i = 0; i < SHA256_HASH_SIZE; i++) { if (computed.hash[i] != expected->hash[i]) { bpf_printk( - "binary-attestation: Hash mismatch for %s in mntns_id=%llu\n", + "sigward: Hash mismatch for %s in mntns_id=%llu\n", fkey.path, mntns_id); struct event *event; @@ -137,7 +137,7 @@ attest_file(void *ctx, struct file *file, __u32 unattested_event_type, } SEC("lsm.s/bprm_check_security") -int BPF_PROG(micromize_bprm_check_security, struct linux_binprm *bprm, +int BPF_PROG(sigward_bprm_check_security, struct linux_binprm *bprm, int ret) { // Preserve a deny decision from a previously-run LSM program in the chain. if (ret) @@ -151,7 +151,7 @@ int BPF_PROG(micromize_bprm_check_security, struct linux_binprm *bprm, } SEC("lsm.s/mmap_file") -int BPF_PROG(micromize_mmap_file, struct file *file, unsigned long reqprot, +int BPF_PROG(sigward_mmap_file, struct file *file, unsigned long reqprot, unsigned long prot, unsigned long flags, int ret) { // Preserve a deny decision from a previously-run LSM program in the chain. if (ret) diff --git a/gadgets/binary-attestation/program.bpf.h b/gadgets/sigward/program.bpf.h similarity index 100% rename from gadgets/binary-attestation/program.bpf.h rename to gadgets/sigward/program.bpf.h diff --git a/include/micromize/event_types.h b/include/micromize/event_types.h index 1c21bbd..5d804f0 100644 --- a/include/micromize/event_types.h +++ b/include/micromize/event_types.h @@ -20,7 +20,7 @@ enum micromize_event_type { EVENT_TYPE_PTRACE_ACCESS = 5, EVENT_TYPE_PTRACE_TRACEME = 6, - // binary-attestation + // sigward EVENT_TYPE_UNATTESTED_BINARY = 7, EVENT_TYPE_HASH_MISMATCH = 8, EVENT_TYPE_UNATTESTED_SHARED_OBJECT = 9, diff --git a/internal/attest/ima.go b/internal/attest/ima.go index f775b0e..f2dd110 100644 --- a/internal/attest/ima.go +++ b/internal/attest/ima.go @@ -132,7 +132,7 @@ func handleContainerCreated(ctx context.Context, gadgetCtx igoperators.GadgetCon } } -// Keep in sync with gadgets/binary-attestation/program.bpf.h +// Keep in sync with gadgets/sigward/program.bpf.h const ( expectedHashesMapName = "map/expected_hashes" maxAllowedFileHashes = 512 From 48f30ba8a6472076fccccfbca5bf3a2505a3b9d5 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:06:48 +0000 Subject: [PATCH 03/32] feat: add sigward command Signed-off-by: Dor Serero --- cmd/sigward/embeds.go | 24 +++++ cmd/sigward/embeds_dev.go | 19 ++++ cmd/sigward/main.go | 23 +++++ cmd/sigward/root.go | 199 ++++++++++++++++++++++++++++++++++++++ cmd/sigward/root_test.go | 60 ++++++++++++ 5 files changed, 325 insertions(+) create mode 100644 cmd/sigward/embeds.go create mode 100644 cmd/sigward/embeds_dev.go create mode 100644 cmd/sigward/main.go create mode 100644 cmd/sigward/root.go create mode 100644 cmd/sigward/root_test.go diff --git a/cmd/sigward/embeds.go b/cmd/sigward/embeds.go new file mode 100644 index 0000000..bd169ab --- /dev/null +++ b/cmd/sigward/embeds.go @@ -0,0 +1,24 @@ +// Copyright The micromize authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build release + +package main + +import ( + _ "embed" +) + +//go:embed build/sigward.tar +var sigwardGadgetBytes []byte diff --git a/cmd/sigward/embeds_dev.go b/cmd/sigward/embeds_dev.go new file mode 100644 index 0000000..ae456de --- /dev/null +++ b/cmd/sigward/embeds_dev.go @@ -0,0 +1,19 @@ +// Copyright The micromize authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !release + +package main + +var sigwardGadgetBytes []byte diff --git a/cmd/sigward/main.go b/cmd/sigward/main.go new file mode 100644 index 0000000..34681c1 --- /dev/null +++ b/cmd/sigward/main.go @@ -0,0 +1,23 @@ +// Copyright The micromize authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +// Version is the version of the gadgets to run. +// It is set at build time via -ldflags. +var Version = "latest" + +func main() { + Execute() +} diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go new file mode 100644 index 0000000..f7c84d2 --- /dev/null +++ b/cmd/sigward/root.go @@ -0,0 +1,199 @@ +// Copyright The micromize authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "context" + _ "embed" + "fmt" + "log/slog" + "os" + "os/signal" + "strings" + "syscall" + + "github.com/spf13/cobra" + + "github.com/micromize-dev/micromize/internal/attest" + "github.com/micromize-dev/micromize/internal/gadget" + k8sclient "github.com/micromize-dev/micromize/internal/k8s" + "github.com/micromize-dev/micromize/internal/logger" + "github.com/micromize-dev/micromize/internal/operators" + "github.com/micromize-dev/micromize/internal/runtime" + "github.com/micromize-dev/micromize/internal/utils" +) + +const sigwardGadgetImageRepo = "ghcr.io/micromize-dev/micromize/sigward" + +var ( + enforce bool + verbose bool + filterNamespaces string + filterImageDigest string + exemptLabel string +) + +var rootCmd = &cobra.Command{ + Use: "sigward", + Short: "sigward enforces execution integrity for containerized applications", + Long: `sigward verifies, in the kernel, that only cryptographically attested binaries and shared objects declared in a container image's signed SBOM are allowed to execute, using BPF LSM and IMA.`, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + logger.Setup(verbose) + }, + RunE: func(cmd *cobra.Command, args []string) error { + return run(cmd.Context()) + }, +} + +func Execute() { + if err := rootCmd.Execute(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +func init() { + rootCmd.Version = Version + rootCmd.PersistentFlags().BoolVar(&enforce, "enforce", true, "Enforce restrictions") + rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging") + rootCmd.PersistentFlags().StringVar(&filterNamespaces, "filter-namespaces", "", "Comma-separated list of Kubernetes namespaces to monitor (empty means all except 'sigward'). Supports exclusion with '!' prefix.") + rootCmd.PersistentFlags().StringVar(&filterImageDigest, "filter-image-digest", "", "Filter out containers running this image digest from monitoring (e.g. sha256:abc123...)") + rootCmd.PersistentFlags().StringVar(&exemptLabel, "exempt-label", "sigward.dev/exempt", "Kubernetes label key used to mark namespaces as exempt from monitoring (value must be 'true'). Set to empty string to disable. Changes take effect on restart.") +} + +func run(ctx context.Context) error { + slog.Info("Starting sigward...") + + // Validate BPF LSM is enabled before starting + if err := utils.ValidateBPFLSM(); err != nil { + return fmt.Errorf("BPF LSM validation failed: %w", err) + } + slog.Info("BPF LSM is enabled") + + if enforce { + slog.Info("Enforcement enabled") + } else { + slog.Info("Enforcement disabled (audit mode)") + } + + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + // Handle graceful shutdown + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + <-sigChan + slog.Info("Received shutdown signal") + cancel() + }() + + runtimeManager, err := runtime.NewManager() + if err != nil { + return fmt.Errorf("initializing runtime manager: %w", err) + } + + defer runtimeManager.Close() + + ociHandlerOp := operators.NewOCIHandler() + imaOp := attest.NewImaOperator() + eventTypeOp := operators.NewEventTypeOperator() + outputOp := operators.NewOutputOperator() + + localManagerOp, err := operators.NewLocalManager() + if err != nil { + return fmt.Errorf("creating local manager operator: %w", err) + } + + contextManager := gadget.NewContextManager([]operators.DataOperator{ociHandlerOp, localManagerOp, imaOp, eventTypeOp, outputOp}) + + // Create gadget registry + registry := gadget.NewRegistry(contextManager, runtimeManager) + + nsFilter := buildNamespaceFilter(filterNamespaces) + + // Discover namespaces exempt by label and append them as exclusions. + // Evaluated at startup only — a DaemonSet restart is required to pick up + // changes to namespace labels. + if exemptLabel != "" { + k8s, err := k8sclient.NewClient() + if err != nil { + slog.Warn("Could not build Kubernetes client for exempt label discovery; skipping", "error", err) + } else { + exemptNS, err := k8sclient.ListExemptNamespaces(ctx, k8s, exemptLabel) + if err != nil { + slog.Warn("Could not list exempt namespaces; skipping", "label", exemptLabel, "error", err) + } else if len(exemptNS) > 0 { + slog.Info("Exempt namespaces discovered (startup only)", "namespaces", exemptNS, "label", exemptLabel) + for _, ns := range exemptNS { + nsFilter += ",!" + ns + } + } + } + } + + slog.Info("Namespace filter", "filter", nsFilter) + + commonParams := map[string]string{ + "operator.oci.ebpf.enforce": fmt.Sprintf("%d", utils.BoolToInt(enforce)), + "operator.LocalManager.k8s-namespace": nsFilter, + } + + if filterImageDigest != "" { + digest := strings.TrimPrefix(filterImageDigest, "!") + commonParams["operator.LocalManager.runtime-containerimage-digest"] = "!" + digest + slog.Info("Filtering out containers by image digest", "digest", digest) + } + + registry.Register("sigward", &gadget.GadgetConfig{ + Bytes: sigwardGadgetBytes, + ImageName: fmt.Sprintf("%s:%s", sigwardGadgetImageRepo, Version), + Params: commonParams, + }) + + // Run all gadgets + if err := registry.RunAll(ctx); err != nil { + return fmt.Errorf("running gadgets: %w", err) + } + + // Wait for context to be done (which happens on signal) + <-ctx.Done() + return nil +} + +// buildNamespaceFilter constructs the k8s-namespace filter value. +// It always excludes the "sigward" namespace and appends any user-specified +// namespace filters. When filterNamespaces is empty, only "!sigward" is used. +func buildNamespaceFilter(filterNamespaces string) string { + const excludeSigward = "!sigward" + normalizedFilter := excludeSigward + + if filterNamespaces == "" { + return normalizedFilter + } + + parts := strings.Split(filterNamespaces, ",") + for _, p := range parts { + nsPart := strings.TrimSpace(p) + if nsPart == "" { + continue + } + if nsPart != excludeSigward { + normalizedFilter += "," + nsPart + } + } + + return normalizedFilter +} diff --git a/cmd/sigward/root_test.go b/cmd/sigward/root_test.go new file mode 100644 index 0000000..e263a4b --- /dev/null +++ b/cmd/sigward/root_test.go @@ -0,0 +1,60 @@ +// Copyright The micromize authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import "testing" + +func TestBuildNamespaceFilter(t *testing.T) { + tests := []struct { + name string + filterNamespaces string + want string + }{ + { + name: "empty filter returns only sigward exclusion", + filterNamespaces: "", + want: "!sigward", + }, + { + name: "single namespace appends sigward exclusion", + filterNamespaces: "default", + want: "!sigward,default", + }, + { + name: "multiple namespaces append sigward exclusion", + filterNamespaces: "default,kube-system", + want: "!sigward,default,kube-system", + }, + { + name: "user already excludes sigward", + filterNamespaces: "default,!sigward", + want: "!sigward,default", + }, + { + name: "empty segments are skipped", + filterNamespaces: "default,,kube-system,", + want: "!sigward,default,kube-system", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := buildNamespaceFilter(tt.filterNamespaces) + if got != tt.want { + t.Errorf("buildNamespaceFilter(%q) = %q, want %q", tt.filterNamespaces, got, tt.want) + } + }) + } +} From da8b874236ad13002667bd3436ad0ad27efb6dba Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:09:22 +0000 Subject: [PATCH 04/32] refactor: drop attestation gadget from micromize command Signed-off-by: Dor Serero --- cmd/micromize/embeds.go | 3 --- cmd/micromize/embeds_dev.go | 1 - cmd/micromize/root.go | 13 +------------ 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/cmd/micromize/embeds.go b/cmd/micromize/embeds.go index 02f9cda..cef38eb 100644 --- a/cmd/micromize/embeds.go +++ b/cmd/micromize/embeds.go @@ -31,6 +31,3 @@ var ptraceRestrictGadgetBytes []byte //go:embed build/socket-restrict.tar var socketRestrictGadgetBytes []byte - -//go:embed build/sigward.tar -var sigwardGadgetBytes []byte diff --git a/cmd/micromize/embeds_dev.go b/cmd/micromize/embeds_dev.go index 7614e4c..16d1fbf 100644 --- a/cmd/micromize/embeds_dev.go +++ b/cmd/micromize/embeds_dev.go @@ -20,4 +20,3 @@ var fsRestrictGadgetBytes []byte var capRestrictGadgetBytes []byte var ptraceRestrictGadgetBytes []byte var socketRestrictGadgetBytes []byte -var sigwardGadgetBytes []byte diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index 12b521c..b712644 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -26,7 +26,6 @@ import ( "github.com/spf13/cobra" - "github.com/micromize-dev/micromize/internal/attest" "github.com/micromize-dev/micromize/internal/gadget" k8sclient "github.com/micromize-dev/micromize/internal/k8s" "github.com/micromize-dev/micromize/internal/logger" @@ -40,7 +39,6 @@ const ( capRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/cap-restrict" ptraceRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/ptrace-restrict" socketRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/socket-restrict" - sigwardGadgetImageRepo = "ghcr.io/micromize-dev/micromize/sigward" ) var ( @@ -116,7 +114,6 @@ func run(ctx context.Context) error { defer runtimeManager.Close() ociHandlerOp := operators.NewOCIHandler() - imaOp := attest.NewImaOperator() eventTypeOp := operators.NewEventTypeOperator() outputOp := operators.NewOutputOperator() @@ -125,7 +122,7 @@ func run(ctx context.Context) error { return fmt.Errorf("creating local manager operator: %w", err) } - contextManager := gadget.NewContextManager([]operators.DataOperator{ociHandlerOp, localManagerOp, imaOp, eventTypeOp, outputOp}) + contextManager := gadget.NewContextManager([]operators.DataOperator{ociHandlerOp, localManagerOp, eventTypeOp, outputOp}) // Create gadget registry registry := gadget.NewRegistry(contextManager, runtimeManager) @@ -214,14 +211,6 @@ func run(ctx context.Context) error { }) } - if !disabled["sigward"] { - registry.Register("sigward", &gadget.GadgetConfig{ - Bytes: sigwardGadgetBytes, - ImageName: fmt.Sprintf("%s:%s", sigwardGadgetImageRepo, Version), - Params: commonParams, - }) - } - // Run all gadgets if err := registry.RunAll(ctx); err != nil { return fmt.Errorf("running gadgets: %w", err) From 690a31ff577a2ebf57b1f4dcb20faa391033df21 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:09:50 +0000 Subject: [PATCH 05/32] feat: add sigward helm chart Signed-off-by: Dor Serero --- charts/sigward/Chart.yaml | 6 + charts/sigward/templates/NOTES.txt | 11 ++ charts/sigward/templates/_helpers.tpl | 62 ++++++++ charts/sigward/templates/clusterrole.yaml | 22 +++ .../sigward/templates/clusterrolebinding.yaml | 16 ++ charts/sigward/templates/daemonset.yaml | 145 ++++++++++++++++++ charts/sigward/templates/serviceaccount.yaml | 12 ++ charts/sigward/values.schema.json | 106 +++++++++++++ charts/sigward/values.yaml | 62 ++++++++ 9 files changed, 442 insertions(+) create mode 100644 charts/sigward/Chart.yaml create mode 100644 charts/sigward/templates/NOTES.txt create mode 100644 charts/sigward/templates/_helpers.tpl create mode 100644 charts/sigward/templates/clusterrole.yaml create mode 100644 charts/sigward/templates/clusterrolebinding.yaml create mode 100644 charts/sigward/templates/daemonset.yaml create mode 100644 charts/sigward/templates/serviceaccount.yaml create mode 100644 charts/sigward/values.schema.json create mode 100644 charts/sigward/values.yaml diff --git a/charts/sigward/Chart.yaml b/charts/sigward/Chart.yaml new file mode 100644 index 0000000..e1456eb --- /dev/null +++ b/charts/sigward/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: sigward +description: A Helm chart for Sigward - kernel-enforced execution integrity for containers +type: application +version: 0.1.0 +appVersion: "0.1.0" diff --git a/charts/sigward/templates/NOTES.txt b/charts/sigward/templates/NOTES.txt new file mode 100644 index 0000000..2520e64 --- /dev/null +++ b/charts/sigward/templates/NOTES.txt @@ -0,0 +1,11 @@ +Sigward has been installed. + +To verify that the agents are running: + + kubectl get pods -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} + +To check logs: + + kubectl logs -l app.kubernetes.io/instance={{ .Release.Name }} -n {{ .Release.Namespace }} + +For more information, visit https://github.com/micromize-dev/sigward diff --git a/charts/sigward/templates/_helpers.tpl b/charts/sigward/templates/_helpers.tpl new file mode 100644 index 0000000..5049dc4 --- /dev/null +++ b/charts/sigward/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "sigward.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "sigward.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "sigward.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "sigward.labels" -}} +helm.sh/chart: {{ include "sigward.chart" . }} +{{ include "sigward.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "sigward.selectorLabels" -}} +app.kubernetes.io/name: {{ include "sigward.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "sigward.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "sigward.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/sigward/templates/clusterrole.yaml b/charts/sigward/templates/clusterrole.yaml new file mode 100644 index 0000000..a111b74 --- /dev/null +++ b/charts/sigward/templates/clusterrole.yaml @@ -0,0 +1,22 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "sigward.fullname" . }} + labels: + {{- include "sigward.labels" . | nindent 4 }} +rules: + - apiGroups: [""] + resources: ["nodes/proxy"] + verbs: ["get"] + - apiGroups: [""] + resources: ["namespaces", "nodes", "pods"] + verbs: ["get", "watch", "list"] + - apiGroups: [""] + resources: ["services"] + verbs: ["list", "watch"] + - apiGroups: ["*"] + resources: ["deployments", "replicasets", "statefulsets", "daemonsets", "jobs", "cronjobs", "replicationcontrollers"] + # Required to retrieve the owner references used by the seccomp gadget. + verbs: ["get", "list", "watch", "create"] +{{- end -}} \ No newline at end of file diff --git a/charts/sigward/templates/clusterrolebinding.yaml b/charts/sigward/templates/clusterrolebinding.yaml new file mode 100644 index 0000000..728579e --- /dev/null +++ b/charts/sigward/templates/clusterrolebinding.yaml @@ -0,0 +1,16 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "sigward.fullname" . }} + labels: + {{- include "sigward.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "sigward.fullname" . }} +subjects: + - kind: ServiceAccount + name: {{ include "sigward.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end -}} diff --git a/charts/sigward/templates/daemonset.yaml b/charts/sigward/templates/daemonset.yaml new file mode 100644 index 0000000..5fb3867 --- /dev/null +++ b/charts/sigward/templates/daemonset.yaml @@ -0,0 +1,145 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "sigward.fullname" . }} + labels: + {{- include "sigward.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "sigward.selectorLabels" . | nindent 6 }} + {{- with .Values.updateStrategy }} + updateStrategy: + {{- toYaml . | nindent 4 }} + {{- end }} + template: + metadata: + annotations: + # Required for accessing securityfs and BPF subsystem on systems with AppArmor + container.apparmor.security.beta.kubernetes.io/{{ .Chart.Name }}: "unconfined" + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "sigward.selectorLabels" . | nindent 8 }} + spec: + hostPID: true + {{- if .Values.priorityClassName }} + priorityClassName: {{ .Values.priorityClassName }} + {{- end }} + serviceAccountName: {{ include "sigward.serviceAccountName" . }} + containers: + - name: {{ .Chart.Name }} + securityContext: + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + add: + # Required for loading BPF programs. + - SYS_ADMIN + # Required for reading kernel logs. + - SYSLOG + # Required for ptrace-based gadgets. + - SYS_PTRACE + # Required for setting rlimits (e.g. memlock). + - SYS_RESOURCE + # Required for locking memory for BPF maps. + - IPC_LOCK + image: "{{ .Values.image.repository }}:{{ required "A valid .Values.image.tag is required!" .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + args: + - --enforce={{ .Values.enforce }} + {{- if .Values.filterNamespaces }} + - --filter-namespaces={{ .Values.filterNamespaces }} + {{- end }} + {{- if .Values.image.digest }} + - --filter-image-digest={{ .Values.image.digest }} + {{- end }} + {{- if .Values.exemptLabel }} + - --exempt-label={{ .Values.exemptLabel }} + {{- else }} + - --exempt-label= + {{- end }} + {{- with .Values.args }} + {{- toYaml . | nindent 12 }} + {{- end }} + env: + - name: LOG_LEVEL + value: {{ .Values.logLevel | quote }} + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- if .Values.registryAuth.existingSecret }} + - name: DOCKER_CONFIG + value: /etc/docker-registry + {{- end }} + volumeMounts: + # Required for pinning BPF maps. + - mountPath: /sys/fs/bpf + name: bpf + # Required for accessing debugfs (e.g. for kprobes). + - mountPath: /sys/kernel/debug + name: debugfs + # Required for validating BPF LSM is enabled. + - mountPath: /sys/kernel/security + name: security + readOnly: true + # Required for container level enrichment. + - mountPath: /host/bin + name: host-bin + # Required for accessing host process information. + - mountPath: /host/proc + name: host-proc + # Required for accessing container runtime sockets. + - mountPath: /host/run + name: host-run + # Required for container level enrichment. + - mountPath: /host/usr + name: host-usr + {{- if .Values.registryAuth.existingSecret }} + - mountPath: /etc/docker-registry + name: registry-auth + readOnly: true + {{- end }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + volumes: + - name: bpf + hostPath: + path: /sys/fs/bpf + - name: debugfs + hostPath: + path: /sys/kernel/debug + - name: security + hostPath: + path: /sys/kernel/security + - name: host-bin + hostPath: + path: /bin + - name: host-proc + hostPath: + path: /proc + - name: host-run + hostPath: + path: /run + - name: host-usr + hostPath: + path: /usr + {{- if .Values.registryAuth.existingSecret }} + - name: registry-auth + secret: + secretName: {{ .Values.registryAuth.existingSecret }} + items: + - key: .dockerconfigjson + path: config.json + {{- end }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/sigward/templates/serviceaccount.yaml b/charts/sigward/templates/serviceaccount.yaml new file mode 100644 index 0000000..411e203 --- /dev/null +++ b/charts/sigward/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "sigward.serviceAccountName" . }} + labels: + {{- include "sigward.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/sigward/values.schema.json b/charts/sigward/values.schema.json new file mode 100644 index 0000000..379f421 --- /dev/null +++ b/charts/sigward/values.schema.json @@ -0,0 +1,106 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "Values", + "type": "object", + "properties": { + "image": { + "type": "object", + "properties": { + "repository": { + "type": "string", + "description": "Image repository" + }, + "pullPolicy": { + "type": "string", + "enum": ["Always", "IfNotPresent", "Never"] + }, + "tag": { + "type": "string", + "description": "Image tag" + }, + "digest": { + "type": "string", + "description": "Image digest for self-exclusion filtering (e.g. sha256:abc123...)" + } + }, + "required": ["repository", "pullPolicy"] + }, + "logLevel": { + "type": "string", + "enum": ["debug", "info", "warn", "error"] + }, + "enforce": { + "type": "boolean", + "description": "Enable enforcement mode" + }, + "filterNamespaces": { + "type": "string", + "description": "Comma-separated list of Kubernetes namespaces to monitor (empty means all)" + }, + "args": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional arguments passed to the agent" + }, + "priorityClassName": { + "type": "string" + }, + "updateStrategy": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["RollingUpdate", "OnDelete"] + }, + "rollingUpdate": { + "type": "object" + } + } + }, + "resources": { + "type": "object", + "properties": { + "limits": { + "type": "object" + }, + "requests": { + "type": "object" + } + } + }, + "nodeSelector": { + "type": "object" + }, + "tolerations": { + "type": "array" + }, + "serviceAccount": { + "type": "object", + "properties": { + "create": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "annotations": { + "type": "object" + } + } + }, + "podAnnotations": { + "type": "object" + }, + "registryAuth": { + "type": "object", + "properties": { + "existingSecret": { + "type": "string", + "description": "Name of an existing Kubernetes secret of type kubernetes.io/dockerconfigjson for private registry authentication" + } + } + } + } +} diff --git a/charts/sigward/values.yaml b/charts/sigward/values.yaml new file mode 100644 index 0000000..fa8b66e --- /dev/null +++ b/charts/sigward/values.yaml @@ -0,0 +1,62 @@ +image: + repository: ghcr.io/micromize-dev/sigward + pullPolicy: IfNotPresent + # The image tag is required. + tag: "" + # Image digest for self-exclusion filtering. When set, sigward filters out + # containers running this digest from monitoring. Resolve with: + # crane digest ghcr.io/micromize-dev/sigward: + digest: "" + +logLevel: info + +enforce: true + +filterNamespaces: "" + +# Label key used to discover exempt namespaces from the Kubernetes API at +# startup. Any namespace with this label set to "true" will be excluded from +# monitoring. Set to empty string to disable this feature. +# NOTE: changes to namespace labels require a DaemonSet restart to take effect. +exemptLabel: "sigward.dev/exempt" + +args: [] + +# Priority class to ensure the pod is scheduled and not preempted +priorityClassName: "system-node-critical" + +updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 1 + +resources: + limits: + cpu: 50m + memory: 128Mi + requests: + cpu: 50m + memory: 128Mi + +nodeSelector: {} + +tolerations: + - effect: NoSchedule + operator: Exists + - effect: NoExecute + operator: Exists + +serviceAccount: + create: true + name: "sigward" + annotations: {} + +podAnnotations: {} + +# Registry authentication for SBOM fetching from private registries. +# Provide the name of an existing Kubernetes secret of type +# kubernetes.io/dockerconfigjson. The secret will be mounted and used +# to authenticate when pulling SBOMs from private registries. +registryAuth: + existingSecret: "" + From 08118143ee70fcbd0a38b3631d58f259b44b0f76 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:11:32 +0000 Subject: [PATCH 06/32] build: add sigward image and split release wiring Signed-off-by: Dor Serero --- .github/workflows/release.yml | 42 ++++++++++++++++- Dockerfile | 2 +- Dockerfile.sigward | 87 +++++++++++++++++++++++++++++++++++ Makefile | 11 +++-- 4 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 Dockerfile.sigward diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3ace802..e466048 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: strategy: matrix: - gadget: [fs-restrict, cap-restrict, ptrace-restrict] + gadget: [fs-restrict, cap-restrict, ptrace-restrict, socket-restrict, sigward] steps: - name: Checkout repository @@ -114,3 +114,43 @@ jobs: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.TAG_NAME }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest platforms: linux/amd64,linux/arm64 + + release-sigward: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set TAG_NAME + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "TAG_NAME=${{ inputs.tag_name }}" >> $GITHUB_ENV + else + echo "TAG_NAME=${{ github.event.release.tag_name }}" >> $GITHUB_ENV + fi + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v4 + + - name: Log in to the Container registry + uses: docker/login-action@v4 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push Sigward + uses: docker/build-push-action@v7 + with: + context: . + file: Dockerfile.sigward + push: true + tags: | + ${{ env.REGISTRY }}/${{ github.repository_owner }}/sigward:${{ env.TAG_NAME }} + ${{ env.REGISTRY }}/${{ github.repository_owner }}/sigward:latest + platforms: linux/amd64,linux/arm64 diff --git a/Dockerfile b/Dockerfile index d660adc..b38bf2c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,7 +15,7 @@ COPY gadgets gadgets # Build gadgets RUN mkdir -p build/gadgets && \ - for gadget in fs-restrict cap-restrict ptrace-restrict socket-restrict sigward; do \ + for gadget in fs-restrict cap-restrict ptrace-restrict socket-restrict; do \ echo "Building gadget: $gadget" && \ ig image build \ --local \ diff --git a/Dockerfile.sigward b/Dockerfile.sigward new file mode 100644 index 0000000..c7e375d --- /dev/null +++ b/Dockerfile.sigward @@ -0,0 +1,87 @@ +FROM ghcr.io/inspektor-gadget/gadget-builder:main AS gadget-builder + +ARG IG_VERSION=v0.47.0 +ARG IMAGE_TAG=dev +ARG TARGETOS +ARG TARGETARCH + +# Install ig +RUN wget -qO- https://github.com/inspektor-gadget/inspektor-gadget/releases/download/${IG_VERSION}/ig-${TARGETOS}-${TARGETARCH}-${IG_VERSION}.tar.gz \ + | tar -xz -C /usr/local/bin ig + +WORKDIR /app +COPY include/micromize /usr/include/micromize +COPY gadgets gadgets + +# Build the sigward attestation gadget +RUN mkdir -p build/gadgets && \ + for gadget in sigward; do \ + echo "Building gadget: $gadget" && \ + ig image build \ + --local \ + -t ghcr.io/micromize-dev/micromize/${gadget}:${IMAGE_TAG} \ + gadgets/${gadget} && \ + ig image export \ + ghcr.io/micromize-dev/micromize/${gadget}:${IMAGE_TAG} \ + build/gadgets/${gadget}.tar; \ + done + +FROM --platform=$BUILDPLATFORM golang:1.26.2-alpine AS builder + +ARG IG_VERSION=v0.47.0 +ARG IMAGE_TAG=dev +ARG TARGETOS +ARG TARGETARCH + +WORKDIR /app + +# Cache dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Copy source code +COPY . . + +# Copy the built gadget where embeds.go expects it (cmd/sigward/build/) +RUN mkdir -p cmd/sigward/build +COPY --from=gadget-builder /app/build/gadgets/sigward.tar cmd/sigward/build/ + +# Build the static binary +RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build \ + -tags release \ + -ldflags "-X github.com/inspektor-gadget/inspektor-gadget/internal/version.version=${IG_VERSION} -X main.Version=${IMAGE_TAG} -w -s -extldflags '-static'" \ + -o /sigward \ + ./cmd/sigward + +# Build the image +FROM scratch +COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt +COPY --from=builder /sigward /sigward + +# Access to kernel debug filesystem (tracefs) +VOLUME ["/sys/kernel/debug"] + +# Access to kernel security configuration (LSM) +VOLUME ["/sys/kernel/security"] + +# Access to BPF filesystem for map pinning +VOLUME ["/sys/fs/bpf"] + +# Access to cgroup hierarchy +VOLUME ["/sys/fs/cgroup"] + +# Access to host process information +VOLUME ["/host/proc"] + +# Access to host system information +VOLUME ["/host/sys"] + +# Access to host binaries and libraries +VOLUME ["/host/bin"] +VOLUME ["/host/usr"] + +# Access to host runtime files (sockets, etc.) +VOLUME ["/host/run"] + +ENV HOST_ROOT=/host +ENTRYPOINT ["/sigward"] diff --git a/Makefile b/Makefile index fe94761..5700ade 100644 --- a/Makefile +++ b/Makefile @@ -74,12 +74,17 @@ $(GOARCHS): # Copy source to build/src cp -r cmd internal go.mod go.sum build/src/ - # Copy gadgets to where main.go expects them + # micromize embeds the boundary gadgets mkdir -p build/src/cmd/micromize/build - cp build/gadgets/*.tar build/src/cmd/micromize/build/ + cp build/gadgets/fs-restrict.tar build/gadgets/cap-restrict.tar build/gadgets/ptrace-restrict.tar build/gadgets/socket-restrict.tar build/src/cmd/micromize/build/ - # Build + # sigward embeds its attestation gadget + mkdir -p build/src/cmd/sigward/build + cp build/gadgets/sigward.tar build/src/cmd/sigward/build/ + + # Build both product binaries cd build/src && GOOS=linux GOARCH=$@ CGO_ENABLED=0 go build -tags release -ldflags "$(LDFLAGS)" -o ../../$(OUTPUT_DIR)/micromize-linux-$@ ./cmd/micromize + cd build/src && GOOS=linux GOARCH=$@ CGO_ENABLED=0 go build -tags release -ldflags "$(LDFLAGS)" -o ../../$(OUTPUT_DIR)/sigward-linux-$@ ./cmd/sigward .PHONY: run-fs-restrict run-fs-restrict: From 542b3ce1ac7bbed8f8f0bfba4495bcabe72b1732 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:12:34 +0000 Subject: [PATCH 07/32] refactor: remove sbom registry-auth from micromize chart Signed-off-by: Dor Serero --- charts/micromize/templates/daemonset.yaml | 17 ----------------- charts/micromize/values.schema.json | 9 --------- charts/micromize/values.yaml | 7 ------- 3 files changed, 33 deletions(-) diff --git a/charts/micromize/templates/daemonset.yaml b/charts/micromize/templates/daemonset.yaml index ac42a6f..0058f48 100644 --- a/charts/micromize/templates/daemonset.yaml +++ b/charts/micromize/templates/daemonset.yaml @@ -71,10 +71,6 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - {{- if .Values.registryAuth.existingSecret }} - - name: DOCKER_CONFIG - value: /etc/docker-registry - {{- end }} volumeMounts: # Required for pinning BPF maps. - mountPath: /sys/fs/bpf @@ -98,11 +94,6 @@ spec: # Required for container level enrichment. - mountPath: /host/usr name: host-usr - {{- if .Values.registryAuth.existingSecret }} - - mountPath: /etc/docker-registry - name: registry-auth - readOnly: true - {{- end }} resources: {{- toYaml .Values.resources | nindent 12 }} volumes: @@ -127,14 +118,6 @@ spec: - name: host-usr hostPath: path: /usr - {{- if .Values.registryAuth.existingSecret }} - - name: registry-auth - secret: - secretName: {{ .Values.registryAuth.existingSecret }} - items: - - key: .dockerconfigjson - path: config.json - {{- end }} {{- with .Values.nodeSelector }} nodeSelector: {{- toYaml . | nindent 8 }} diff --git a/charts/micromize/values.schema.json b/charts/micromize/values.schema.json index 379f421..a11a6d1 100644 --- a/charts/micromize/values.schema.json +++ b/charts/micromize/values.schema.json @@ -92,15 +92,6 @@ }, "podAnnotations": { "type": "object" - }, - "registryAuth": { - "type": "object", - "properties": { - "existingSecret": { - "type": "string", - "description": "Name of an existing Kubernetes secret of type kubernetes.io/dockerconfigjson for private registry authentication" - } - } } } } diff --git a/charts/micromize/values.yaml b/charts/micromize/values.yaml index 1061142..67c6823 100644 --- a/charts/micromize/values.yaml +++ b/charts/micromize/values.yaml @@ -53,10 +53,3 @@ serviceAccount: podAnnotations: {} -# Registry authentication for SBOM fetching from private registries. -# Provide the name of an existing Kubernetes secret of type -# kubernetes.io/dockerconfigjson. The secret will be mounted and used -# to authenticate when pulling SBOMs from private registries. -registryAuth: - existingSecret: "" - From d653d44775bf30a2fa3163a0d20549ab23a64ad8 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:13:35 +0000 Subject: [PATCH 08/32] docs: document micromize and sigward products Signed-off-by: Dor Serero --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fe2a537..ec1690b 100644 --- a/README.md +++ b/README.md @@ -17,12 +17,14 @@ Tools may detect this. Few eliminate it. ## Philosophy -Micromize doesn't care what happens inside the container. Instead, it enforces the boundaries. We don't scan for cryptominers because with Micromize, unauthorized binaries can't execute in the first place. You can't effectively protect against every poorly written application, but you can guarantee that nothing runs unless it was part of the original image. +Micromize doesn't care what happens inside the container. Instead, it enforces the boundaries. You can't effectively protect against every poorly written application, but you can guarantee a container stays within the limits of what a container is meant to be. Micromize assumes containers are immutable, disposable, non-host-mutating, and explicit about privilege. If your workload violates those assumptions, Micromize blocks it or forces an explicit posture decision. +> Want to go further and guarantee that only the exact, cryptographically signed binaries from your image can execute? See **[Sigward](#sigward)**, the execution-attestation product that ships from this repository. + ## What Micromize Does Today, Micromize attaches eBPF programs to LSM hooks and enforces: @@ -31,10 +33,18 @@ Today, Micromize attaches eBPF programs to LSM hooks and enforces: - **Capability restriction** — prevents privilege escalation via `unshare`/`clone`/`setns` - **Ptrace blocking** — eliminates ptrace-based debugging/injection attacks - **Socket restriction** — blocks `AF_ALG` (kernel crypto userspace API) socket usage in containers, mitigating CVE-2026-31431 and related attack surface -- **Execution integrity** — SBOM + runtime hash validation via `bpf_ima_file_hash` Policies are loaded before container start and enforced at execution time. No runtime replacement. No learning mode. Kernel-native enforcement. +## Sigward + +This repository is a monorepo that ships **two** products from a shared codebase: + +- **Micromize** (`cmd/micromize`) — the boundary-enforcement agent described above. +- **[Sigward](gadgets/sigward)** (`cmd/sigward`) — execution attestation. Sigward verifies, in the kernel (BPF-LSM + IMA), that every binary and shared object a container runs matches a cryptographically signed SPDX SBOM attached to its image. Anything unattested or tampered with is blocked before it executes. + +They are separate deployables — separate binaries, images, and Helm charts (`charts/sigward`) — so Sigward's registry access, credentials, and `CONFIG_IMA` requirement never get forced onto a plain Micromize deployment. Deploy either or both; they compose at the LSM layer. + ## Quickstart ### Docker @@ -82,7 +92,6 @@ helm install micromize ./charts/micromize \ - Linux kernel 5.18+ - BPF LSM enabled (`CONFIG_BPF_LSM=y`, boot with `lsm=...,bpf`) -- IMA enabled (`CONFIG_IMA=y`) — required for execution integrity via `bpf_ima_file_hash` ## Development From f002ba4caa8978102b0c7d9d57bb5267838eb272 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:23:44 +0000 Subject: [PATCH 09/32] ci: build the sigward image in CI Signed-off-by: Dor Serero --- .github/workflows/build.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b1fd0f6..e97dd0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,5 +75,8 @@ jobs: - name: Test run: go test ./... - - name: Build Docker image + - name: Build Micromize image run: docker build . + + - name: Build Sigward image + run: docker build -f Dockerfile.sigward . From 8c7ab00f5ad70d9bd8e8b9e95bd2bc212d1b2aaa Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:47:10 +0000 Subject: [PATCH 10/32] fix: correct sbom path normalization and length check Signed-off-by: Dor Serero --- internal/attest/ima.go | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/internal/attest/ima.go b/internal/attest/ima.go index f2dd110..e1a0de5 100644 --- a/internal/attest/ima.go +++ b/internal/attest/ima.go @@ -177,18 +177,24 @@ func populateExpectedHashes(gadgetCtx igoperators.GadgetContext, innerMaps *sync for _, f := range files { var key [maxFilepathLen]byte - if len(f.FileName) > maxFilepathLen { - slog.Error("SBOM file path exceeds maximum length", "file", f.FileName, "length", len(f.FileName)) - continue - } // Normalize SBOM filename to match kernel dentry path format. // SPDX filenames use "./" prefix (e.g. "./hello"), while the kernel // returns absolute paths from the mount root (e.g. "/hello"). name := f.FileName - name = strings.TrimPrefix(name, ".") + name = strings.TrimPrefix(name, "./") if !strings.HasPrefix(name, "/") { name = "/" + name } + + // Enforce the length limit AFTER normalization and leave room for the + // NUL terminator. The BPF side fills the key via bpf_probe_read_kernel_str + // (at most maxFilepathLen-1 chars + NUL), so a name of maxFilepathLen or + // more would be copied without a terminator here and never match the + // kernel key, silently causing "unattested" misses. + if len(name) >= maxFilepathLen { + slog.Error("SBOM file path exceeds maximum length", "file", f.FileName, "length", len(name)) + continue + } copy(key[:], name) var value [sha256HashSize]byte From 26e80b9ebb861459e8c26b627b5c52c85768b558 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:47:16 +0000 Subject: [PATCH 11/32] fix(helm): point sigward chart notes at the monorepo Signed-off-by: Dor Serero --- charts/sigward/templates/NOTES.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/charts/sigward/templates/NOTES.txt b/charts/sigward/templates/NOTES.txt index 2520e64..f9775f5 100644 --- a/charts/sigward/templates/NOTES.txt +++ b/charts/sigward/templates/NOTES.txt @@ -8,4 +8,4 @@ To check logs: kubectl logs -l app.kubernetes.io/instance={{ .Release.Name }} -n {{ .Release.Namespace }} -For more information, visit https://github.com/micromize-dev/sigward +For more information, visit https://github.com/micromize-dev/micromize From 9a8f4a91ad01186be739aec0a9b8d684484ee835 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:47:16 +0000 Subject: [PATCH 12/32] refactor: share namespace filter helper across commands Signed-off-by: Dor Serero --- cmd/micromize/root.go | 24 +-------------- cmd/micromize/root_test.go | 48 ----------------------------- cmd/sigward/root.go | 27 +--------------- cmd/sigward/root_test.go | 60 ------------------------------------ internal/utils/utils.go | 25 +++++++++++++++ internal/utils/utils_test.go | 27 ++++++++++++++++ 6 files changed, 54 insertions(+), 157 deletions(-) delete mode 100644 cmd/sigward/root_test.go diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index b712644..77b6e4e 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -132,7 +132,7 @@ func run(ctx context.Context) error { return fmt.Errorf("getting host pid namespace ID: %w", err) } - nsFilter := buildNamespaceFilter(filterNamespaces) + nsFilter := utils.BuildNamespaceFilter(filterNamespaces, "micromize") // Discover namespaces exempt by label and append them as exclusions. // Evaluated at startup only — a DaemonSet restart is required to pick up @@ -235,25 +235,3 @@ func buildDisabledSet(disableGadgets string) map[string]bool { } return disabled } - -// buildNamespaceFilter constructs the k8s-namespace filter value. -// It always excludes the "micromize" namespace and appends any user-specified -// namespace filters. When filterNamespaces is empty, only "!micromize" is used. -func buildNamespaceFilter(filterNamespaces string) string { - const excludeMicromize = "!micromize" - normalizedFilter := excludeMicromize - - if filterNamespaces == "" { - return normalizedFilter - } - - parts := strings.Split(filterNamespaces, ",") - for _, p := range parts { - nsPart := strings.TrimSpace(p) - if nsPart != excludeMicromize { - normalizedFilter += "," + nsPart - } - } - - return normalizedFilter -} diff --git a/cmd/micromize/root_test.go b/cmd/micromize/root_test.go index c549d01..6a2b9c5 100644 --- a/cmd/micromize/root_test.go +++ b/cmd/micromize/root_test.go @@ -64,51 +64,3 @@ func TestBuildDisabledSet(t *testing.T) { }) } } - -func TestBuildNamespaceFilter(t *testing.T) { - tests := []struct { - name string - filterNamespaces string - want string - }{ - { - name: "empty filter returns only micromize exclusion", - filterNamespaces: "", - want: "!micromize", - }, - { - name: "single namespace appends micromize exclusion", - filterNamespaces: "default", - want: "!micromize,default", - }, - { - name: "multiple namespaces append micromize exclusion", - filterNamespaces: "default,kube-system", - want: "!micromize,default,kube-system", - }, - { - name: "user already excludes micromize", - filterNamespaces: "default,!micromize", - want: "!micromize,default", - }, - { - name: "only micromize exclusion", - filterNamespaces: "!micromize", - want: "!micromize", - }, - { - name: "exclusion filter appends micromize exclusion", - filterNamespaces: "!kube-system", - want: "!micromize,!kube-system", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := buildNamespaceFilter(tt.filterNamespaces) - if got != tt.want { - t.Errorf("buildNamespaceFilter(%q) = %q, want %q", tt.filterNamespaces, got, tt.want) - } - }) - } -} diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go index f7c84d2..9c748a3 100644 --- a/cmd/sigward/root.go +++ b/cmd/sigward/root.go @@ -122,7 +122,7 @@ func run(ctx context.Context) error { // Create gadget registry registry := gadget.NewRegistry(contextManager, runtimeManager) - nsFilter := buildNamespaceFilter(filterNamespaces) + nsFilter := utils.BuildNamespaceFilter(filterNamespaces, "sigward") // Discover namespaces exempt by label and append them as exclusions. // Evaluated at startup only — a DaemonSet restart is required to pick up @@ -172,28 +172,3 @@ func run(ctx context.Context) error { <-ctx.Done() return nil } - -// buildNamespaceFilter constructs the k8s-namespace filter value. -// It always excludes the "sigward" namespace and appends any user-specified -// namespace filters. When filterNamespaces is empty, only "!sigward" is used. -func buildNamespaceFilter(filterNamespaces string) string { - const excludeSigward = "!sigward" - normalizedFilter := excludeSigward - - if filterNamespaces == "" { - return normalizedFilter - } - - parts := strings.Split(filterNamespaces, ",") - for _, p := range parts { - nsPart := strings.TrimSpace(p) - if nsPart == "" { - continue - } - if nsPart != excludeSigward { - normalizedFilter += "," + nsPart - } - } - - return normalizedFilter -} diff --git a/cmd/sigward/root_test.go b/cmd/sigward/root_test.go deleted file mode 100644 index e263a4b..0000000 --- a/cmd/sigward/root_test.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright The micromize authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package main - -import "testing" - -func TestBuildNamespaceFilter(t *testing.T) { - tests := []struct { - name string - filterNamespaces string - want string - }{ - { - name: "empty filter returns only sigward exclusion", - filterNamespaces: "", - want: "!sigward", - }, - { - name: "single namespace appends sigward exclusion", - filterNamespaces: "default", - want: "!sigward,default", - }, - { - name: "multiple namespaces append sigward exclusion", - filterNamespaces: "default,kube-system", - want: "!sigward,default,kube-system", - }, - { - name: "user already excludes sigward", - filterNamespaces: "default,!sigward", - want: "!sigward,default", - }, - { - name: "empty segments are skipped", - filterNamespaces: "default,,kube-system,", - want: "!sigward,default,kube-system", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := buildNamespaceFilter(tt.filterNamespaces) - if got != tt.want { - t.Errorf("buildNamespaceFilter(%q) = %q, want %q", tt.filterNamespaces, got, tt.want) - } - }) - } -} diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 71127be..649af90 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -45,6 +45,31 @@ func BoolToInt(b bool) int { return 0 } +// BuildNamespaceFilter constructs the LocalManager k8s-namespace filter value. +// It always excludes the agent's own namespace (selfNamespace) and appends any +// user-specified namespace filters, skipping empty segments. When +// filterNamespaces is empty, only the self-exclusion is returned. +func BuildNamespaceFilter(filterNamespaces, selfNamespace string) string { + exclude := "!" + selfNamespace + normalizedFilter := exclude + + if filterNamespaces == "" { + return normalizedFilter + } + + for _, p := range strings.Split(filterNamespaces, ",") { + nsPart := strings.TrimSpace(p) + if nsPart == "" { + continue + } + if nsPart != exclude { + normalizedFilter += "," + nsPart + } + } + + return normalizedFilter +} + func GetHostPidNamespaceID() (uint64, error) { var stat syscall.Stat_t if err := syscall.Stat("/proc/1/ns/pid", &stat); err != nil { diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index f6adc0c..9f543e8 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -102,3 +102,30 @@ func TestValidateBPFLSM_FileNotFound(t *testing.T) { t.Errorf("Expected error when file doesn't exist, but got nil") } } + +func TestBuildNamespaceFilter(t *testing.T) { + tests := []struct { + name string + filterNamespaces string + selfNamespace string + want string + }{ + {"empty returns only self exclusion", "", "micromize", "!micromize"}, + {"single namespace", "default", "micromize", "!micromize,default"}, + {"multiple namespaces", "default,kube-system", "sigward", "!sigward,default,kube-system"}, + {"user already excludes self", "default,!sigward", "sigward", "!sigward,default"}, + {"only self exclusion", "!micromize", "micromize", "!micromize"}, + {"exclusion filter", "!kube-system", "sigward", "!sigward,!kube-system"}, + {"empty segments skipped", "default,,kube-system,", "sigward", "!sigward,default,kube-system"}, + {"whitespace trimmed", " default , kube-system ", "micromize", "!micromize,default,kube-system"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := BuildNamespaceFilter(tt.filterNamespaces, tt.selfNamespace) + if got != tt.want { + t.Errorf("BuildNamespaceFilter(%q, %q) = %q, want %q", tt.filterNamespaces, tt.selfNamespace, got, tt.want) + } + }) + } +} From 3f436af14baa04a443c463f4b4163a62f31ab5f0 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:51:45 +0000 Subject: [PATCH 13/32] refactor: clarify sbom path safety helper naming Signed-off-by: Dor Serero --- internal/sbom/sbom.go | 15 +++++++-------- internal/sbom/sbom_test.go | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/internal/sbom/sbom.go b/internal/sbom/sbom.go index e5421ac..a1464ab 100644 --- a/internal/sbom/sbom.go +++ b/internal/sbom/sbom.go @@ -234,8 +234,8 @@ func ParseFiles(sbomData []byte) ([]FileInfo, error) { if !isBinary(f.FileTypes) && !isScript(f.FileName) { continue } - if !isAbsolutePath(f.FileName) { - slog.Warn("Skipping SBOM file with relative path", "file", f.FileName) + if !isSafeSBOMPath(f.FileName) { + slog.Warn("Skipping SBOM file with unsafe path (empty or contains '..')", "file", f.FileName) continue } for _, c := range f.Checksums { @@ -251,16 +251,15 @@ func ParseFiles(sbomData []byte) ([]FileInfo, error) { return files, nil } -// isAbsolutePath checks that the SBOM filename is a valid absolute path -// (optionally with "./" SPDX prefix) and does not contain ".." traversal -// components. -func isAbsolutePath(name string) bool { +// isSafeSBOMPath reports whether the SBOM filename is safe to use as a lookup +// key: it must be non-empty and must not contain any ".." parent-directory +// traversal components. It does not require the path to be absolute (SPDX +// filenames may be relative or "./"-prefixed; callers normalize them later). +func isSafeSBOMPath(name string) bool { if name == "" { return false } - // Reject any remaining ".." components (Clean resolves most, but - // e.g. "/../foo" → "/foo" is fine—check the original intent). for _, part := range strings.Split(name, "/") { if part == ".." { return false diff --git a/internal/sbom/sbom_test.go b/internal/sbom/sbom_test.go index 905beb5..e9cf446 100644 --- a/internal/sbom/sbom_test.go +++ b/internal/sbom/sbom_test.go @@ -243,7 +243,7 @@ func TestExtractSPDXFromDSSE(t *testing.T) { } } -func TestParseFiles_RejectsRelativePaths(t *testing.T) { +func TestParseFiles_RejectsPathTraversal(t *testing.T) { makeSBOM := func(files []map[string]any) []byte { doc := map[string]any{"files": files} b, _ := json.Marshal(doc) From 89c253df6d47a63ac517f1651093b8591a042a6c Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:51:45 +0000 Subject: [PATCH 14/32] build: align conform version with ci Signed-off-by: Dor Serero --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 5700ade..7474ca1 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ LDFLAGS := -X github.com/inspektor-gadget/inspektor-gadget/internal/version.vers -X main.Version=$(IMAGE_TAG) \ -w -s -extldflags "-static" GADGETS := fs-restrict cap-restrict ptrace-restrict socket-restrict sigward -CONFORM_VERSION ?= v0.1.0-alpha.30 +CONFORM_VERSION ?= v0.1.0-alpha.31 # This version number must be kept in sync with CI workflow lint one. LINTER_IMAGE ?= golangci/golangci-lint:v2.10.1 From 6d09606547e0dc7ff498ee8162d3fb3db8b8fb1b Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 10:51:45 +0000 Subject: [PATCH 15/32] refactor(helm): narrow owner-reference enrichment rbac Signed-off-by: Dor Serero --- charts/micromize/templates/clusterrole.yaml | 6 +++--- charts/sigward/templates/clusterrole.yaml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/charts/micromize/templates/clusterrole.yaml b/charts/micromize/templates/clusterrole.yaml index e452567..4eb928d 100644 --- a/charts/micromize/templates/clusterrole.yaml +++ b/charts/micromize/templates/clusterrole.yaml @@ -15,8 +15,8 @@ rules: - apiGroups: [""] resources: ["services"] verbs: ["list", "watch"] - - apiGroups: ["*"] + - apiGroups: ["", "apps", "batch"] resources: ["deployments", "replicasets", "statefulsets", "daemonsets", "jobs", "cronjobs", "replicationcontrollers"] - # Required to retrieve the owner references used by the seccomp gadget. - verbs: ["get", "list", "watch", "create"] + # Required to resolve pod owner references for Kubernetes enrichment. + verbs: ["get", "list", "watch"] {{- end -}} \ No newline at end of file diff --git a/charts/sigward/templates/clusterrole.yaml b/charts/sigward/templates/clusterrole.yaml index a111b74..a9cdd8e 100644 --- a/charts/sigward/templates/clusterrole.yaml +++ b/charts/sigward/templates/clusterrole.yaml @@ -15,8 +15,8 @@ rules: - apiGroups: [""] resources: ["services"] verbs: ["list", "watch"] - - apiGroups: ["*"] + - apiGroups: ["", "apps", "batch"] resources: ["deployments", "replicasets", "statefulsets", "daemonsets", "jobs", "cronjobs", "replicationcontrollers"] - # Required to retrieve the owner references used by the seccomp gadget. - verbs: ["get", "list", "watch", "create"] + # Required to resolve pod owner references for Kubernetes enrichment. + verbs: ["get", "list", "watch"] {{- end -}} \ No newline at end of file From 2093c5623b02297d30af01d54cf650ab9bae3998 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 11:51:59 +0000 Subject: [PATCH 16/32] build: align ig and go toolchain versions with go.mod Signed-off-by: Dor Serero --- .github/workflows/release.yml | 2 +- Dockerfile | 6 +++--- Dockerfile.sigward | 6 +++--- Makefile | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e466048..59c4fbe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ on: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} - IG_VERSION: v0.47.0 + IG_VERSION: v0.51.1 jobs: release-gadgets: diff --git a/Dockerfile b/Dockerfile index b38bf2c..a8af82f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM ghcr.io/inspektor-gadget/gadget-builder:main AS gadget-builder -ARG IG_VERSION=v0.47.0 +ARG IG_VERSION=v0.51.1 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH @@ -26,9 +26,9 @@ RUN mkdir -p build/gadgets && \ build/gadgets/${gadget}.tar; \ done -FROM --platform=$BUILDPLATFORM golang:1.26.2-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.25.7-alpine AS builder -ARG IG_VERSION=v0.47.0 +ARG IG_VERSION=v0.51.1 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH diff --git a/Dockerfile.sigward b/Dockerfile.sigward index c7e375d..bca4162 100644 --- a/Dockerfile.sigward +++ b/Dockerfile.sigward @@ -1,6 +1,6 @@ FROM ghcr.io/inspektor-gadget/gadget-builder:main AS gadget-builder -ARG IG_VERSION=v0.47.0 +ARG IG_VERSION=v0.51.1 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH @@ -26,9 +26,9 @@ RUN mkdir -p build/gadgets && \ build/gadgets/${gadget}.tar; \ done -FROM --platform=$BUILDPLATFORM golang:1.26.2-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.25.7-alpine AS builder -ARG IG_VERSION=v0.47.0 +ARG IG_VERSION=v0.51.1 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH diff --git a/Makefile b/Makefile index 7474ca1..88af9c7 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ IMAGE_TAG ?= $(TAG) CLANG_FORMAT ?= clang-format OUTPUT_DIR := dist GOARCHS := amd64 arm64 -LDFLAGS := -X github.com/inspektor-gadget/inspektor-gadget/internal/version.version=v0.47.0 \ +LDFLAGS := -X github.com/inspektor-gadget/inspektor-gadget/internal/version.version=v0.51.1 \ -X main.Version=$(IMAGE_TAG) \ -w -s -extldflags "-static" GADGETS := fs-restrict cap-restrict ptrace-restrict socket-restrict sigward @@ -155,8 +155,8 @@ dev-logs: ## Tail logs from all dev pods dev-status: ## Show dev pod status kubectl get pods -n $(DEV_NAMESPACE) -l app.kubernetes.io/name=micromize -o wide -IG_VERSION ?= v0.49.1 -IG_ARCHIVE_SHA256 ?= 1cc186b4ebe476da9c89b6ff2f38234b13d4eae3d2a3b597b3647393c2a223c0 +IG_VERSION ?= v0.51.1 +IG_ARCHIVE_SHA256 ?= 3d8c47380607849f4a924246a9cf901d6c5205665fddabcfc6c7e9f706b8b754 SKIP_CHECKSUM ?= 0 .PHONY: update-includes update-includes: From 1c0d6bb0dbdd63741d7e8a007e0328648ce65262 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 13:34:23 +0000 Subject: [PATCH 17/32] build: bump inspektor-gadget to v0.53.2 Signed-off-by: Dor Serero --- .github/workflows/release.yml | 2 +- Dockerfile | 4 +- Dockerfile.sigward | 4 +- Makefile | 6 +- go.mod | 48 ++++++------ go.sum | 134 +++++++++++++++++++++------------- 6 files changed, 114 insertions(+), 84 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 59c4fbe..6d9a1e8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,7 +12,7 @@ on: env: REGISTRY: ghcr.io IMAGE_NAME: ${{ github.repository }} - IG_VERSION: v0.51.1 + IG_VERSION: v0.53.2 jobs: release-gadgets: diff --git a/Dockerfile b/Dockerfile index a8af82f..565a4ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM ghcr.io/inspektor-gadget/gadget-builder:main AS gadget-builder -ARG IG_VERSION=v0.51.1 +ARG IG_VERSION=v0.53.2 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH @@ -28,7 +28,7 @@ RUN mkdir -p build/gadgets && \ FROM --platform=$BUILDPLATFORM golang:1.25.7-alpine AS builder -ARG IG_VERSION=v0.51.1 +ARG IG_VERSION=v0.53.2 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH diff --git a/Dockerfile.sigward b/Dockerfile.sigward index bca4162..aa27d6b 100644 --- a/Dockerfile.sigward +++ b/Dockerfile.sigward @@ -1,6 +1,6 @@ FROM ghcr.io/inspektor-gadget/gadget-builder:main AS gadget-builder -ARG IG_VERSION=v0.51.1 +ARG IG_VERSION=v0.53.2 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH @@ -28,7 +28,7 @@ RUN mkdir -p build/gadgets && \ FROM --platform=$BUILDPLATFORM golang:1.25.7-alpine AS builder -ARG IG_VERSION=v0.51.1 +ARG IG_VERSION=v0.53.2 ARG IMAGE_TAG=dev ARG TARGETOS ARG TARGETARCH diff --git a/Makefile b/Makefile index 88af9c7..5cda317 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ IMAGE_TAG ?= $(TAG) CLANG_FORMAT ?= clang-format OUTPUT_DIR := dist GOARCHS := amd64 arm64 -LDFLAGS := -X github.com/inspektor-gadget/inspektor-gadget/internal/version.version=v0.51.1 \ +LDFLAGS := -X github.com/inspektor-gadget/inspektor-gadget/internal/version.version=v0.53.2 \ -X main.Version=$(IMAGE_TAG) \ -w -s -extldflags "-static" GADGETS := fs-restrict cap-restrict ptrace-restrict socket-restrict sigward @@ -155,8 +155,8 @@ dev-logs: ## Tail logs from all dev pods dev-status: ## Show dev pod status kubectl get pods -n $(DEV_NAMESPACE) -l app.kubernetes.io/name=micromize -o wide -IG_VERSION ?= v0.51.1 -IG_ARCHIVE_SHA256 ?= 3d8c47380607849f4a924246a9cf901d6c5205665fddabcfc6c7e9f706b8b754 +IG_VERSION ?= v0.53.2 +IG_ARCHIVE_SHA256 ?= 4eb164b04d2fbb2fc28b763a4aff9a81a4830f9e60c7c91c9e1206419ed7cf46 SKIP_CHECKSUM ?= 0 .PHONY: update-includes update-includes: diff --git a/go.mod b/go.mod index b1b5ff0..01f59d3 100644 --- a/go.mod +++ b/go.mod @@ -6,15 +6,15 @@ require ( github.com/cilium/ebpf v0.21.0 github.com/cyphar/filepath-securejoin v0.6.1 github.com/docker/cli v29.6.0+incompatible - github.com/inspektor-gadget/inspektor-gadget v0.51.1 + github.com/inspektor-gadget/inspektor-gadget v0.53.2 github.com/opencontainers/image-spec v1.1.1 github.com/quay/claircore v1.5.52 github.com/sirupsen/logrus v1.9.4 github.com/spf13/cobra v1.10.2 golang.org/x/sync v0.21.0 - k8s.io/api v0.35.3 - k8s.io/apimachinery v0.35.3 - k8s.io/client-go v0.35.3 + k8s.io/api v0.35.4 + k8s.io/apimachinery v0.35.4 + k8s.io/client-go v0.35.4 oras.land/oras-go/v2 v2.6.1 ) @@ -23,7 +23,7 @@ require ( github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 // indirect github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect - github.com/Azure/go-ntlmssp v0.1.0 // indirect + github.com/Azure/go-ntlmssp v0.1.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/Microsoft/hcsshim v0.13.0 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -32,7 +32,7 @@ require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudflare/cbpfc v0.0.0-20240920015331-ff978e94500b // indirect github.com/containerd/cgroups/v3 v3.0.5 // indirect - github.com/containerd/containerd v1.7.30 // indirect + github.com/containerd/containerd v1.7.32 // indirect github.com/containerd/containerd/api v1.8.0 // indirect github.com/containerd/continuity v0.4.4 // indirect github.com/containerd/errdefs v1.0.0 // indirect @@ -46,7 +46,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/docker-credential-helpers v0.9.3 // indirect - github.com/docker/go-connections v0.6.0 // indirect + github.com/docker/go-connections v0.7.0 // indirect github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect github.com/docker/go-units v0.5.0 // indirect github.com/emicklei/go-restful/v3 v3.12.2 // indirect @@ -62,7 +62,7 @@ require ( github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.1 // indirect - github.com/go-viper/mapstructure/v2 v2.4.0 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/godbus/dbus/v5 v5.2.2 // indirect github.com/gofrs/flock v0.13.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect @@ -75,7 +75,7 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/gopacket/gopacket v1.5.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect - github.com/in-toto/attestation v1.1.2 // indirect + github.com/in-toto/attestation v1.2.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/josharian/native v1.1.0 // indirect @@ -87,8 +87,8 @@ require ( github.com/mdlayher/socket v0.5.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/locker v1.0.1 // indirect - github.com/moby/moby/api v1.54.0 // indirect - github.com/moby/moby/client v0.3.0 // indirect + github.com/moby/moby/api v1.54.2 // indirect + github.com/moby/moby/client v0.4.1 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect github.com/moby/sys/sequential v0.6.0 // indirect github.com/moby/sys/signal v0.7.0 // indirect @@ -118,7 +118,7 @@ require ( github.com/s3rj1k/go-fanotify/fanotify v0.0.0-20210917134616-9c00a300bb7a // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/secure-systems-lab/go-securesystemslib v0.10.0 // indirect - github.com/sigstore/protobuf-specs v0.5.0 // indirect + github.com/sigstore/protobuf-specs v0.5.1 // indirect github.com/sigstore/sigstore v1.10.4 // indirect github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect github.com/spf13/afero v1.15.0 // indirect @@ -139,30 +139,30 @@ require ( go.opentelemetry.io/otel/trace v1.43.0 // indirect go.yaml.in/yaml/v2 v2.4.3 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.49.0 // indirect - golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect - golang.org/x/mod v0.34.0 // indirect - golang.org/x/net v0.52.0 // indirect + golang.org/x/crypto v0.51.0 // indirect + golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect + golang.org/x/mod v0.35.0 // indirect + golang.org/x/net v0.55.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/term v0.41.0 // indirect - golang.org/x/text v0.35.0 // indirect + golang.org/x/sys v0.45.0 // indirect + golang.org/x/term v0.43.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.15.0 // indirect google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect - google.golang.org/grpc v1.79.3 // indirect + google.golang.org/grpc v1.80.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/cli-runtime v0.35.3 // indirect - k8s.io/component-base v0.35.3 // indirect - k8s.io/cri-api v0.35.3 // indirect + k8s.io/cli-runtime v0.35.4 // indirect + k8s.io/component-base v0.35.4 // indirect + k8s.io/cri-api v0.35.4 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/kubelet v0.35.3 // indirect + k8s.io/kubelet v0.35.4 // indirect k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect diff --git a/go.sum b/go.sum index 9cdc019..ebe8111 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,8 @@ github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0 h1:59M github.com/AdamKorcz/go-118-fuzz-build v0.0.0-20230306123547-8075edf89bb0/go.mod h1:OahwfttHWG6eJ0clwcfBAHoDI6X/LV/15hx/wlMZSrU= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-ntlmssp v0.1.0 h1:DjFo6YtWzNqNvQdrwEyr/e4nhU3vRiwenz5QX7sFz+A= -github.com/Azure/go-ntlmssp v0.1.0/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk= +github.com/Azure/go-ntlmssp v0.1.1 h1:l+FM/EEMb0U9QZE7mKNEDw5Mu3mFiaa2GKOoTSsNDPw= +github.com/Azure/go-ntlmssp v0.1.1/go.mod h1:NYqdhxd/8aAct/s4qSYZEerdPuH1liG2/X9DiVTbhpk= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= @@ -41,8 +41,8 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUo github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4= github.com/containerd/cgroups/v3 v3.0.5 h1:44na7Ud+VwyE7LIoJ8JTNQOa549a8543BmzaJHo6Bzo= github.com/containerd/cgroups/v3 v3.0.5/go.mod h1:SA5DLYnXO8pTGYiAHXz94qvLQTKfVM5GEVisn4jpins= -github.com/containerd/containerd v1.7.30 h1:/2vezDpLDVGGmkUXmlNPLCCNKHJ5BbC5tJB5JNzQhqE= -github.com/containerd/containerd v1.7.30/go.mod h1:fek494vwJClULlTpExsmOyKCMUAbuVjlFsJQc4/j44M= +github.com/containerd/containerd v1.7.32 h1:S54xuVcPxeLaYgaRABtpJ2VyVUVsy0IGf7qHBs+sbY8= +github.com/containerd/containerd v1.7.32/go.mod h1:jdwD6s/BhV4XVJGrvtziNPVA+83n66TwptVaPKprq4E= github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0= github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= github.com/containerd/continuity v0.4.4 h1:/fNVfTJ7wIl/YPMHjf+5H32uFhl63JucB34PlCpMKII= @@ -79,12 +79,16 @@ github.com/docker/cli v29.6.0+incompatible h1:nw9himxMMZ7eIeherJNlKQq+acnlzGgHd+ github.com/docker/cli v29.6.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= -github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= -github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c= +github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8= github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/elastic/go-freelru v0.16.0 h1:gG2HJ1WXN2tNl5/p40JS/l59HjvjRhjyAa+oFTRArYs= +github.com/elastic/go-freelru v0.16.0/go.mod h1:bSdWT4M0lW79K8QbX6XY2heQYSCqD7THoYf82pT/H3I= +github.com/elastic/go-perf v0.0.0-20260224073651-af0ee0c731b7 h1:fGi5uudj7m5O1RgQl+bSZmwlqvuUMEi97X7TzWBOMGk= +github.com/elastic/go-perf v0.0.0-20260224073651-af0ee0c731b7/go.mod h1:ucTo2u8JvFyIPQOaRlX7aVF0d3wwmF1dy/PVp5GUHZI= github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -124,8 +128,8 @@ github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6 h1:teYtXy9B7y5 github.com/go-quicktest/qt v1.101.1-0.20240301121107-c6c8733fa1e6/go.mod h1:p4lGIVX+8Wa6ZPNDvqcxq36XpUDLh42FLetFU7odllI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= -github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/godbus/dbus/v5 v5.2.2 h1:TUR3TgtSVDmjiXOgAAyaZbYmIeP3DPkld3jgKGV8mXQ= github.com/godbus/dbus/v5 v5.2.2/go.mod h1:3AAv2+hPq5rdnr5txxxRwiGjPXamgoIHgz9FPBfOp3c= github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw= @@ -182,12 +186,14 @@ github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJr github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/in-toto/attestation v1.1.2 h1:MBFn6lsMq6dptQZJBhalXTcWMb/aJy3V+GX3VYj/V1E= -github.com/in-toto/attestation v1.1.2/go.mod h1:gYFddHMZj3DiQ0b62ltNi1Vj5rC879bTmBbrv9CRHpM= +github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bPle2i4= +github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/in-toto/attestation v1.2.0 h1:aPRUZ3azbqD7yEBD5fP3TD8Dszf+YHo284SOcpahjQk= +github.com/in-toto/attestation v1.2.0/go.mod h1:r79G45gOmzPismgObLSL+rZTFxUgZLOQJI6LofTZgXk= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/inspektor-gadget/inspektor-gadget v0.51.1 h1:fEL7Sbib3iOGq6esJsT+R+FVVshtJ+ejGMHevM/qQ6o= -github.com/inspektor-gadget/inspektor-gadget v0.51.1/go.mod h1:1K1uFLKnwRPwD+MWd+iZSZ6c1Z+ldpQPOaTEZ8YM6yw= +github.com/inspektor-gadget/inspektor-gadget v0.53.2 h1:0ZfiU4lSzoSHBJmz83Y0IMczGF4Be3ymXXmLZCpbBI4= +github.com/inspektor-gadget/inspektor-gadget v0.53.2/go.mod h1:nsnAhJzx7A/TYkcp1qTuSkGtY2wf8mgC/JCQqTQ9BUI= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= @@ -232,6 +238,8 @@ github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -249,6 +257,8 @@ github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4 github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mdlayher/ethtool v0.0.0-20210210192532-2b88debcdd43/go.mod h1:+t7E0lkKfbBsebllff1xdTmyJt8lH37niI6kwFk9OTo= github.com/mdlayher/genetlink v1.0.0/go.mod h1:0rJ0h4itni50A86M2kHcgS85ttZazNt7a8H2a2cw0Gc= +github.com/mdlayher/kobject v0.0.0-20200520190114-19ca17470d7d h1:JmrZTpS0GAyMV4ZQVVH/AS0Y6r2PbnYNSRUuRX+HOLA= +github.com/mdlayher/kobject v0.0.0-20200520190114-19ca17470d7d/go.mod h1:+SexPO1ZvdbbWUdUnyXEWv3+4NwHZjKhxOmQqHY4Pqc= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= github.com/mdlayher/netlink v1.1.0/go.mod h1:H4WCitaheIsdF9yOYu8CFmCgQthAPIWZmcKp9uZHgmY= @@ -266,14 +276,16 @@ github.com/mdlayher/socket v0.0.0-20210307095302-262dc9984e00/go.mod h1:GAFlyu4/ github.com/mdlayher/socket v0.1.1/go.mod h1:mYV5YIZAfHh4dzDVzI8x8tWLWCliuX8Mon5Awbj+qDs= github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos= github.com/mdlayher/socket v0.5.1/go.mod h1:TjPLHI1UgwEv5J1B5q0zTZq12A/6H7nKmtTanQE37IQ= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/moby/api v1.54.0 h1:7kbUgyiKcoBhm0UrWbdrMs7RX8dnwzURKVbZGy2GnL0= -github.com/moby/moby/api v1.54.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= -github.com/moby/moby/client v0.3.0 h1:UUGL5okry+Aomj3WhGt9Aigl3ZOxZGqR7XPo+RLPlKs= -github.com/moby/moby/client v0.3.0/go.mod h1:HJgFbJRvogDQjbM8fqc1MCEm4mIAGMLjXbgwoZp6jCQ= +github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg= +github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= +github.com/moby/moby/client v0.4.1 h1:DMQgisVoMkmMs7fp3ROSdiBnoAu8+vo3GggFl06M/wY= +github.com/moby/moby/client v0.4.1/go.mod h1:z52C9O2POPOsnxZAy//WtKcQ32P+jT/NGeXu/7nfjGQ= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= @@ -350,8 +362,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.10.0 h1:l+H5ErcW0PAehBNrBxo github.com/secure-systems-lab/go-securesystemslib v0.10.0/go.mod h1:MRKONWmRoFzPNQ9USRF9i1mc7MvAVvF1LlW8X5VWDvk= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= -github.com/sigstore/protobuf-specs v0.5.0 h1:F8YTI65xOHw70NrvPwJ5PhAzsvTnuJMGLkA4FIkofAY= -github.com/sigstore/protobuf-specs v0.5.0/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc= +github.com/sigstore/protobuf-specs v0.5.1 h1:/5OPaNuolRJmQfeZLayJGFXMpsRJEdgC6ah1/+7Px7U= +github.com/sigstore/protobuf-specs v0.5.1/go.mod h1:DRBzpFuE+LnvQMN10/dU6nBeKwVLGEQ6o2FovN2Rats= github.com/sigstore/sigstore v1.10.4 h1:ytOmxMgLdcUed3w1SbbZOgcxqwMG61lh1TmZLN+WeZE= github.com/sigstore/sigstore v1.10.4/go.mod h1:tDiyrdOref3q6qJxm2G+JHghqfmvifB7hw+EReAfnbI= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= @@ -397,12 +409,26 @@ github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zeebo/xxh3 v1.1.0 h1:s7DLGDK45Dyfg7++yxI0khrfwq9661w9EN78eP/UZVs= +github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F5s= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= 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/collector/consumer v1.53.0 h1:Gyy80dX5r1Lv9lvQk8XFtUkWs1eniicOzzCQBejLseg= +go.opentelemetry.io/collector/consumer v1.53.0/go.mod h1:f5U6ibd+XpC5eOSeEYhERAQJ2a5bp1d2RzW3MFddMDM= +go.opentelemetry.io/collector/consumer/xconsumer v0.147.0 h1:XJVQc2dYyalaFXMTa4/RE+aweQTiBpw1edfwdCIJSxw= +go.opentelemetry.io/collector/consumer/xconsumer v0.147.0/go.mod h1:mtwh1VsUoGjxwdmXEzjbswH7KAGByJNCIMHmhqwXeK0= +go.opentelemetry.io/collector/featuregate v1.53.0 h1:cgjXdtl7jezWxq6V0eohe/JqjY4PBotZGb5+bTR2OJw= +go.opentelemetry.io/collector/featuregate v1.53.0/go.mod h1:PS7zY/zaCb28EqciePVwRHVhc3oKortTFXsi3I6ee4g= +go.opentelemetry.io/collector/pdata v1.53.0 h1:DlYDbRwammEZaxDZHINx5v0n8SEOVNniPbi6FRTlVkA= +go.opentelemetry.io/collector/pdata v1.53.0/go.mod h1:LRSYGNjKXaUrZEwZv3Yl+8/zV2HmRGKXW62zB2bysms= +go.opentelemetry.io/collector/pdata/pprofile v0.147.0 h1:yQS3RBvcvRcy9N7AnJvsxmse0AxJcRqBZfwMA22xBA8= +go.opentelemetry.io/collector/pdata/pprofile v0.147.0/go.mod h1:pm9mUqHNpT1SaCkxILu4FW1BvMAelh7EKhpSKe2KJIQ= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0/go.mod h1:h06DGIukJOevXaj/xrNjhi/2098RZzcLTbc0jDAUbsg= +go.opentelemetry.io/ebpf-profiler v0.0.202536 h1:RokX9rsyO9uEbdHSC5145jYZIxIXk//u9cJTSh6Vy30= +go.opentelemetry.io/ebpf-profiler v0.0.202536/go.mod h1:oGg4sNNmbpAuXZtzBGnHp7tCSeEWRK7ij4TltZdqsAY= 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= @@ -415,25 +441,29 @@ go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09 go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/arch v0.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y= +golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= -golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/yqS/lQJ6PmkyIV3YP+o= -golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= +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/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI= -golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY= +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-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -454,8 +484,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210928044308-7d9f5e0b762b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= -golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= @@ -497,18 +527,18 @@ golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.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.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= -golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= +golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4= +golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk= 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.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= -golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -519,14 +549,14 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s= -golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0= +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-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= -gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= @@ -543,8 +573,8 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE= -google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ= +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 v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -574,24 +604,24 @@ gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ= -k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4= -k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8= -k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= -k8s.io/cli-runtime v0.35.3 h1:UZq4ipNimtzBmhN7PPKbfAdqo8quK0H0UdGl6qAQnqI= -k8s.io/cli-runtime v0.35.3/go.mod h1:O7MUmCqcKSd5xI+O5X7/pRkB5l0O2NIhOdUVwbHLXu4= -k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg= -k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c= -k8s.io/component-base v0.35.3 h1:mbKbzoIMy7JDWS/wqZobYW1JDVRn/RKRaoMQHP9c4P0= -k8s.io/component-base v0.35.3/go.mod h1:IZ8LEG30kPN4Et5NeC7vjNv5aU73ku5MS15iZyvyMYk= -k8s.io/cri-api v0.35.3 h1:gONTLBvK1eBPyveXEQ39mtTqi2oANeHj1mCo1YhQosI= -k8s.io/cri-api v0.35.3/go.mod h1:Cnt29u/tYl1Se1cBRL30uSZ/oJ5TaIp4sZm1xDLvcMc= +k8s.io/api v0.35.4 h1:P7nFYKl5vo9AGUp1Z+Pmd3p2tA7bX2wbFWCvDeRv988= +k8s.io/api v0.35.4/go.mod h1:yl4lqySWOgYJJf9RERXKUwE9g2y+CkuwG+xmcOK8wXU= +k8s.io/apimachinery v0.35.4 h1:xtdom9RG7e+yDp71uoXoJDWEE2eOiHgeO4GdBzwWpds= +k8s.io/apimachinery v0.35.4/go.mod h1:NNi1taPOpep0jOj+oRha3mBJPqvi0hGdaV8TCqGQ+cc= +k8s.io/cli-runtime v0.35.4 h1:8QRCXSDvopflFNM65Vkkdv42BljPdRSiqf6HFyI1iik= +k8s.io/cli-runtime v0.35.4/go.mod h1:MKLFuZxiJpm87UxjVeQRNy3sCaczHrSOPKN9pinlrM0= +k8s.io/client-go v0.35.4 h1:DN6fyaGuzK64UvnKO5fOA6ymSjvfGAnCAHAR0C66kD8= +k8s.io/client-go v0.35.4/go.mod h1:2Pg9WpsS4NeOpoYTfHHfMxBG8zFMSAUi4O/qoiJC3nY= +k8s.io/component-base v0.35.4 h1:6n1tNJ87johN0Hif0Fs8K2GMthsaUwMqCebUDLYyv7U= +k8s.io/component-base v0.35.4/go.mod h1:qaDJgz5c1KYKla9occFmlJEfPpkuA55s90G509R+PeY= +k8s.io/cri-api v0.35.4 h1:9/3Wj18YldMLADyiPoZGrdFHZ7miA8LVO2cjjWENPlk= +k8s.io/cri-api v0.35.4/go.mod h1:V7aEqk4QGvezHJYFCLGfTA+XqSkD6WoWTQdPirLLbFM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/kubelet v0.35.3 h1:Y6b9+U/aTBmou9JZ6qv18O4dpFbJOfl7cBe+ZksT7RY= -k8s.io/kubelet v0.35.3/go.mod h1:aWoMogtyUEf/mTl8VjqHbSkW5ZZkB8vTkrg9Fi6TKwE= +k8s.io/kubelet v0.35.4 h1:g/qX1F6PdJQYzAzje3BDRGGEAmeYiiRi9QlLuyliRyw= +k8s.io/kubelet v0.35.4/go.mod h1:T3X1s+/TM23j8j3hjIem0PCBoSc7VNaKDyOkzAHUiDU= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go/v2 v2.6.1 h1:bonOEkjLfp8tt6qXWRRWP6p1F+9octchOf2EqnWB4Zs= From eae57ee7f4a7050d6ec5a7329a5f356014402799 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 13:37:45 +0000 Subject: [PATCH 18/32] build: upgrade go to 1.26 ahead of inspektor-gadget requirement Signed-off-by: Dor Serero --- Dockerfile | 2 +- Dockerfile.sigward | 2 +- go.mod | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index 565a4ca..39d714a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,7 +26,7 @@ RUN mkdir -p build/gadgets && \ build/gadgets/${gadget}.tar; \ done -FROM --platform=$BUILDPLATFORM golang:1.25.7-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.26.4-alpine AS builder ARG IG_VERSION=v0.53.2 ARG IMAGE_TAG=dev diff --git a/Dockerfile.sigward b/Dockerfile.sigward index aa27d6b..abad129 100644 --- a/Dockerfile.sigward +++ b/Dockerfile.sigward @@ -26,7 +26,7 @@ RUN mkdir -p build/gadgets && \ build/gadgets/${gadget}.tar; \ done -FROM --platform=$BUILDPLATFORM golang:1.25.7-alpine AS builder +FROM --platform=$BUILDPLATFORM golang:1.26.4-alpine AS builder ARG IG_VERSION=v0.53.2 ARG IMAGE_TAG=dev diff --git a/go.mod b/go.mod index 01f59d3..640a597 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/micromize-dev/micromize -go 1.25.7 +go 1.26.4 require ( github.com/cilium/ebpf v0.21.0 From 774fb5995574c3792d1c14a288817897bd39faa6 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 13:51:11 +0000 Subject: [PATCH 19/32] docs(helm): correct SYS_PTRACE capability comment Signed-off-by: Dor Serero --- charts/micromize/templates/daemonset.yaml | 3 ++- charts/sigward/templates/daemonset.yaml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/charts/micromize/templates/daemonset.yaml b/charts/micromize/templates/daemonset.yaml index 0058f48..1f36e0b 100644 --- a/charts/micromize/templates/daemonset.yaml +++ b/charts/micromize/templates/daemonset.yaml @@ -40,7 +40,8 @@ spec: - SYS_ADMIN # Required for reading kernel logs. - SYSLOG - # Required for ptrace-based gadgets. + # Required to read /proc//ns/* for container/namespace + # enrichment (kernel gates this behind ptrace_may_access). - SYS_PTRACE # Required for setting rlimits (e.g. memlock). - SYS_RESOURCE diff --git a/charts/sigward/templates/daemonset.yaml b/charts/sigward/templates/daemonset.yaml index 5fb3867..5614151 100644 --- a/charts/sigward/templates/daemonset.yaml +++ b/charts/sigward/templates/daemonset.yaml @@ -40,7 +40,8 @@ spec: - SYS_ADMIN # Required for reading kernel logs. - SYSLOG - # Required for ptrace-based gadgets. + # Required to read /proc//ns/* for container/namespace + # enrichment (kernel gates this behind ptrace_may_access). - SYS_PTRACE # Required for setting rlimits (e.g. memlock). - SYS_RESOURCE From 362addd32bea5c4c359291804096dd096a0d543a Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 14:08:24 +0000 Subject: [PATCH 20/32] fix: derive agent namespace at runtime for self-exclusion Signed-off-by: Dor Serero --- charts/micromize/templates/daemonset.yaml | 4 ++++ charts/sigward/templates/daemonset.yaml | 4 ++++ cmd/micromize/root.go | 3 ++- cmd/sigward/root.go | 3 ++- internal/k8s/namespaces.go | 28 +++++++++++++++++++++++ internal/k8s/namespaces_test.go | 23 +++++++++++++++++++ 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/charts/micromize/templates/daemonset.yaml b/charts/micromize/templates/daemonset.yaml index 1f36e0b..a8ec0d5 100644 --- a/charts/micromize/templates/daemonset.yaml +++ b/charts/micromize/templates/daemonset.yaml @@ -72,6 +72,10 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace volumeMounts: # Required for pinning BPF maps. - mountPath: /sys/fs/bpf diff --git a/charts/sigward/templates/daemonset.yaml b/charts/sigward/templates/daemonset.yaml index 5614151..942a6fa 100644 --- a/charts/sigward/templates/daemonset.yaml +++ b/charts/sigward/templates/daemonset.yaml @@ -72,6 +72,10 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace {{- if .Values.registryAuth.existingSecret }} - name: DOCKER_CONFIG value: /etc/docker-registry diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index 77b6e4e..1106a16 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -132,7 +132,8 @@ func run(ctx context.Context) error { return fmt.Errorf("getting host pid namespace ID: %w", err) } - nsFilter := utils.BuildNamespaceFilter(filterNamespaces, "micromize") + selfNamespace := k8sclient.CurrentNamespace("micromize") + nsFilter := utils.BuildNamespaceFilter(filterNamespaces, selfNamespace) // Discover namespaces exempt by label and append them as exclusions. // Evaluated at startup only — a DaemonSet restart is required to pick up diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go index 9c748a3..692481d 100644 --- a/cmd/sigward/root.go +++ b/cmd/sigward/root.go @@ -122,7 +122,8 @@ func run(ctx context.Context) error { // Create gadget registry registry := gadget.NewRegistry(contextManager, runtimeManager) - nsFilter := utils.BuildNamespaceFilter(filterNamespaces, "sigward") + selfNamespace := k8sclient.CurrentNamespace("sigward") + nsFilter := utils.BuildNamespaceFilter(filterNamespaces, selfNamespace) // Discover namespaces exempt by label and append them as exclusions. // Evaluated at startup only — a DaemonSet restart is required to pick up diff --git a/internal/k8s/namespaces.go b/internal/k8s/namespaces.go index 63bb9b8..9ef1aa7 100644 --- a/internal/k8s/namespaces.go +++ b/internal/k8s/namespaces.go @@ -17,6 +17,7 @@ package k8s import ( "context" "fmt" + "os" "strings" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -27,6 +28,33 @@ import ( const exemptLabelValue = "true" +const ( + // podNamespaceEnvVar can be populated via the Kubernetes Downward API + // (fieldRef: metadata.namespace). + podNamespaceEnvVar = "POD_NAMESPACE" + // serviceAccountNamespacePath is the namespace file mounted into every pod + // that has a service account token. + serviceAccountNamespacePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" +) + +// CurrentNamespace returns the namespace the agent is running in. It is +// discovered from the POD_NAMESPACE environment variable (Downward API) first, +// then the in-cluster service account namespace file. When neither is available +// (e.g. running outside Kubernetes), it returns fallback. This avoids hardcoding +// the agent's namespace, which would otherwise let it monitor itself when the +// chart is installed into an arbitrarily named namespace. +func CurrentNamespace(fallback string) string { + if ns := strings.TrimSpace(os.Getenv(podNamespaceEnvVar)); ns != "" { + return ns + } + if data, err := os.ReadFile(serviceAccountNamespacePath); err == nil { + if ns := strings.TrimSpace(string(data)); ns != "" { + return ns + } + } + return fallback +} + // NewClient builds a Kubernetes client using in-cluster config, falling back // to the default kubeconfig for local development. func NewClient() (kubernetes.Interface, error) { diff --git a/internal/k8s/namespaces_test.go b/internal/k8s/namespaces_test.go index 677b7f6..0ca284e 100644 --- a/internal/k8s/namespaces_test.go +++ b/internal/k8s/namespaces_test.go @@ -139,3 +139,26 @@ func TestListExemptNamespaces(t *testing.T) { }) } } + +func TestCurrentNamespace(t *testing.T) { + t.Run("returns POD_NAMESPACE env when set", func(t *testing.T) { + t.Setenv(podNamespaceEnvVar, "team-security") + if got := CurrentNamespace("micromize"); got != "team-security" { + t.Errorf("CurrentNamespace() = %q, want %q", got, "team-security") + } + }) + + t.Run("trims whitespace from env value", func(t *testing.T) { + t.Setenv(podNamespaceEnvVar, " prod ") + if got := CurrentNamespace("micromize"); got != "prod" { + t.Errorf("CurrentNamespace() = %q, want %q", got, "prod") + } + }) + + t.Run("falls back when env empty and no service account file", func(t *testing.T) { + t.Setenv(podNamespaceEnvVar, "") + if got := CurrentNamespace("sigward"); got != "sigward" { + t.Errorf("CurrentNamespace() = %q, want %q", got, "sigward") + } + }) +} From 134dacf24776b443231cb0f2aab6b96974595db5 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 14:08:24 +0000 Subject: [PATCH 21/32] fix(helm): add exemptLabel to values schema Signed-off-by: Dor Serero --- charts/micromize/values.schema.json | 4 ++++ charts/sigward/values.schema.json | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/charts/micromize/values.schema.json b/charts/micromize/values.schema.json index a11a6d1..959a87a 100644 --- a/charts/micromize/values.schema.json +++ b/charts/micromize/values.schema.json @@ -92,6 +92,10 @@ }, "podAnnotations": { "type": "object" + }, + "exemptLabel": { + "type": "string", + "description": "Kubernetes label key used to mark namespaces as exempt from monitoring (value must be 'true'). Empty string disables the feature." } } } diff --git a/charts/sigward/values.schema.json b/charts/sigward/values.schema.json index 379f421..2122485 100644 --- a/charts/sigward/values.schema.json +++ b/charts/sigward/values.schema.json @@ -101,6 +101,10 @@ "description": "Name of an existing Kubernetes secret of type kubernetes.io/dockerconfigjson for private registry authentication" } } + }, + "exemptLabel": { + "type": "string", + "description": "Kubernetes label key used to mark namespaces as exempt from monitoring (value must be 'true'). Empty string disables the feature." } } } From 146431eda875570108e6d7db08db211b6e5e0651 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 18:51:54 +0000 Subject: [PATCH 22/32] feat: attest sigward's own namespace Signed-off-by: Dor Serero --- charts/sigward/templates/daemonset.yaml | 4 ---- cmd/sigward/root.go | 6 ++++-- internal/utils/utils.go | 23 +++++++++++++---------- internal/utils/utils_test.go | 3 +++ 4 files changed, 20 insertions(+), 16 deletions(-) diff --git a/charts/sigward/templates/daemonset.yaml b/charts/sigward/templates/daemonset.yaml index 942a6fa..5614151 100644 --- a/charts/sigward/templates/daemonset.yaml +++ b/charts/sigward/templates/daemonset.yaml @@ -72,10 +72,6 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - - name: POD_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace {{- if .Values.registryAuth.existingSecret }} - name: DOCKER_CONFIG value: /etc/docker-registry diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go index 692481d..8c74103 100644 --- a/cmd/sigward/root.go +++ b/cmd/sigward/root.go @@ -122,8 +122,10 @@ func run(ctx context.Context) error { // Create gadget registry registry := gadget.NewRegistry(contextManager, runtimeManager) - selfNamespace := k8sclient.CurrentNamespace("sigward") - nsFilter := utils.BuildNamespaceFilter(filterNamespaces, selfNamespace) + // Sigward attests every namespace, including its own — it follows its own + // attestation rules rather than exempting itself. Operators can still scope + // coverage with --filter-namespaces and --exempt-label. + nsFilter := utils.BuildNamespaceFilter(filterNamespaces, "") // Discover namespaces exempt by label and append them as exclusions. // Evaluated at startup only — a DaemonSet restart is required to pick up diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 649af90..4e971da 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -46,15 +46,17 @@ func BoolToInt(b bool) int { } // BuildNamespaceFilter constructs the LocalManager k8s-namespace filter value. -// It always excludes the agent's own namespace (selfNamespace) and appends any -// user-specified namespace filters, skipping empty segments. When -// filterNamespaces is empty, only the self-exclusion is returned. +// When selfNamespace is non-empty, the agent's own namespace is excluded +// ("!"); when it is empty, no self-exclusion is added (the agent +// monitors its own namespace too). User-specified namespace filters are appended +// with empty segments skipped. An empty result means "all namespaces". func BuildNamespaceFilter(filterNamespaces, selfNamespace string) string { - exclude := "!" + selfNamespace - normalizedFilter := exclude + var parts []string - if filterNamespaces == "" { - return normalizedFilter + exclude := "" + if selfNamespace != "" { + exclude = "!" + selfNamespace + parts = append(parts, exclude) } for _, p := range strings.Split(filterNamespaces, ",") { @@ -62,12 +64,13 @@ func BuildNamespaceFilter(filterNamespaces, selfNamespace string) string { if nsPart == "" { continue } - if nsPart != exclude { - normalizedFilter += "," + nsPart + if exclude != "" && nsPart == exclude { + continue } + parts = append(parts, nsPart) } - return normalizedFilter + return strings.Join(parts, ",") } func GetHostPidNamespaceID() (uint64, error) { diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index 9f543e8..6ad75a7 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -118,6 +118,9 @@ func TestBuildNamespaceFilter(t *testing.T) { {"exclusion filter", "!kube-system", "sigward", "!sigward,!kube-system"}, {"empty segments skipped", "default,,kube-system,", "sigward", "!sigward,default,kube-system"}, {"whitespace trimmed", " default , kube-system ", "micromize", "!micromize,default,kube-system"}, + {"no self-exclusion, empty filter means all", "", "", ""}, + {"no self-exclusion keeps user filter", "default,kube-system", "", "default,kube-system"}, + {"no self-exclusion respects user exclusion", "default,!kube-system", "", "default,!kube-system"}, } for _, tt := range tests { From 532b226295ae8c78857e5b228cd46713e2b997aa Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 19:01:51 +0000 Subject: [PATCH 23/32] build: rename Dockerfile to Dockerfile.micromize Signed-off-by: Dor Serero --- .github/workflows/build.yml | 2 +- .github/workflows/release.yml | 1 + Dockerfile => Dockerfile.micromize | 0 Makefile | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) rename Dockerfile => Dockerfile.micromize (100%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index e97dd0f..d97eadc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -76,7 +76,7 @@ jobs: run: go test ./... - name: Build Micromize image - run: docker build . + run: docker build -f Dockerfile.micromize . - name: Build Sigward image run: docker build -f Dockerfile.sigward . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d9a1e8..1cd77d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -109,6 +109,7 @@ jobs: uses: docker/build-push-action@v7 with: context: . + file: Dockerfile.micromize push: true tags: | ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ env.TAG_NAME }} diff --git a/Dockerfile b/Dockerfile.micromize similarity index 100% rename from Dockerfile rename to Dockerfile.micromize diff --git a/Makefile b/Makefile index 5cda317..de9f7af 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,7 @@ dev-build: ## Build Docker image for dev deployment ifeq ($(strip $(DEV_REGISTRY)),) $(error DEV_REGISTRY is required. Set it via environment or argument: make dev-build DEV_REGISTRY=myacr.azurecr.io) endif - docker build --no-cache -t $(DEV_REGISTRY)/micromize:$(DEV_TAG) . + docker build --no-cache -f Dockerfile.micromize -t $(DEV_REGISTRY)/micromize:$(DEV_TAG) . .PHONY: dev-push dev-push: ## Push dev image to registry From 8dc769b4a948a13c840bf2c828362b247449f27d Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 19:13:39 +0000 Subject: [PATCH 24/32] fix: avoid leading comma when appending exempt namespaces Signed-off-by: Dor Serero --- cmd/micromize/root.go | 2 +- cmd/sigward/root.go | 2 +- internal/utils/utils.go | 11 +++++++++++ internal/utils/utils_test.go | 21 +++++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index 1106a16..b1282a8 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -149,7 +149,7 @@ func run(ctx context.Context) error { } else if len(exemptNS) > 0 { slog.Info("Exempt namespaces discovered (startup only)", "namespaces", exemptNS, "label", exemptLabel) for _, ns := range exemptNS { - nsFilter += ",!" + ns + nsFilter = utils.AppendNamespaceExclusion(nsFilter, ns) } } } diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go index 8c74103..7fc1bf0 100644 --- a/cmd/sigward/root.go +++ b/cmd/sigward/root.go @@ -141,7 +141,7 @@ func run(ctx context.Context) error { } else if len(exemptNS) > 0 { slog.Info("Exempt namespaces discovered (startup only)", "namespaces", exemptNS, "label", exemptLabel) for _, ns := range exemptNS { - nsFilter += ",!" + ns + nsFilter = utils.AppendNamespaceExclusion(nsFilter, ns) } } } diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 4e971da..8d91663 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -73,6 +73,17 @@ func BuildNamespaceFilter(filterNamespaces, selfNamespace string) string { return strings.Join(parts, ",") } +// AppendNamespaceExclusion appends an exclusion ("!namespace") to a +// comma-separated LocalManager k8s-namespace filter, avoiding a leading comma +// when the filter is empty (which can happen for agents that do not self-exclude). +func AppendNamespaceExclusion(filter, namespace string) string { + exclusion := "!" + namespace + if filter == "" { + return exclusion + } + return filter + "," + exclusion +} + func GetHostPidNamespaceID() (uint64, error) { var stat syscall.Stat_t if err := syscall.Stat("/proc/1/ns/pid", &stat); err != nil { diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index 6ad75a7..fe4715f 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -132,3 +132,24 @@ func TestBuildNamespaceFilter(t *testing.T) { }) } } + +func TestAppendNamespaceExclusion(t *testing.T) { + tests := []struct { + name string + filter string + namespace string + want string + }{ + {"empty filter yields no leading comma", "", "sigward", "!sigward"}, + {"appends to a non-empty filter", "default", "sigward", "default,!sigward"}, + {"appends to existing exclusions", "!micromize,default", "foo", "!micromize,default,!foo"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := AppendNamespaceExclusion(tt.filter, tt.namespace); got != tt.want { + t.Errorf("AppendNamespaceExclusion(%q, %q) = %q, want %q", tt.filter, tt.namespace, got, tt.want) + } + }) + } +} From c5c0b6862c50e524b3d2193ba50f4619c7e386e9 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 19:13:39 +0000 Subject: [PATCH 25/32] refactor: make namespace file path injectable for tests Signed-off-by: Dor Serero --- internal/k8s/namespaces.go | 7 ++++--- internal/k8s/namespaces_test.go | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/internal/k8s/namespaces.go b/internal/k8s/namespaces.go index 9ef1aa7..4cc7621 100644 --- a/internal/k8s/namespaces.go +++ b/internal/k8s/namespaces.go @@ -32,11 +32,12 @@ const ( // podNamespaceEnvVar can be populated via the Kubernetes Downward API // (fieldRef: metadata.namespace). podNamespaceEnvVar = "POD_NAMESPACE" - // serviceAccountNamespacePath is the namespace file mounted into every pod - // that has a service account token. - serviceAccountNamespacePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" ) +// serviceAccountNamespacePath is the namespace file mounted into every pod that +// has a service account token. It is a var so tests can override it. +var serviceAccountNamespacePath = "/var/run/secrets/kubernetes.io/serviceaccount/namespace" + // CurrentNamespace returns the namespace the agent is running in. It is // discovered from the POD_NAMESPACE environment variable (Downward API) first, // then the in-cluster service account namespace file. When neither is available diff --git a/internal/k8s/namespaces_test.go b/internal/k8s/namespaces_test.go index 0ca284e..b15e21d 100644 --- a/internal/k8s/namespaces_test.go +++ b/internal/k8s/namespaces_test.go @@ -16,6 +16,8 @@ package k8s import ( "context" + "os" + "path/filepath" "testing" corev1 "k8s.io/api/core/v1" @@ -155,8 +157,27 @@ func TestCurrentNamespace(t *testing.T) { } }) + t.Run("reads service account file when env unset", func(t *testing.T) { + t.Setenv(podNamespaceEnvVar, "") + path := filepath.Join(t.TempDir(), "namespace") + if err := os.WriteFile(path, []byte("prod-ns\n"), 0o600); err != nil { + t.Fatalf("writing namespace file: %v", err) + } + orig := serviceAccountNamespacePath + serviceAccountNamespacePath = path + t.Cleanup(func() { serviceAccountNamespacePath = orig }) + + if got := CurrentNamespace("fallback"); got != "prod-ns" { + t.Errorf("CurrentNamespace() = %q, want %q", got, "prod-ns") + } + }) + t.Run("falls back when env empty and no service account file", func(t *testing.T) { t.Setenv(podNamespaceEnvVar, "") + orig := serviceAccountNamespacePath + serviceAccountNamespacePath = filepath.Join(t.TempDir(), "does-not-exist") + t.Cleanup(func() { serviceAccountNamespacePath = orig }) + if got := CurrentNamespace("sigward"); got != "sigward" { t.Errorf("CurrentNamespace() = %q, want %q", got, "sigward") } From 7ce86ecb8ff4338687baa097a45a19e67dd26cb8 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 19:13:39 +0000 Subject: [PATCH 26/32] fix(helm): require image.tag in values schema Signed-off-by: Dor Serero --- charts/micromize/values.schema.json | 2 +- charts/sigward/values.schema.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/charts/micromize/values.schema.json b/charts/micromize/values.schema.json index 959a87a..c737e98 100644 --- a/charts/micromize/values.schema.json +++ b/charts/micromize/values.schema.json @@ -23,7 +23,7 @@ "description": "Image digest for self-exclusion filtering (e.g. sha256:abc123...)" } }, - "required": ["repository", "pullPolicy"] + "required": ["repository", "pullPolicy", "tag"] }, "logLevel": { "type": "string", diff --git a/charts/sigward/values.schema.json b/charts/sigward/values.schema.json index 2122485..3dbb24e 100644 --- a/charts/sigward/values.schema.json +++ b/charts/sigward/values.schema.json @@ -23,7 +23,7 @@ "description": "Image digest for self-exclusion filtering (e.g. sha256:abc123...)" } }, - "required": ["repository", "pullPolicy"] + "required": ["repository", "pullPolicy", "tag"] }, "logLevel": { "type": "string", From c81484ecb09010e3991d8e19e7248d90ebffb47a Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 19:29:07 +0000 Subject: [PATCH 27/32] docs: correct sigward filter-namespaces help text Signed-off-by: Dor Serero --- cmd/sigward/root.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go index 7fc1bf0..bc66986 100644 --- a/cmd/sigward/root.go +++ b/cmd/sigward/root.go @@ -68,7 +68,7 @@ func init() { rootCmd.Version = Version rootCmd.PersistentFlags().BoolVar(&enforce, "enforce", true, "Enforce restrictions") rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging") - rootCmd.PersistentFlags().StringVar(&filterNamespaces, "filter-namespaces", "", "Comma-separated list of Kubernetes namespaces to monitor (empty means all except 'sigward'). Supports exclusion with '!' prefix.") + rootCmd.PersistentFlags().StringVar(&filterNamespaces, "filter-namespaces", "", "Comma-separated list of Kubernetes namespaces to monitor (empty means all namespaces). Supports exclusion with '!' prefix.") rootCmd.PersistentFlags().StringVar(&filterImageDigest, "filter-image-digest", "", "Filter out containers running this image digest from monitoring (e.g. sha256:abc123...)") rootCmd.PersistentFlags().StringVar(&exemptLabel, "exempt-label", "sigward.dev/exempt", "Kubernetes label key used to mark namespaces as exempt from monitoring (value must be 'true'). Set to empty string to disable. Changes take effect on restart.") } From 34e1d35c4060caa54bb1c554ffb8077987c7ea87 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Fri, 3 Jul 2026 19:29:07 +0000 Subject: [PATCH 28/32] build: use go 1.26 directive with toolchain go1.26.4 Signed-off-by: Dor Serero --- go.mod | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 640a597..e2e7d07 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/micromize-dev/micromize -go 1.26.4 +go 1.26 + +toolchain go1.26.4 require ( github.com/cilium/ebpf v0.21.0 From a5f181ca20bba00050293d1dc7a6b7278fd11203 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Sat, 4 Jul 2026 04:44:30 +0000 Subject: [PATCH 29/32] fix: close superseded inner map to avoid bpf fd leak Signed-off-by: Dor Serero --- internal/attest/ima.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/internal/attest/ima.go b/internal/attest/ima.go index e1a0de5..25731a8 100644 --- a/internal/attest/ima.go +++ b/internal/attest/ima.go @@ -223,8 +223,16 @@ func populateExpectedHashes(gadgetCtx igoperators.GadgetContext, innerMaps *sync return } - // Track the inner map for cleanup on container removal - innerMaps.Store(mntnsID, innerMap) + // Track the inner map for cleanup on container removal. Close any map + // previously tracked for this mount namespace so a repeated CREATED event + // for the same mntns_id doesn't leak the superseded map's FD/memory. + if old, loaded := innerMaps.Swap(mntnsID, innerMap); loaded { + if oldMap, ok := old.(*ebpf.Map); ok && oldMap != nil { + if err := oldMap.Close(); err != nil { + slog.Debug("Failed to close superseded inner BPF map", "mntns_id", mntnsID, "error", err) + } + } + } slog.Debug("Populated expected_hashes map", "mntns_id", mntnsID, "entries", len(files)) } From 32a84ecb93b52f33e58312a93a6658c6e1240677 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Sat, 4 Jul 2026 04:44:30 +0000 Subject: [PATCH 30/32] fix: trim the self-namespace in the namespace filter Signed-off-by: Dor Serero --- internal/utils/utils.go | 2 +- internal/utils/utils_test.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 8d91663..136ba59 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -54,7 +54,7 @@ func BuildNamespaceFilter(filterNamespaces, selfNamespace string) string { var parts []string exclude := "" - if selfNamespace != "" { + if selfNamespace = strings.TrimSpace(selfNamespace); selfNamespace != "" { exclude = "!" + selfNamespace parts = append(parts, exclude) } diff --git a/internal/utils/utils_test.go b/internal/utils/utils_test.go index fe4715f..aa6b60c 100644 --- a/internal/utils/utils_test.go +++ b/internal/utils/utils_test.go @@ -121,6 +121,7 @@ func TestBuildNamespaceFilter(t *testing.T) { {"no self-exclusion, empty filter means all", "", "", ""}, {"no self-exclusion keeps user filter", "default,kube-system", "", "default,kube-system"}, {"no self-exclusion respects user exclusion", "default,!kube-system", "", "default,!kube-system"}, + {"whitespace self-namespace means no exclusion", "default", " ", "default"}, } for _, tt := range tests { From 19b0e38291f68dddd2606bba60612268b2baa724 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Sat, 4 Jul 2026 04:44:30 +0000 Subject: [PATCH 31/32] fix: ignore empty --filter-image-digest values Signed-off-by: Dor Serero --- cmd/micromize/root.go | 10 +++++++--- cmd/sigward/root.go | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index b1282a8..ce48296 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -168,9 +168,13 @@ func run(ctx context.Context) error { } if filterImageDigest != "" { - digest := strings.TrimPrefix(filterImageDigest, "!") - commonParams["operator.LocalManager.runtime-containerimage-digest"] = "!" + digest - slog.Info("Filtering out containers by image digest", "digest", digest) + digest := strings.TrimSpace(strings.TrimPrefix(filterImageDigest, "!")) + if digest == "" { + slog.Warn("Ignoring --filter-image-digest with an empty digest value", "value", filterImageDigest) + } else { + commonParams["operator.LocalManager.runtime-containerimage-digest"] = "!" + digest + slog.Info("Filtering out containers by image digest", "digest", digest) + } } if !disabled["fs-restrict"] { diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go index bc66986..d8248c5 100644 --- a/cmd/sigward/root.go +++ b/cmd/sigward/root.go @@ -155,9 +155,13 @@ func run(ctx context.Context) error { } if filterImageDigest != "" { - digest := strings.TrimPrefix(filterImageDigest, "!") - commonParams["operator.LocalManager.runtime-containerimage-digest"] = "!" + digest - slog.Info("Filtering out containers by image digest", "digest", digest) + digest := strings.TrimSpace(strings.TrimPrefix(filterImageDigest, "!")) + if digest == "" { + slog.Warn("Ignoring --filter-image-digest with an empty digest value", "value", filterImageDigest) + } else { + commonParams["operator.LocalManager.runtime-containerimage-digest"] = "!" + digest + slog.Info("Filtering out containers by image digest", "digest", digest) + } } registry.Register("sigward", &gadget.GadgetConfig{ From 695c1065d8d76828fc9db88a5e2cf62920c49511 Mon Sep 17 00:00:00 2001 From: Dor Serero Date: Sat, 4 Jul 2026 05:00:20 +0000 Subject: [PATCH 32/32] fix: align gadget image paths under /gadgets/ Signed-off-by: Dor Serero --- Dockerfile.micromize | 4 ++-- Dockerfile.sigward | 4 ++-- Makefile | 12 ++++++------ cmd/micromize/root.go | 8 ++++---- cmd/sigward/root.go | 2 +- docs/running-in-ig.mdx | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Dockerfile.micromize b/Dockerfile.micromize index 39d714a..7514a85 100644 --- a/Dockerfile.micromize +++ b/Dockerfile.micromize @@ -19,10 +19,10 @@ RUN mkdir -p build/gadgets && \ echo "Building gadget: $gadget" && \ ig image build \ --local \ - -t ghcr.io/micromize-dev/micromize/${gadget}:${IMAGE_TAG} \ + -t ghcr.io/micromize-dev/micromize/gadgets/${gadget}:${IMAGE_TAG} \ gadgets/${gadget} && \ ig image export \ - ghcr.io/micromize-dev/micromize/${gadget}:${IMAGE_TAG} \ + ghcr.io/micromize-dev/micromize/gadgets/${gadget}:${IMAGE_TAG} \ build/gadgets/${gadget}.tar; \ done diff --git a/Dockerfile.sigward b/Dockerfile.sigward index abad129..956547f 100644 --- a/Dockerfile.sigward +++ b/Dockerfile.sigward @@ -19,10 +19,10 @@ RUN mkdir -p build/gadgets && \ echo "Building gadget: $gadget" && \ ig image build \ --local \ - -t ghcr.io/micromize-dev/micromize/${gadget}:${IMAGE_TAG} \ + -t ghcr.io/micromize-dev/micromize/gadgets/${gadget}:${IMAGE_TAG} \ gadgets/${gadget} && \ ig image export \ - ghcr.io/micromize-dev/micromize/${gadget}:${IMAGE_TAG} \ + ghcr.io/micromize-dev/micromize/gadgets/${gadget}:${IMAGE_TAG} \ build/gadgets/${gadget}.tar; \ done diff --git a/Makefile b/Makefile index de9f7af..9cda040 100644 --- a/Makefile +++ b/Makefile @@ -60,12 +60,12 @@ build-app: test $(GOARCHS) $(GADGETS): sudo -E IG_SOURCE_PATH=$(CURDIR) ig image build \ - -t $(CONTAINER_REPO)/$@:$(IMAGE_TAG) \ + -t $(CONTAINER_REPO)/gadgets/$@:$(IMAGE_TAG) \ --update-metadata gadgets/$@ mkdir -p build/gadgets - sudo -E ig image export $(CONTAINER_REPO)/$@:$(IMAGE_TAG) build/gadgets/$@.tar + sudo -E ig image export $(CONTAINER_REPO)/gadgets/$@:$(IMAGE_TAG) build/gadgets/$@.tar $(GOARCHS): @mkdir -p $(OUTPUT_DIR) @@ -88,20 +88,20 @@ $(GOARCHS): .PHONY: run-fs-restrict run-fs-restrict: - sudo -E ig run $(CONTAINER_REPO)/fs-restrict:$(IMAGE_TAG) $$PARAMS + sudo -E ig run $(CONTAINER_REPO)/gadgets/fs-restrict:$(IMAGE_TAG) $$PARAMS .PHONY: run-cap-restrict run-cap-restrict: - sudo -E ig run $(CONTAINER_REPO)/cap-restrict:$(IMAGE_TAG) $$PARAMS + sudo -E ig run $(CONTAINER_REPO)/gadgets/cap-restrict:$(IMAGE_TAG) $$PARAMS .PHONY: run-socket-restrict run-socket-restrict: - sudo -E ig run $(CONTAINER_REPO)/socket-restrict:$(IMAGE_TAG) $$PARAMS + sudo -E ig run $(CONTAINER_REPO)/gadgets/socket-restrict:$(IMAGE_TAG) $$PARAMS .PHONY: push push: for gadget in $(GADGETS); do \ - sudo -E ig image push $(CONTAINER_REPO)/$$gadget:$(IMAGE_TAG); \ + sudo -E ig image push $(CONTAINER_REPO)/gadgets/$$gadget:$(IMAGE_TAG); \ done .PHONY: clang-format diff --git a/cmd/micromize/root.go b/cmd/micromize/root.go index ce48296..5b89ca6 100644 --- a/cmd/micromize/root.go +++ b/cmd/micromize/root.go @@ -35,10 +35,10 @@ import ( ) const ( - fsRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/fs-restrict" - capRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/cap-restrict" - ptraceRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/ptrace-restrict" - socketRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/socket-restrict" + fsRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/gadgets/fs-restrict" + capRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/gadgets/cap-restrict" + ptraceRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/gadgets/ptrace-restrict" + socketRestrictGadgetImageRepo = "ghcr.io/micromize-dev/micromize/gadgets/socket-restrict" ) var ( diff --git a/cmd/sigward/root.go b/cmd/sigward/root.go index d8248c5..a364708 100644 --- a/cmd/sigward/root.go +++ b/cmd/sigward/root.go @@ -35,7 +35,7 @@ import ( "github.com/micromize-dev/micromize/internal/utils" ) -const sigwardGadgetImageRepo = "ghcr.io/micromize-dev/micromize/sigward" +const sigwardGadgetImageRepo = "ghcr.io/micromize-dev/micromize/gadgets/sigward" var ( enforce bool diff --git a/docs/running-in-ig.mdx b/docs/running-in-ig.mdx index 436643d..201df1c 100644 --- a/docs/running-in-ig.mdx +++ b/docs/running-in-ig.mdx @@ -45,7 +45,7 @@ Once built (or if you want to run from the registry), you can use `ig run` or `k If you built the gadget locally, you can run it by referencing the image tag you used. ```bash -sudo ig run ghcr.io/micromize-dev/micromize/cap-restrict:latest --verify-image=false +sudo ig run ghcr.io/micromize-dev/micromize/gadgets/cap-restrict:latest --verify-image=false ``` ### Running from Registry @@ -53,7 +53,7 @@ sudo ig run ghcr.io/micromize-dev/micromize/cap-restrict:latest --verify-image=f You can also run the gadgets directly from the container registry: ```bash -sudo ig run ghcr.io/micromize-dev/micromize/cap-restrict:latest +sudo ig run ghcr.io/micromize-dev/micromize/gadgets/cap-restrict:latest ``` ### Configuration Parameters @@ -67,7 +67,7 @@ All gadgets support the following parameters: **Run in Audit Mode (Log only):** ```bash -sudo ig run ghcr.io/micromize-dev/micromize/cap-restrict:latest --enforce=false +sudo ig run ghcr.io/micromize-dev/micromize/gadgets/cap-restrict:latest --enforce=false ``` ## Available Gadgets