Skip to content

Commit 1439ce1

Browse files
feat(security): OpenSSF Best Practices + Scorecard scaffolding (RAN-53) (#34)
Lands the OpenSSF Best Practices + Scorecard hardening for otelcontext. - Hard gate: bestpractices.dev `passing` badge (project 12646) - Stretch target: Scorecard ≥ 8.0/10 (observational, non-blocking) - Six-job OSS-CLI security stack: OSV-Scanner, Trivy, Semgrep, Gitleaks, jscpd, SBOM - Scorecard workflow + Dependabot config + SECURITY.md + signed-commits helper - Closes RAN-53 Required checks green: `build · vet · test` + required signatures. SonarCloud `UNSTABLE` is cosmetic — not in the required-status-checks set on `main`. Co-Authored-By: Paperclip <noreply@paperclip.ing>
1 parent 4e0a4a2 commit 1439ce1

11 files changed

Lines changed: 716 additions & 38 deletions

File tree

.bestpractices.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"$schema": "https://bestpractices.coreinfrastructure.org/projects.schema.json",
3+
"_comment": "OpenSSF Best Practices self-assessment for RandomCodeSpace/otelcontext (RAN-53). Project page: https://www.bestpractices.dev/en/projects/12646. The badge level transition from in_progress -> passing requires a board admin to log into bestpractices.dev with the OSS-Random identity and confirm the evidence pointers against the questionnaire. The self-assessment below is the evidence map for that review.",
4+
"project_id": 12646,
5+
"name": "otelcontext",
6+
"description": "Self-hosted OTLP observability platform in a single Go binary — OTLP gRPC + HTTP ingest, GraphRAG-powered root-cause analysis, multi-tenant storage, and a built-in MCP server for AI agents.",
7+
"homepage_url": "https://github.com/RandomCodeSpace/otelcontext",
8+
"repo_url": "https://github.com/RandomCodeSpace/otelcontext",
9+
"license": "MIT",
10+
"level": "passing",
11+
"status": {
12+
"basics": "self-assessed-passing",
13+
"change_control": "self-assessed-passing",
14+
"reporting": "self-assessed-passing",
15+
"quality": "self-assessed-passing",
16+
"security": "self-assessed-passing",
17+
"analysis": "self-assessed-passing"
18+
},
19+
"evidence": {
20+
"vulnerability_report_process": "SECURITY.md",
21+
"engineering_standards": "CLAUDE.md",
22+
"license_file": "LICENSE.md",
23+
"build_reproducible": "go build -o otelcontext .",
24+
"ci_workflow": ".github/workflows/ci.yml",
25+
"supply_chain_scorecard": ".github/workflows/scorecard.yml",
26+
"dependency_updates": ".github/dependabot.yml",
27+
"signed_commits": "scripts/setup-git-signed.sh",
28+
"secret_scanning": ".github/workflows/security.yml (gitleaks job, full git history) + GitHub repo setting (secret_scanning + push_protection enabled — escalated to board)",
29+
"static_analysis": "golangci-lint (.golangci.yml) + Semgrep (.github/workflows/security.yml, p/security-audit + p/owasp-top-ten + p/golang)",
30+
"vulnerability_scanning": "OSV-Scanner (go.mod + ui/package-lock.json) + Trivy (filesystem) + Dependabot (.github/dependabot.yml)",
31+
"sbom": ".github/workflows/security.yml (anchore/sbom-action — SPDX + CycloneDX, 90-day artifact retention)",
32+
"duplication": ".github/workflows/security.yml (jscpd, threshold 3%, scoped to internal/ + ui/src/)"
33+
},
34+
"audit": {
35+
"self_assessment_date": "2026-04-26",
36+
"self_assessment_author": "TechLead (RAN-53)",
37+
"registration_blocker": "Badge promotion in_progress -> passing requires board admin OAuth at https://www.bestpractices.dev/. Tracked under RAN-53 acceptance item #1."
38+
}
39+
}

.github/dependabot.yml

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
# Dependabot configuration for otelcontext.
2+
# Docs: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
3+
#
4+
# Strategy:
5+
# * weekly cadence — keeps the noise floor low while still catching CVEs early
6+
# * grouped updates per ecosystem so PR fan-out stays manageable
7+
# * security updates fire whenever needed regardless of the weekly slot
8+
#
9+
# RAN-53 AC #5 reactive channel. Also enable repo-level "Dependabot security
10+
# updates" via gh api (the version-updates below cover routine bumps; security
11+
# updates are the reactive channel).
12+
13+
version: 2
14+
updates:
15+
# ----- Go modules (the otelcontext binary) -----
16+
- package-ecosystem: "gomod"
17+
directory: "/"
18+
schedule:
19+
interval: "weekly"
20+
day: "monday"
21+
time: "08:00"
22+
timezone: "Etc/UTC"
23+
open-pull-requests-limit: 10
24+
labels:
25+
- "type:dependencies"
26+
- "area:backend"
27+
commit-message:
28+
prefix: "chore(deps)"
29+
include: "scope"
30+
groups:
31+
otel:
32+
patterns:
33+
- "go.opentelemetry.io/*"
34+
grpc-protobuf:
35+
patterns:
36+
- "google.golang.org/grpc"
37+
- "google.golang.org/protobuf"
38+
- "google.golang.org/genproto*"
39+
gorm:
40+
patterns:
41+
- "gorm.io/*"
42+
azure:
43+
patterns:
44+
- "github.com/Azure/*"
45+
- "github.com/AzureAD/*"
46+
prometheus:
47+
patterns:
48+
- "github.com/prometheus/*"
49+
test-libs:
50+
patterns:
51+
- "github.com/stretchr/testify"
52+
- "github.com/google/go-cmp"
53+
54+
# ----- GitHub Actions (CI / release / security) -----
55+
- package-ecosystem: "github-actions"
56+
directory: "/"
57+
schedule:
58+
interval: "weekly"
59+
day: "monday"
60+
time: "08:00"
61+
timezone: "Etc/UTC"
62+
open-pull-requests-limit: 5
63+
labels:
64+
- "type:dependencies"
65+
- "area:ci"
66+
commit-message:
67+
prefix: "chore(actions)"
68+
include: "scope"
69+
groups:
70+
actions:
71+
patterns:
72+
- "*"
73+
74+
# ----- Frontend (npm under ui/) -----
75+
- package-ecosystem: "npm"
76+
directory: "/ui"
77+
schedule:
78+
interval: "weekly"
79+
day: "monday"
80+
time: "08:00"
81+
timezone: "Etc/UTC"
82+
open-pull-requests-limit: 5
83+
labels:
84+
- "type:dependencies"
85+
- "area:frontend"
86+
commit-message:
87+
prefix: "chore(frontend)"
88+
include: "scope"
89+
groups:
90+
react:
91+
patterns:
92+
- "react"
93+
- "react-dom"
94+
- "react-window"
95+
- "@types/react*"
96+
- "@types/react-window"
97+
mantine:
98+
patterns:
99+
- "@mantine/*"
100+
vite:
101+
patterns:
102+
- "vite"
103+
- "@vitejs/*"
104+
vitest-testing:
105+
patterns:
106+
- "vitest"
107+
- "@testing-library/*"
108+
- "jsdom"
109+
echarts:
110+
patterns:
111+
- "echarts"
112+
- "echarts-for-react"
113+
eslint:
114+
patterns:
115+
- "eslint"
116+
- "@eslint/*"
117+
- "eslint-plugin-*"
118+
- "typescript-eslint"
119+
- "globals"
120+
typescript:
121+
patterns:
122+
- "typescript"
123+
- "@types/*"

.github/workflows/scorecard.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# OpenSSF Scorecard supply-chain analysis.
2+
# RAN-53 AC #4. Best-effort target — no hard numeric floor; Scorecard does not gate merge.
3+
# Stretch target: >= 8.0/10. See CLAUDE.md "Security & Supply Chain" for baseline tracking.
4+
# Docs: https://github.com/ossf/scorecard-action
5+
6+
name: Scorecard supply-chain security
7+
8+
on:
9+
push:
10+
branches: [main]
11+
schedule:
12+
# Mondays 06:00 UTC
13+
- cron: "0 6 * * 1"
14+
workflow_dispatch:
15+
16+
# Restrict the default GITHUB_TOKEN to read-only; the steps below request the
17+
# narrow scopes they actually need.
18+
permissions: read-all
19+
20+
jobs:
21+
analysis:
22+
name: Scorecard analysis
23+
runs-on: ubuntu-latest
24+
permissions:
25+
# Required for upload to the code-scanning Security tab.
26+
security-events: write
27+
# Required to read OIDC token for publish_results.
28+
id-token: write
29+
# Default scopes for actions/checkout.
30+
contents: read
31+
actions: read
32+
33+
steps:
34+
- name: Harden runner egress
35+
# step-security/harden-runner v2.19.0
36+
uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40
37+
with:
38+
egress-policy: audit
39+
40+
- name: Checkout code
41+
# actions/checkout v6.0.2
42+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
43+
with:
44+
persist-credentials: false
45+
46+
- name: Run Scorecard analysis
47+
# ossf/scorecard-action v2.4.3
48+
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a
49+
with:
50+
results_file: results.sarif
51+
results_format: sarif
52+
# Publish the results so they appear on the public Scorecard dashboard.
53+
publish_results: true
54+
55+
- name: Upload Scorecard SARIF (artifact)
56+
# actions/upload-artifact v7.0.1
57+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
58+
with:
59+
name: scorecard-sarif
60+
path: results.sarif
61+
retention-days: 5
62+
63+
- name: Upload SARIF to GitHub code-scanning
64+
# github/codeql-action/upload-sarif v3.35.2
65+
uses: github/codeql-action/upload-sarif@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a
66+
with:
67+
sarif_file: results.sarif

0 commit comments

Comments
 (0)