-
Notifications
You must be signed in to change notification settings - Fork 0
chore(bootstrap): RAN-46 engineering bootstrap (security, runbooks, OpenSSF wiring) #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
638fda7
0b03459
35762b1
9b9665c
e71ccdb
1dad7e7
fdac5c8
069cbb7
6e7e911
a4dee7c
182a590
2d3e16d
4f2f5bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| { | ||
| "$schema": "https://bestpractices.coreinfrastructure.org/projects.schema.json", | ||
| "_comment": "OpenSSF Best Practices self-assessment skeleton for RandomCodeSpace/codeiq. The numeric project_id and badge URL are populated by a board admin after registering the project at https://www.bestpractices.dev/ — RAN-46 AC #8 calls this out as auth-blocked. Once the registration is complete, fill `project_id` and re-render the README badge with the resolved URL.", | ||
| "project_id": null, | ||
| "name": "codeiq", | ||
| "description": "Deterministic code knowledge graph — scans codebases to map services, endpoints, entities, infrastructure, auth patterns, and framework usage. No AI, pure static analysis.", | ||
| "homepage_url": "https://github.com/RandomCodeSpace/codeiq", | ||
| "repo_url": "https://github.com/RandomCodeSpace/codeiq", | ||
| "license": "MIT", | ||
| "level": "passing", | ||
| "status": { | ||
| "basics": "self-assessed-passing", | ||
| "change_control": "self-assessed-passing", | ||
| "reporting": "self-assessed-passing", | ||
| "quality": "self-assessed-passing", | ||
| "security": "self-assessed-passing", | ||
| "analysis": "self-assessed-passing" | ||
| }, | ||
| "evidence": { | ||
| "vulnerability_report_process": "SECURITY.md", | ||
| "release_process": "shared/runbooks/release.md", | ||
| "rollback_process": "shared/runbooks/rollback.md", | ||
| "first_time_setup": "shared/runbooks/first-time-setup.md", | ||
| "engineering_standards": "shared/runbooks/engineering-standards.md", | ||
| "license_file": "LICENSE", | ||
| "build_reproducible": "mvn -B -ntp clean verify", | ||
| "ci_workflow": ".github/workflows/ci-java.yml", | ||
| "code_scanning": "GitHub repo setting (CodeQL default setup, java-kotlin + javascript-typescript + actions). Workflow-driven CodeQL was tried in PR #74 but conflicts with default setup at SARIF upload — keeping default setup as the SSoT.", | ||
| "supply_chain_scorecard": ".github/workflows/scorecard.yml", | ||
| "dependency_updates": ".github/dependabot.yml", | ||
| "signed_commits": "scripts/setup-git-signed.sh", | ||
| "secret_scanning": "GitHub repo setting (secret_scanning + push_protection enabled)", | ||
| "static_analysis": "SpotBugs (mvn spotbugs:check) + SonarCloud Quality Gate", | ||
| "vulnerability_scanning": "OWASP Dependency-Check (mvn dependency-check:check) + Dependabot security updates" | ||
| }, | ||
| "audit": { | ||
| "self_assessment_date": "2026-04-25", | ||
| "self_assessment_author": "TechLead (RAN-46)", | ||
| "registration_blocker": "https://www.bestpractices.dev/ requires human OAuth/form. Tracked under RAN-46 AC #8." | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| # Dependabot configuration for codeiq. | ||
| # Docs: https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file | ||
| # | ||
| # Strategy: | ||
| # * weekly cadence — keeps the noise floor low while still catching CVEs early | ||
| # * grouped updates per ecosystem so PR fan-out stays manageable | ||
| # * security updates fire whenever needed regardless of the weekly slot | ||
| # | ||
| # RAN-46 AC #4: Dependabot (security + version updates, weekly, grouped). Also | ||
| # enable repo-level "Dependabot security updates" via gh api (the version-updates | ||
| # below cover routine bumps; security updates are the reactive channel). | ||
|
|
||
| version: 2 | ||
| updates: | ||
| # ----- Maven (the codeiq application) ----- | ||
| - package-ecosystem: "maven" | ||
| directory: "/" | ||
| schedule: | ||
| interval: "weekly" | ||
| day: "monday" | ||
| time: "08:00" | ||
| timezone: "Etc/UTC" | ||
| open-pull-requests-limit: 10 | ||
| labels: | ||
| - "type:dependencies" | ||
| - "area:backend" | ||
| commit-message: | ||
| prefix: "chore(deps)" | ||
| include: "scope" | ||
| groups: | ||
| spring: | ||
| patterns: | ||
| - "org.springframework*" | ||
| - "org.springframework.boot:*" | ||
| - "org.springframework.security:*" | ||
| - "org.springframework.ai:*" | ||
| jackson: | ||
| patterns: | ||
| - "com.fasterxml.jackson*" | ||
| neo4j: | ||
| patterns: | ||
| - "org.neo4j:*" | ||
| - "org.neo4j.driver:*" | ||
| antlr: | ||
| patterns: | ||
| - "org.antlr:*" | ||
| maven-plugins: | ||
| patterns: | ||
| - "org.apache.maven.plugins:*" | ||
| - "org.codehaus.*" | ||
| - "org.jacoco:*" | ||
| - "com.github.spotbugs:*" | ||
| - "org.owasp:*" | ||
| - "org.sonarsource.scanner.maven:*" | ||
| - "org.sonatype.central:*" | ||
| test-libs: | ||
| patterns: | ||
| - "org.junit.jupiter:*" | ||
| - "org.mockito:*" | ||
| - "org.assertj:*" | ||
| - "org.hamcrest:*" | ||
| - "com.h2database:*" | ||
|
|
||
| # ----- GitHub Actions (CI / release / security) ----- | ||
| - package-ecosystem: "github-actions" | ||
| directory: "/" | ||
| schedule: | ||
| interval: "weekly" | ||
| day: "monday" | ||
| time: "08:00" | ||
| timezone: "Etc/UTC" | ||
| open-pull-requests-limit: 5 | ||
| labels: | ||
| - "type:dependencies" | ||
| - "area:ci" | ||
| commit-message: | ||
| prefix: "chore(actions)" | ||
| include: "scope" | ||
| groups: | ||
| actions: | ||
| patterns: | ||
| - "*" | ||
|
|
||
| # ----- Frontend (npm under src/main/frontend) ----- | ||
| - package-ecosystem: "npm" | ||
| directory: "/src/main/frontend" | ||
| schedule: | ||
| interval: "weekly" | ||
| day: "monday" | ||
| time: "08:00" | ||
| timezone: "Etc/UTC" | ||
| open-pull-requests-limit: 5 | ||
| labels: | ||
| - "type:dependencies" | ||
| - "area:frontend" | ||
| commit-message: | ||
| prefix: "chore(frontend)" | ||
| include: "scope" | ||
| groups: | ||
| react: | ||
| patterns: | ||
| - "react" | ||
| - "react-dom" | ||
| - "@types/react*" | ||
| ant-design: | ||
| patterns: | ||
| - "antd" | ||
| - "@ant-design/*" | ||
| vite: | ||
| patterns: | ||
| - "vite" | ||
| - "@vitejs/*" | ||
| echarts: | ||
| patterns: | ||
| - "echarts" | ||
| - "echarts-for-react" | ||
| eslint: | ||
| patterns: | ||
| - "eslint*" | ||
| - "@eslint/*" | ||
| - "@typescript-eslint/*" | ||
| typescript: | ||
| patterns: | ||
| - "typescript" | ||
| - "@types/*" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,8 +12,8 @@ jobs: | |
| permissions: | ||
| contents: write | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-java@v4 | ||
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4.2.2 | ||
| - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v4.7.1 | ||
| with: | ||
| distribution: 'temurin' | ||
| java-version: '25' | ||
|
|
@@ -23,23 +23,53 @@ jobs: | |
| server-password: MAVEN_PASSWORD | ||
| gpg-private-key: ${{ secrets.MAVEN_GPG_PRIVATE_KEY }} | ||
| gpg-passphrase: MAVEN_GPG_PASSPHRASE | ||
| - name: Set release version | ||
| - name: Configure git identity for signed release commit and tag | ||
| run: | | ||
| git config user.email "github-actions[bot]@users.noreply.github.com" | ||
| git config user.name "github-actions[bot]" | ||
| # Use the GPG key imported by setup-java (MAVEN_GPG_PRIVATE_KEY) for | ||
| # both commit and tag signing — same trust path as the artifact. | ||
| KEYID=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec:/ {print $5; exit}') | ||
| if [ -z "$KEYID" ]; then | ||
| echo "no GPG secret key in agent — release-java.yml needs MAVEN_GPG_PRIVATE_KEY" >&2 | ||
| exit 1 | ||
| fi | ||
| git config user.signingkey "$KEYID" | ||
| git config gpg.format openpgp | ||
| git config commit.gpgsign true | ||
| git config tag.gpgsign true | ||
| - name: Set release version and create signed release commit | ||
| env: | ||
| RELEASE_VERSION: ${{ inputs.version }} | ||
| run: mvn versions:set -DnewVersion="$RELEASE_VERSION" | ||
| MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} | ||
| # Commit the version bump on a detached HEAD off the workflow's | ||
| # checkout. The commit is reachable only via the tag created below — | ||
| # no push to `main`, so this works under branch protection. | ||
| # The commit captures the exact source tree that the deploy step | ||
| # will build from, fixing the prior "tag diverges from released | ||
| # artifact" gap (Reviewer finding 47b718b9). | ||
| run: | | ||
| mvn -B -ntp versions:set -DnewVersion="$RELEASE_VERSION" -DgenerateBackupPoms=false | ||
| git add pom.xml | ||
| git commit -S -m "chore(release): ${RELEASE_VERSION}" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The release workflow signs the version-bump commit with Useful? React with 👍 / 👎. |
||
| - name: Deploy to Maven Central | ||
| env: | ||
| MAVEN_USERNAME: ${{ secrets.OSS_NEXUS_USER }} | ||
| MAVEN_PASSWORD: ${{ secrets.OSS_NEXUS_PASS }} | ||
| MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} | ||
| run: mvn clean deploy -P release -B | ||
| - name: Tag release | ||
| run: mvn -B -ntp -P release clean deploy | ||
| - name: Create signed annotated tag and push | ||
| env: | ||
| RELEASE_VERSION: ${{ inputs.version }} | ||
| MAVEN_GPG_PASSPHRASE: ${{ secrets.MAVEN_GPG_PASSPHRASE }} | ||
| # Annotated + GPG-signed tag pointing at the release commit (the | ||
| # current HEAD after the commit step above). Push only the tag — | ||
| # the release commit lives only as a tag-reachable object so we | ||
| # never need to update `main`, and branch protection stays clean. | ||
| run: | | ||
| git tag "v${RELEASE_VERSION}" | ||
| git push origin "v${RELEASE_VERSION}" | ||
| - uses: softprops/action-gh-release@v2 | ||
| git tag -s "v${RELEASE_VERSION}" -m "codeiq ${RELEASE_VERSION}" | ||
| git push origin "refs/tags/v${RELEASE_VERSION}" | ||
| - uses: softprops/action-gh-release@3bb12739c298aeb8a4eeaf626c5b8d85266b0e65 # v2 | ||
| with: | ||
| tag_name: v${{ inputs.version }} | ||
| generate_release_notes: true | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # OpenSSF Scorecard supply-chain analysis. | ||
| # RAN-46 AC #9. Best-effort target — no hard numeric floor; Scorecard does not gate merge. | ||
| # Docs: https://github.com/ossf/scorecard-action | ||
|
|
||
| name: Scorecard supply-chain security | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| schedule: | ||
| # Mondays 06:00 UTC | ||
| - cron: "0 6 * * 1" | ||
| workflow_dispatch: | ||
|
|
||
| # Restrict the default GITHUB_TOKEN to read-only; the steps below request the | ||
| # narrow scopes they actually need. | ||
| permissions: read-all | ||
|
|
||
| jobs: | ||
| analysis: | ||
| name: Scorecard analysis | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| # Required for upload to the code-scanning Security tab. | ||
| security-events: write | ||
| # Required to read OIDC token for publish_results. | ||
| id-token: write | ||
| # Default scopes for actions/checkout. | ||
| contents: read | ||
| actions: read | ||
|
|
||
| steps: | ||
| - name: Harden runner egress | ||
| # step-security/harden-runner v2.19.0 | ||
| uses: step-security/harden-runner@8d3c67de8e2fe68ef647c8db1e6a09f647780f40 | ||
| with: | ||
| egress-policy: audit | ||
|
|
||
| - name: Checkout code | ||
| # actions/checkout v6.0.2 | ||
| uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd | ||
| with: | ||
| persist-credentials: false | ||
|
|
||
| - name: Run Scorecard analysis | ||
| # ossf/scorecard-action v2.4.3 | ||
| uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a | ||
| with: | ||
| results_file: results.sarif | ||
| results_format: sarif | ||
| # Publish the results so they appear on the public Scorecard dashboard. | ||
| publish_results: true | ||
|
|
||
| - name: Upload Scorecard SARIF (artifact) | ||
| # actions/upload-artifact v7.0.1 | ||
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a | ||
| with: | ||
| name: scorecard-sarif | ||
| path: results.sarif | ||
| retention-days: 5 | ||
|
|
||
| - name: Upload SARIF to GitHub code-scanning | ||
| # github/codeql-action/upload-sarif v3.35.2 | ||
| uses: github/codeql-action/upload-sarif@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a | ||
| with: | ||
| sarif_file: results.sarif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This workflow only executes
mvn -B -ntp clean verify, butspotbugs-maven-pluginis not bound to any lifecycle phase inpom.xml, sospotbugs:checkis never executed here. In practice, PRs can merge with new High/Critical SpotBugs findings even though this step and the runbooks describe SpotBugs as part of the blocking gate.Useful? React with 👍 / 👎.