diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..ec32dea --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,56 @@ +version: 2 +updates: + - package-ecosystem: gomod + directory: / + schedule: + interval: weekly + day: monday + time: "06:00" + timezone: UTC + open-pull-requests-limit: 5 + labels: + - dependencies + - go + + - package-ecosystem: npm + directory: /ui + schedule: + interval: weekly + day: monday + time: "06:00" + timezone: UTC + open-pull-requests-limit: 5 + labels: + - dependencies + - javascript + groups: + react: + patterns: + - react + - react-dom + - "@types/react*" + dev-tooling: + patterns: + - vite + - vitest + - "@vitejs/*" + - typescript + - eslint* + - "@eslint/*" + - prettier + d3: + patterns: + - "d3-*" + - "@types/d3-*" + + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + day: monday + time: "06:00" + timezone: UTC + open-pull-requests-limit: 5 + labels: + - dependencies + - ci diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cec81f5..e736b3a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,17 +5,18 @@ on: branches: [main] pull_request: -permissions: - contents: read +permissions: read-all jobs: ui: name: ui (build + test + budget) runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: actions/setup-node@v6 + - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6 with: node-version: '22' cache: 'npm' @@ -46,7 +47,7 @@ jobs: fi - name: Upload ui/dist - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: ui-dist path: ui/dist @@ -56,6 +57,8 @@ jobs: test: name: test (${{ matrix.os }}) needs: ui + permissions: + contents: read strategy: fail-fast: false matrix: @@ -64,9 +67,9 @@ jobs: env: CGO_ENABLED: "1" steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: actions/setup-go@v6 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: go.mod @@ -75,7 +78,7 @@ jobs: run: clang --version - name: Go build cache - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/.cache/go-build @@ -88,7 +91,7 @@ jobs: # Hydrate ui/dist with the build artifact produced by the `ui` job so # the //go:embed ui/dist directive has real assets to embed. - name: Download ui/dist - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: ui-dist path: ui/dist @@ -103,7 +106,7 @@ jobs: run: CGO_ENABLED=1 go build -tags sqlite_fts5 -o docsiq ./ - name: Upload docsiq binary - uses: actions/upload-artifact@v7 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: docsiq-${{ matrix.os }} path: docsiq @@ -114,15 +117,17 @@ jobs: name: integration tests (-race) needs: ui runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - - uses: actions/setup-go@v6 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: go.mod - name: cache go build - uses: actions/cache@v5 + uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5 with: path: | ~/.cache/go-build @@ -130,7 +135,7 @@ jobs: key: go-integ-${{ hashFiles('go.sum') }} - name: Download ui/dist - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8 with: name: ui-dist path: ui/dist diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000..8a3cf98 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,46 @@ +name: CodeQL + +on: + push: + branches: [main] + pull_request: + branches: [main] + schedule: + - cron: '0 5 * * 1' + +permissions: read-all + +jobs: + analyze: + name: Analyze (${{ matrix.language }}) + runs-on: ubuntu-latest + permissions: + security-events: write + packages: read + actions: read + contents: read + + strategy: + fail-fast: false + matrix: + include: + - language: go + build-mode: autobuild + - language: javascript-typescript + build-mode: none + + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + + - name: Initialize CodeQL + uses: github/codeql-action/init@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + queries: security-extended + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@ce64ddcb0d8d890d2df4a9d1c04ff297367dea2a # v3 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 986a928..006041b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,8 +6,7 @@ on: push: branches: [main] -permissions: - contents: write +permissions: read-all concurrency: group: release-main @@ -17,8 +16,10 @@ jobs: release: name: auto-tag + release runs-on: ubuntu-latest + permissions: + contents: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 97b5df9..050edd2 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -21,7 +21,7 @@ jobs: steps: - name: checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: persist-credentials: false @@ -33,7 +33,7 @@ jobs: publish_results: true - name: upload artifact - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7 with: name: scorecard-results path: results.sarif diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..364faad --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,38 @@ +# Security Policy + +## Reporting a Vulnerability + +Please report security vulnerabilities via GitHub's +[private vulnerability reporting](https://github.com/RandomCodeSpace/docsiq/security/advisories/new). + +Do **not** open a public issue for security reports. + +We aim to acknowledge reports within 72 hours and provide a remediation +plan within 7 days of triage. + +## Scope + +In scope: + +- The `docsiq` binary and all Go packages under `internal/` and `cmd/` +- The embedded React SPA in `ui/` +- The MCP server and REST API exposed by `docsiq serve` +- Build, release, and CI workflows under `.github/` + +Out of scope: + +- Third-party LLM providers (Azure OpenAI, OpenAI, Ollama) — report + upstream +- Vulnerabilities that require a compromised local shell or filesystem + access + +## Supported Versions + +docsiq is pre-1.0. Only the latest `v0.0.0-beta.N` prerelease receives +security patches. + +## Disclosure + +We follow coordinated disclosure. Once a fix ships in a release, we +publish a [GitHub Security Advisory](https://github.com/RandomCodeSpace/docsiq/security/advisories) +crediting the reporter unless they request anonymity.