Skip to content

Commit c6e5d51

Browse files
committed
Merge branch 'master' into docs
2 parents b6e7126 + f0f5200 commit c6e5d51

File tree

2,161 files changed

+1107803
-11762
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,161 files changed

+1107803
-11762
lines changed

.github/workflows/package.yml

+43-19
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,26 @@ jobs:
1818
steps:
1919
- name: Checkout code
2020
uses: actions/checkout@v4
21+
with:
22+
fetch-depth: 0 # Fetch all history for all tags and branches
2123

2224
- name: Setup Go
2325
uses: actions/setup-go@v4
2426
with:
2527
go-version-file: go.mod
2628

27-
- name: Fetch Tags
29+
- name: Get latest tag
2830
run: |
29-
git fetch --tags -f
30-
TAG=$(git describe --tags --always)
31-
VERSION=${TAG#v}
31+
# Try to get tag for the current commit
32+
CURRENT_TAG=$(git describe --exact-match --tags HEAD 2>/dev/null || echo "")
33+
34+
# If no tag for current commit, get the most recent tag
35+
if [ -z "$CURRENT_TAG" ]; then
36+
CURRENT_TAG=$(git describe --tags --abbrev=0)
37+
fi
38+
39+
# Remove 'v' prefix if present
40+
VERSION=${CURRENT_TAG#v}
3241
echo "VERSION=$VERSION" >> $GITHUB_ENV
3342
3443
- name: Get dependencies
@@ -39,11 +48,10 @@ jobs:
3948
dep ensure
4049
fi
4150
42-
- name: Update
43-
run: sudo apt-get update -y
44-
45-
- name: Make all release artifacts
46-
run: make build-all
51+
- name: Build binaries
52+
run: |
53+
make build-linux/amd64
54+
make build-linux/arm64
4755
4856
- name: Set up QEMU
4957
uses: docker/setup-qemu-action@v2
@@ -66,19 +74,35 @@ jobs:
6674

6775
- name: Build and push Docker images
6876
run: |
69-
PLATFORMS=(linux/amd64 linux/arm linux/arm64)
77+
PLATFORMS=(linux/amd64 linux/arm64)
7078
for platform in "${PLATFORMS[@]}"; do
79+
make docker-build-$platform
80+
7181
os=$(echo $platform | cut -d'/' -f1)
7282
arch=$(echo $platform | cut -d'/' -f2)
7383
74-
docker buildx build --platform $platform \
75-
--build-arg BINARY=release/intercept-$os-$arch \
76-
-t xfhg/intercept:${{ env.VERSION }}-$os-$arch \
77-
-t xfhg/intercept:latest-$os-$arch \
78-
-t ghcr.io/${{ github.repository }}:${{ env.VERSION }}-$os-$arch \
79-
-t ghcr.io/${{ github.repository }}:latest-$os-$arch \
80-
--push \
81-
.
84+
docker tag test/intercept:$os-$arch xfhg/intercept:${{ env.VERSION }}-$os-$arch
85+
docker tag test/intercept:$os-$arch xfhg/intercept:latest-$os-$arch
86+
docker tag test/intercept:$os-$arch ghcr.io/${{ github.repository }}:${{ env.VERSION }}-$os-$arch
87+
docker tag test/intercept:$os-$arch ghcr.io/${{ github.repository }}:latest-$os-$arch
88+
89+
docker push xfhg/intercept:${{ env.VERSION }}-$os-$arch
90+
docker push xfhg/intercept:latest-$os-$arch
91+
docker push ghcr.io/${{ github.repository }}:${{ env.VERSION }}-$os-$arch
92+
docker push ghcr.io/${{ github.repository }}:latest-$os-$arch
8293
done
8394
84-
95+
- name: Create multi-arch manifests
96+
run: |
97+
# Create and push multi-arch manifest for DockerHub
98+
docker manifest create xfhg/intercept:latest \
99+
xfhg/intercept:latest-linux-amd64 \
100+
xfhg/intercept:latest-linux-arm64
101+
docker manifest push xfhg/intercept:latest
102+
103+
# Create and push multi-arch manifest for GitHub Container Registry
104+
docker manifest create ghcr.io/${{ github.repository }}:latest \
105+
ghcr.io/${{ github.repository }}:latest-linux-amd64 \
106+
ghcr.io/${{ github.repository }}:latest-linux-arm64
107+
docker manifest push ghcr.io/${{ github.repository }}:latest
108+

.github/workflows/release.yml

+20-8
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,26 @@ jobs:
1919

2020
- name: Check out code
2121
uses: actions/checkout@v4
22+
with:
23+
fetch-depth: 0 # Fetch all history for all tags and branches
2224

2325
- uses: actions/setup-go@v4
2426
with:
2527
go-version-file: go.mod
2628

29+
- name: Get latest tag
30+
id: get_latest_tag
31+
run: |
32+
# Try to get tag for the current commit
33+
CURRENT_TAG=$(git describe --exact-match --tags HEAD 2>/dev/null || echo "")
34+
35+
# If no tag for current commit, get the most recent tag
36+
if [ -z "$CURRENT_TAG" ]; then
37+
CURRENT_TAG=$(git describe --tags --abbrev=0)
38+
fi
39+
40+
echo "LATEST_TAG=${CURRENT_TAG}" >> $GITHUB_OUTPUT
41+
2742
- name: Fetch Tags
2843
run: |
2944
git fetch --tags -f
@@ -40,19 +55,16 @@ jobs:
4055
- name: Make all release artifacts
4156
run: make build-all
4257

43-
- name: Get the version
44-
id: get_version
45-
run: echo ::set-output name=VERSION::${GITHUB_REF/refs\/tags\//}
46-
4758
- name: Upload All artifacts
4859
uses: meeDamian/[email protected]
4960
with:
61+
tag: ${{ steps.get_latest_tag.outputs.LATEST_TAG }}
5062
allow_override: "true"
5163
draft: "true"
5264
token: ${{ secrets.GITHUB_TOKEN }}
53-
name: ${{ steps.get_version.outputs.VERSION }}
65+
name: ${{ steps.get_latest_tag.outputs.LATEST_TAG }}
5466
body: >
55-
Release ${{ steps.get_version.outputs.VERSION }}
67+
Release ${{ steps.get_latest_tag.outputs.LATEST_TAG }}
5668
gzip: "true"
5769
files: >
5870
release/intercept-darwin-amd64
@@ -61,8 +73,8 @@ jobs:
6173
release/intercept-darwin-arm64.sha256
6274
release/intercept-linux-amd64
6375
release/intercept-linux-amd64.sha256
64-
release/intercept-linux-arm
65-
release/intercept-linux-arm.sha256
76+
release/intercept-linux-arm-v7
77+
release/intercept-linux-arm-v7.sha256
6678
release/intercept-linux-arm64
6779
release/intercept-linux-arm64.sha256
6880
release/intercept-windows-amd64.exe

Makefile

+45-31
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,26 @@ BINARY_NAME=intercept
55
GIT_TAG := $(shell git describe --tags --abbrev=0 2>/dev/null || echo "v1.0.X")
66
GIT_COMMIT := $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
77

8-
9-
108
# Go parameters
119
GOCMD=go
1210
GOBUILD=$(GOCMD) build
1311
GOCLEAN=$(GOCMD) clean
1412
GOTEST=$(GOCMD) test
1513

1614
# Build flags
17-
# LDFLAGS=-ldflags="-s -w"
18-
# BUILD_FLAGS=-mod=readonly $(LDFLAGS)
19-
20-
BUILD_FLAGS=-mod=readonly -ldflags="-s -w -X intercept/cmd.buildVersion=$(GIT_TAG)-$(GIT_COMMIT)"
15+
BUILD_FLAGS=-mod=readonly -ldflags="-s -w -X intercept/cmd.buildVersion=$(GIT_TAG)-$(GIT_COMMIT)"
2116

2217
# All compilation platforms
23-
ALL_PLATFORMS=darwin/amd64 darwin/arm64 linux/amd64 linux/arm linux/arm64 windows/amd64
18+
PLATFORMS := \
19+
darwin/amd64 \
20+
darwin/arm64 \
21+
windows/amd64 \
22+
linux/amd64 \
23+
linux/arm64 \
24+
linux/arm/v7
2425

2526
# Docker build platforms
26-
DOCKER_PLATFORMS=linux/amd64 linux/arm linux/arm64
27+
DOCKER_PLATFORMS := linux/amd64 linux/arm64
2728

2829
# Docker image name
2930
DOCKER_IMAGE=test/intercept
@@ -34,7 +35,7 @@ all: clean build-all
3435
# Clean
3536
clean:
3637
$(GOCLEAN)
37-
rm -f release/$(BINARY_NAME)*
38+
rm -rf release/$(BINARY_NAME)*
3839

3940
# Run tests
4041
test:
@@ -46,46 +47,59 @@ build: clean
4647

4748
# Compress binary using UPX
4849
compress-binary:
49-
- docker run --rm -w $(shell pwd) -v $(shell pwd):$(shell pwd) xfhg/upx:latest -9 release/$(BINARY_NAME)
50+
- docker run --rm -v $(shell pwd):/workspace -w /workspace docker.io/xfhg/upx:latest -9 release/$(BINARY_NAME)
5051

51-
#Checksums
52+
# Checksums
5253
sha256sums:
53-
@for file in release/*; do \
54+
@for file in release/$(BINARY_NAME)*; do \
5455
echo "Generating SHA256 for $$file"; \
5556
sha256sum "$$file" > "$$file.sha256"; \
5657
done
5758

5859
# Build for all platforms
59-
build-all: clean $(ALL_PLATFORMS) sha256sums
60+
build-all: clean $(PLATFORMS) sha256sums
6061

6162
define BUILD_PLATFORM
62-
build-$(1)-$(2):
63-
CGO_ENABLED=0 GOOS=$(1) GOARCH=$(2) $(GOBUILD) $(BUILD_FLAGS) -o release/$(BINARY_NAME)-$(1)-$(2)$(if $(filter windows,$(1)),.exe,) .
64-
$(MAKE) compress-binary BINARY_NAME=$(BINARY_NAME)-$(1)-$(2)$(if $(filter windows,$(1)),.exe,)
65-
66-
.PHONY: build-$(1)-$(2)
63+
build-$(1):
64+
@echo "Building for platform $(1)"
65+
$(eval GOOS := $(word 1, $(subst /, ,$(1))))
66+
$(eval GOARCH := $(word 2, $(subst /, ,$(1))))
67+
$(eval GOARM := $(word 3, $(subst /, ,$(1))))
68+
$(eval BIN_SUFFIX := $(if $(GOARM),-$(GOARM),))
69+
$(eval OUTPUT_NAME := $(BINARY_NAME)-$(GOOS)-$(GOARCH)$(BIN_SUFFIX)$(if $(filter windows,$(GOOS)),.exe,))
70+
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) $(if $(GOARM),GOARM=$(GOARM),) \
71+
$(GOBUILD) $(BUILD_FLAGS) -o release/$(OUTPUT_NAME) .
72+
$(MAKE) compress-binary BINARY_NAME=$(OUTPUT_NAME)
73+
.PHONY: build-$(1)
6774
endef
6875

69-
$(foreach platform,$(ALL_PLATFORMS),$(eval $(call BUILD_PLATFORM,$(word 1,$(subst /, ,$(platform))),$(word 2,$(subst /, ,$(platform))))))
76+
$(foreach platform,$(PLATFORMS),$(eval $(call BUILD_PLATFORM,$(platform))))
7077

71-
$(ALL_PLATFORMS):
72-
$(MAKE) build-$(word 1,$(subst /, ,$@))-$(word 2,$(subst /, ,$@))
78+
$(PLATFORMS):
79+
$(MAKE) build-$@
7380

7481
# Docker build commands for specific platforms
7582
define DOCKER_BUILD_PLATFORM
76-
docker-build-$(1)-$(2): build-$(1)-$(2)
77-
docker buildx build --platform $(1)/$(2) \
78-
--build-arg BINARY=release/$(BINARY_NAME)-$(1)-$(2) \
79-
-t $(DOCKER_IMAGE):$(1)-$(2) \
83+
docker-build-$(1):
84+
$(eval GOOS := $(word 1, $(subst /, ,$(1))))
85+
$(eval GOARCH := $(word 2, $(subst /, ,$(1))))
86+
$(eval GOARM := $(word 3, $(subst /, ,$(1))))
87+
$(eval BIN_SUFFIX := $(if $(GOARM),-v$(GOARM),))
88+
$(eval OUTPUT_NAME := $(BINARY_NAME)-$(GOOS)-$(GOARCH)$(BIN_SUFFIX)$(if $(filter windows,$(GOOS)),.exe,))
89+
CGO_ENABLED=0 GOOS=$(GOOS) GOARCH=$(GOARCH) $(if $(GOARM),GOARM=$(GOARM),) \
90+
$(GOBUILD) $(BUILD_FLAGS) -tags container -o release/$(OUTPUT_NAME) .
91+
$(MAKE) compress-binary BINARY_NAME=$(OUTPUT_NAME)
92+
docker buildx build --platform $(GOOS)/$(GOARCH)$(if $(GOARM),/v$(GOARM),) \
93+
--build-arg BINARY=release/$(OUTPUT_NAME) \
94+
-t $(DOCKER_IMAGE):$(GOOS)-$(GOARCH)$(BIN_SUFFIX) \
8095
--load \
8196
.
82-
83-
.PHONY: docker-build-$(1)-$(2)
97+
.PHONY: docker-build-$(1)
8498
endef
8599

86-
$(foreach platform,$(DOCKER_PLATFORMS),$(eval $(call DOCKER_BUILD_PLATFORM,$(word 1,$(subst /, ,$(platform))),$(word 2,$(subst /, ,$(platform))))))
100+
$(foreach platform,$(DOCKER_PLATFORMS),$(eval $(call DOCKER_BUILD_PLATFORM,$(platform))))
87101

88-
# Build Docker images for all specified Linux platforms
89-
docker-build-all: $(foreach platform,$(DOCKER_PLATFORMS),docker-build-$(word 1,$(subst /, ,$(platform)))-$(word 2,$(subst /, ,$(platform))))
102+
# Build Docker images for all specified platforms
103+
docker-build-all: $(foreach platform,$(DOCKER_PLATFORMS),docker-build-$(platform))
90104

91-
.PHONY: all clean build build-all test docker-build-all compress-binary $(ALL_PLATFORMS) sha256sums
105+
.PHONY: all clean build build-all compress-binary docker-build-all $(PLATFORMS) sha256sums

cmd/api.go

+51-10
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ func ProcessAPIType(policy Policy, rgPath string) error {
2121
req := client.R()
2222

2323
req.SetHeader("Content-Type", policy.API.ResponseType)
24-
req.SetHeader("User-Agent", "Intercept/v1.0.0")
24+
req.SetHeader("User-Agent", "INTERCEPT/v1.0.X")
2525

2626
// Apply authentication
2727
if err := applyAuth(req, policy.API.Auth); err != nil {
2828
log.Error().Err(err).Msg("error applying authentication")
29-
return fmt.Errorf("error applying authentication: %w", err)
29+
return handlePolicyError(policy, fmt.Errorf("error applying authentication: %w", err))
3030
}
3131

3232
// Set request body if method is POST
@@ -38,7 +38,8 @@ func ProcessAPIType(policy Policy, rgPath string) error {
3838
resp, err := req.Execute(policy.API.Method, policy.API.Endpoint)
3939
if err != nil {
4040
log.Error().Err(err).Msg("error making API request")
41-
return fmt.Errorf("error making API request: %w", err)
41+
return handlePolicyError(policy, fmt.Errorf("error making API request: %w", err))
42+
4243
}
4344

4445
// check for accepted policy.API.ResponseType and map to schema type is defined , or use regex
@@ -50,7 +51,7 @@ func ProcessAPIType(policy Policy, rgPath string) error {
5051
return processWithRegex(policy, resp.Body(), rgPath)
5152
}
5253

53-
return fmt.Errorf("no processing method specified for policy %s", policy.ID)
54+
return handlePolicyError(policy, fmt.Errorf("no processing method specified for policy %s", policy.ID))
5455
}
5556

5657
func applyAuth(req *resty.Request, auth map[string]string) error {
@@ -67,9 +68,12 @@ func applyAuth(req *resty.Request, auth map[string]string) error {
6768
case "bearer":
6869
token := os.Getenv(auth["token_env"])
6970
req.SetHeader("Authorization", "Bearer "+token)
70-
case "api_key":
71+
case "header":
7172
key := os.Getenv(auth["key_env"])
7273
req.SetHeader(auth["header"], key)
74+
case "authorization":
75+
key := fmt.Sprintf("%s %s", auth["prefix"], os.Getenv(auth["key_env"]))
76+
req.SetHeader("Authorization", key)
7377
default:
7478
return fmt.Errorf("unsupported authentication type: %s", authType)
7579
}
@@ -78,7 +82,7 @@ func applyAuth(req *resty.Request, auth map[string]string) error {
7882
}
7983

8084
func processWithCUE(policy Policy, data []byte) error {
81-
valid, issues := validateContentAndCUE(data, policy.Schema.Structure, "json", policy.Schema.Strict)
85+
valid, issues := validateContentAndCUE(data, policy.Schema.Structure, "json", policy.Schema.Strict, policy.ID)
8286

8387
// Generate SARIF report
8488
sarifReport, err := GenerateAPISARIFReport(policy, policy.API.Endpoint, valid, issues)
@@ -152,12 +156,25 @@ func processWithRegex(policy Policy, data []byte, rgPath string) error {
152156
}
153157

154158
// Write SARIF report
155-
err = writeSARIFReport(policy.ID, sarifReport)
156-
if err != nil {
157-
log.Error().Err(err).Msg("error writing SARIF report for policy %s")
158-
return fmt.Errorf("error writing SARIF report for policy %s: %w", policy.ID, err)
159+
var sarifOutputFile string
160+
161+
if policy.RunID != "" {
162+
if err := writeSARIFReport(policy.RunID, sarifReport); err != nil {
163+
log.Error().Err(err).Msg("error writing SARIF report")
164+
return fmt.Errorf("error writing SARIF report: %w", err)
165+
}
166+
sarifOutputFile = fmt.Sprintf("%s.sarif", policy.RunID)
167+
} else {
168+
if err := writeSARIFReport(policy.ID, sarifReport); err != nil {
169+
log.Error().Err(err).Msg("error writing SARIF report")
170+
return fmt.Errorf("error writing SARIF report: %w", err)
171+
}
172+
sarifOutputFile = fmt.Sprintf("%s.sarif", NormalizeFilename(policy.ID))
173+
159174
}
160175

176+
log.Debug().Msgf("Policy %s processed. SARIF report written to: %s ", policy.ID, sarifOutputFile)
177+
161178
if matchesFound {
162179
log.Debug().Msgf("Policy %s assurance passed for API response (pattern found) ", policy.ID)
163180
} else {
@@ -207,3 +224,27 @@ func executeAssureForAPI(policy Policy, rgPath, filePath string) (bool, error) {
207224

208225
return matchesFound, nil
209226
}
227+
228+
func handlePolicyError(policy Policy, err error) error {
229+
issues := []string{err.Error()}
230+
sarifReport, sarifErr := GenerateAPISARIFReport(policy, policy.API.Endpoint, false, issues)
231+
if sarifErr != nil {
232+
log.Error().Err(sarifErr).Msg("error generating SARIF report for policy error")
233+
return fmt.Errorf("error generating SARIF report for policy error: %w", sarifErr)
234+
}
235+
236+
var sarifOutputFile string
237+
if policy.RunID != "" {
238+
sarifOutputFile = fmt.Sprintf("%s.sarif", policy.RunID)
239+
} else {
240+
sarifOutputFile = fmt.Sprintf("%s.sarif", NormalizeFilename(policy.ID))
241+
}
242+
243+
if writeErr := writeSARIFReport(sarifOutputFile, sarifReport); writeErr != nil {
244+
log.Error().Err(writeErr).Msg("error writing SARIF report for policy error")
245+
return fmt.Errorf("error writing SARIF report for policy error: %w", writeErr)
246+
}
247+
248+
log.Debug().Msgf("Policy %s failed. SARIF report written to: %s", policy.ID, sarifOutputFile)
249+
return err
250+
}

0 commit comments

Comments
 (0)