# Excubitor pre-merge security gate, for .github/workflows/ # # Reviews the files a pull request changed for AI-application security issues # (OWASP LLM Top 10), fails the check on HIGH or worse, and posts the review as a # comment. With a console configured it also files the result in your security # ledger, so a finding has a home rather than scrolling out of a pull request. # # ⛔ EXCUBITOR IS NEVER GIVEN ACCESS TO YOUR REPOSITORIES. This runs inside your # CI, which already has the access it needs, and reports outward. Nothing here # asks you to install an app or grant an organization token. # # To file results in your ledger, set two repository secrets: # EXCUBITOR_CONSOLE_URL the console you were given # EXCUBITOR_TOKEN the ingest credential issued for this application # Leave them unset and the gate still gates; it just reports nowhere. name: Excubitor security gate on: [pull_request] permissions: contents: read pull-requests: write # the review comment, and nothing else jobs: excubitor-gate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - uses: actions/setup-python@v5 with: python-version: "3.12" - name: Install Excubitor run: pip install excubitor-sdk[codereview] # + Bandit - name: Review changed files env: EXCUBITOR_CONSOLE_URL: ${{ secrets.EXCUBITOR_CONSOLE_URL }} EXCUBITOR_TOKEN: ${{ secrets.EXCUBITOR_TOKEN }} run: | # The files this pull request touched, and only those. git diff --name-only --diff-filter=ACM origin/${{ github.base_ref }}...HEAD \ | grep -E '\.(py|js|ts|jsx|tsx|java|go|rb|php|sh)$' > changed.txt || true if [ -s changed.txt ]; then excubitor-cigate $(cat changed.txt) --fail-on HIGH | tee review.md else echo "No reviewable files changed." | tee review.md fi - name: Post the review as a comment if: always() uses: actions/github-script@v7 with: script: | const fs = require('fs'); const body = fs.readFileSync('review.md', 'utf8'); github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body, });