Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 87 additions & 2 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,62 @@ jobs:
with:
go-version: '1.21'

- name: Cache Go modules
uses: actions/cache@v4
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-1.21-${{ hashFiles('**/go.sum') }}

- name: Download dependencies
run: go mod download

- name: Run go vet
run: go vet ./...

- name: Install gosec
run: |
go install github.com/securego/gosec/v2/cmd/gosec@latest
gosec --version

- name: Run gosec security scan
run: |
# Run gosec with configuration file and multiple output formats
gosec -conf .gosec.json -fmt sarif -out gosec-results.sarif ./...
gosec -conf .gosec.json -fmt json -out gosec-results.json ./...
gosec -conf .gosec.json -fmt text -out gosec-results.txt ./...

# Display results in CI log
echo "=== GOSEC SECURITY SCAN RESULTS ==="
gosec -conf .gosec.json ./...

# Check if any HIGH or MEDIUM severity issues found
if gosec -conf .gosec.json -fmt json ./... | jq -r '.Issues[]? | select(.severity == "HIGH" or .severity == "MEDIUM") | .severity' | grep -q "HIGH\|MEDIUM"; then
Comment on lines +268 to +278
Copy link

Copilot AI Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The workflow runs gosec multiple times (SARIF, JSON, text, and log). This repeats analysis and increases CI runtime; consider running it once and converting or splitting outputs from a single report.

Suggested change
# Run gosec with configuration file and multiple output formats
gosec -conf .gosec.json -fmt sarif -out gosec-results.sarif ./...
gosec -conf .gosec.json -fmt json -out gosec-results.json ./...
gosec -conf .gosec.json -fmt text -out gosec-results.txt ./...
# Display results in CI log
echo "=== GOSEC SECURITY SCAN RESULTS ==="
gosec -conf .gosec.json ./...
# Check if any HIGH or MEDIUM severity issues found
if gosec -conf .gosec.json -fmt json ./... | jq -r '.Issues[]? | select(.severity == "HIGH" or .severity == "MEDIUM") | .severity' | grep -q "HIGH\|MEDIUM"; then
# Run gosec once and output results in JSON format
gosec -conf .gosec.json -fmt json -out gosec-results.json ./...
# Convert JSON output to SARIF format
jq '{"version": "2.1.0", "runs": [.]} | .runs[0].results = (.runs[0].results // [])' gosec-results.json > gosec-results.sarif
# Convert JSON output to text format
jq -r '.Issues[] | "\(.severity): \(.details) [\(.file):\(.line)]"' gosec-results.json > gosec-results.txt
# Display results in CI log
echo "=== GOSEC SECURITY SCAN RESULTS ==="
cat gosec-results.txt
# Check if any HIGH or MEDIUM severity issues found
if jq -r '.Issues[]? | select(.severity == "HIGH" or .severity == "MEDIUM") | .severity' gosec-results.json | grep -q "HIGH\|MEDIUM"; then

Copilot uses AI. Check for mistakes.
echo "WARNING: HIGH or MEDIUM severity security issues found!"
echo "Please review the gosec results."
else
echo "✅ No HIGH or MEDIUM severity security issues found"
fi
continue-on-error: true

- name: Upload gosec SARIF results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: gosec-results.sarif
category: gosec
continue-on-error: true

- name: Upload gosec security artifacts
uses: actions/upload-artifact@v4
with:
name: gosec-security-results
path: |
gosec-results.sarif
gosec-results.json
gosec-results.txt
continue-on-error: true

# Coverage aggregation job
coverage:
name: Coverage Report
Expand Down Expand Up @@ -359,7 +412,7 @@ jobs:
test-reports:
name: Test Reports
runs-on: ubuntu-latest
needs: [unit-tests, n-node-tests, benchmark-tests]
needs: [unit-tests, n-node-tests, benchmark-tests, security]

steps:
- name: Checkout code
Expand All @@ -371,17 +424,36 @@ jobs:
pattern: "*test*"
merge-multiple: true

- name: Download security scan results
uses: actions/download-artifact@v4
with:
name: gosec-security-results
continue-on-error: true

- name: Generate test report
run: |
echo "# Pickbox Test Report - $(date)" > test-report.md
echo "## Test Summary" >> test-report.md
echo "- Unit Tests: ✅ Completed" >> test-report.md
echo "- N-Node Tests: ✅ Completed (3 categories)" >> test-report.md
echo "- Benchmark Tests: ✅ Completed" >> test-report.md
echo "- Security Scan: ✅ Completed" >> test-report.md
echo "" >> test-report.md
echo "## Coverage Reports" >> test-report.md
echo "Coverage reports available in artifacts" >> test-report.md
echo "" >> test-report.md
echo "## Security Scan Results" >> test-report.md
if [ -f "gosec-results.txt" ]; then
echo "### Gosec Security Scan" >> test-report.md
echo '```' >> test-report.md
head -50 gosec-results.txt >> test-report.md
echo '```' >> test-report.md
echo "" >> test-report.md
echo "Full security scan results available in artifacts" >> test-report.md
else
echo "Security scan results not available" >> test-report.md
fi
echo "" >> test-report.md
echo "## Benchmark Results" >> test-report.md
if [ -f "package-bench-results.txt" ]; then
echo "### Package Benchmarks" >> test-report.md
Expand Down Expand Up @@ -431,6 +503,12 @@ jobs:
with:
name: test-report

- name: Download security scan results
uses: actions/download-artifact@v4
with:
name: gosec-security-results
continue-on-error: true

- name: Get version from git tag
id: version
run: |
Expand All @@ -448,6 +526,8 @@ jobs:
bin/*
coverage.html
test-report.md
gosec-results.txt
gosec-results.json
body: |
## Pickbox Distributed Storage System ${{ steps.version.outputs.version }}

Expand All @@ -462,7 +542,12 @@ jobs:
- ✅ Unit Tests: All package tests passed
- ✅ N-Node Tests: 3 test categories completed
- ✅ Benchmark Tests: Performance benchmarks completed
- ✅ Security Scan: No critical issues found
- ✅ Security Scan: Gosec security analysis completed

### Security
- Static analysis with gosec (Go Security Checker)
- SARIF results uploaded to GitHub Security tab
- Comprehensive security scan results available in artifacts

### Downloads
- **Linux AMD64**: `multi_replication-linux-amd64`
Expand Down
34 changes: 33 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,36 @@
/bin
coverage.out
coverage.html
gosec.sarif
gosec.sarif
gosec-results.*

# Security and secrets
.env
.env.*
!.env.example
*.pem
*.key
*.p12
*.pfx
secrets.yml
secrets.yaml
credentials.json
config.json
.aws/
.gcp/
.azure/

# IDE and editor files
.idea/
*.swp
*.swo
*~

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
175 changes: 175 additions & 0 deletions .gosec.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
{
"global": {
"nosec": "enabled",
"audit": "enabled",
"confidence": "low",
"severity": "low",
"quiet": false,
"verbose": "text",
Copy link

Copilot AI Jul 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The verbose key is not recognized in gosec's configuration schema. Consider removing it or using the --verbose CLI flag instead.

Suggested change
"verbose": "text",

Copilot uses AI. Check for mistakes.
"output": "stdout",
"log": "stderr",
"format": "text",
"color": true
},
"rules": {
"G101": {
"mode": "enabled",
"level": "error",
"description": "Look for hard coded credentials"
},
"G102": {
"mode": "enabled",
"level": "error",
"description": "Bind to all interfaces"
},
"G103": {
"mode": "enabled",
"level": "error",
"description": "Audit the use of unsafe block"
},
"G104": {
"mode": "enabled",
"level": "warning",
"description": "Audit errors not checked"
},
"G105": {
"mode": "enabled",
"level": "error",
"description": "Audit the use of big.Exp function"
},
"G106": {
"mode": "enabled",
"level": "error",
"description": "Audit the use of ssh.InsecureIgnoreHostKey"
},
"G107": {
"mode": "enabled",
"level": "error",
"description": "Url provided to HTTP request as taint input"
},
"G108": {
"mode": "enabled",
"level": "error",
"description": "Profiling endpoint automatically exposed on /debug/pprof"
},
"G109": {
"mode": "enabled",
"level": "error",
"description": "Potential integer overflow when converting to string"
},
"G110": {
"mode": "enabled",
"level": "error",
"description": "Potential DoS vulnerability via decompression bomb"
},
"G201": {
"mode": "enabled",
"level": "error",
"description": "SQL query construction using format string"
},
"G202": {
"mode": "enabled",
"level": "error",
"description": "SQL query construction using string concatenation"
},
"G203": {
"mode": "enabled",
"level": "error",
"description": "Use of unescaped data in HTML templates"
},
"G204": {
"mode": "enabled",
"level": "error",
"description": "Audit use of command execution"
},
"G301": {
"mode": "enabled",
"level": "warning",
"description": "Poor file permissions used when creating a directory"
},
"G302": {
"mode": "enabled",
"level": "warning",
"description": "Poor file permissions used when creation file or using chmod"
},
"G303": {
"mode": "enabled",
"level": "warning",
"description": "Creating tempfile using a predictable path"
},
"G304": {
"mode": "enabled",
"level": "error",
"description": "File path provided as taint input"
},
"G305": {
"mode": "enabled",
"level": "error",
"description": "File traversal when extracting zip archive"
},
"G306": {
"mode": "enabled",
"level": "warning",
"description": "Poor file permissions used when writing to a file"
},
"G307": {
"mode": "enabled",
"level": "error",
"description": "Deferring a method which returns an error"
},
"G401": {
"mode": "enabled",
"level": "error",
"description": "Detect the usage of DES, RC4, MD5 or SHA1"
},
"G402": {
"mode": "enabled",
"level": "error",
"description": "Look for bad TLS connection settings"
},
"G403": {
"mode": "enabled",
"level": "error",
"description": "Ensure minimum RSA key length of 2048 bits"
},
"G404": {
"mode": "enabled",
"level": "error",
"description": "Insecure random number source (rand)"
},
"G501": {
"mode": "enabled",
"level": "error",
"description": "Import blacklist: crypto/md5"
},
"G502": {
"mode": "enabled",
"level": "error",
"description": "Import blacklist: crypto/des"
},
"G503": {
"mode": "enabled",
"level": "error",
"description": "Import blacklist: crypto/rc4"
},
"G504": {
"mode": "enabled",
"level": "error",
"description": "Import blacklist: net/http/cgi"
},
"G505": {
"mode": "enabled",
"level": "error",
"description": "Import blacklist: crypto/sha1"
},
"G601": {
"mode": "enabled",
"level": "error",
"description": "Implicit memory aliasing of items from a range statement"
}
},
"exclude": [
"test/*.go",
"*_test.go"
]
}
Loading