-
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 all 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,80 @@ 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 and non-interactive GPG for signed commit/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 | ||
| # Reviewer finding cf64b44d (RAN-47, R5-1): | ||
| # `git commit -S` / `git tag -s` invoke gpg interactively by default | ||
| # and fail in non-interactive Actions shells when the imported key | ||
| # has a passphrase. setup-java only wires the passphrase for Maven | ||
| # signing (via MAVEN_GPG_PASSPHRASE in settings.xml); git itself | ||
| # has no equivalent autoconfig. Configure the gpg-agent for loopback | ||
| # pinentry, point gpg.program at a thin wrapper that injects | ||
| # --batch / --pinentry-mode loopback / --passphrase from | ||
| # MAVEN_GPG_PASSPHRASE, so signing succeeds non-interactively. | ||
| mkdir -p "$HOME/.gnupg" | ||
| chmod 700 "$HOME/.gnupg" | ||
| printf '%s\n' 'use-agent' 'pinentry-mode loopback' > "$HOME/.gnupg/gpg.conf" | ||
| printf '%s\n' 'allow-loopback-pinentry' > "$HOME/.gnupg/gpg-agent.conf" | ||
| gpgconf --kill gpg-agent || true | ||
| # Wrapper script: git invokes this with the same flags as gpg. | ||
| # We exec into gpg with --batch + loopback + the passphrase from | ||
| # the env (MAVEN_GPG_PASSPHRASE is set on each step that signs). | ||
| cat > "$HOME/.gnupg/gpg-loopback.sh" <<'WRAPPER' | ||
| #!/usr/bin/env bash | ||
| # Non-interactive gpg wrapper for `git commit -S` / `git tag -s`. | ||
| # MAVEN_GPG_PASSPHRASE is set on the workflow step that signs. | ||
| exec gpg --batch --yes --pinentry-mode loopback \ | ||
| --passphrase "${MAVEN_GPG_PASSPHRASE:-}" "$@" | ||
| WRAPPER | ||
| chmod +x "$HOME/.gnupg/gpg-loopback.sh" | ||
| git config gpg.program "$HOME/.gnupg/gpg-loopback.sh" | ||
| - name: Set release version and create signed release commit | ||
| env: | ||
| RELEASE_VERSION: ${{ inputs.version }} | ||
| run: mvn versions:set -DnewVersion="$RELEASE_VERSION" | ||
| # Picked up by the gpg-loopback wrapper script for `git commit -S`. | ||
| 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 | ||
|
|
||
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 👍 / 👎.