-
Notifications
You must be signed in to change notification settings - Fork 20
Matin/ Add Claude code review workflows and documentation #293
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
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,71 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Claude Code Assistant Workflow | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| # This GitHub Actions workflow uses the Claude Code Action to review pull requests. | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| name: Claude Code Assistant | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| on: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull_request: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| types: [opened, synchronize, reopened, ready_for_review] | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| jobs: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| claude-assistant: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Only run on PR-related events that contain @claude | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| if: github.event_name == 'pull_request' | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| runs-on: ubuntu-latest | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| permissions: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| contents: read | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| pull-requests: write | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| issues: write | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| id-token: write | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| actions: read | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Cancel older runs when new commits arrive on the same PR | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| concurrency: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| group: pr-${{ github.event.pull_request.number }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| cancel-in-progress: true | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| steps: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Verify user | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: 'deriv-com/shared-actions/.github/actions/verify_user_in_organization@v3' | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| username: ${{ github.event.pull_request.user.login }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| token: ${{ secrets.PERSONAL_ACCESS_TOKEN }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Ensure we have a real git repo at the PR HEAD (works for forks) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Checkout PR head | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: actions/checkout@v4 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| repository: ${{ github.event.pull_request.head.repo.full_name }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| ref: ${{ github.event.pull_request.head.ref }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| fetch-depth: 20 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| token: ${{ secrets.GITHUB_TOKEN }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Sanity check (helps diagnose if anything goes wrong) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Verify git workspace | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+35
to
+44
Check warningCode scanning / CodeQL Checkout of untrusted code in trusted context Medium
Potential unsafe checkout of untrusted pull request on privileged workflow.
Copilot AutofixAI 12 days ago In general, the fix is to avoid checking out and operating on the untrusted PR HEAD in a privileged context. For a review bot like this, the Claude action can work from the base repository combined with GitHub’s pull request metadata, without needing to execute code from the PR checkout. So the best fix is to stop checking out the PR head repository/ref, and instead either (a) check out the base repository on the merge commit / base ref, or (b) remove the checkout entirely if the Claude action does not require a local working tree. The minimal change that preserves functionality while removing the unsafe pattern is:
Concretely, in - name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 20No new imports or methods are needed; this is purely a workflow configuration change within that file.
Suggested changeset
1
.github/workflows/claude.yml
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| run: | | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| pwd | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| git rev-parse --is-inside-work-tree | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| git log -1 --oneline | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| - name: Run Claude Code Action | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| uses: anthropics/claude-code-action@v1 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warningCode scanning / CodeQL Unpinned tag for a non-immutable Action in workflow Medium
Unpinned 3rd party Action 'Claude Code Assistant' step
Uses Step Error loading related location Loading |
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| timeout-minutes: 60 | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| with: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| github_token: ${{ secrets.GITHUB_TOKEN }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| track_progress: true | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| prompt: | | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| REPO: ${{ github.repository }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| PR NUMBER: ${{ github.event.pull_request.number }} | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| Please review this pull request with a focus on: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Correctness, regressions, and edge cases | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Code quality & readability (React + TypeScript best practices) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Performance (render cost, memoization, effects) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Security (XSS, auth flows, secrets) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Tests (coverage for new logic) | |||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||
| Output: | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Inline comments for specific issues | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - A summary comment with high/medium/low priority items | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| - Concrete fix suggestions and quick patches where safe | |||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,207 @@ | ||
| name: Security NCLC Review | ||
| permissions: | ||
| pull-requests: write # Needed for leaving PR comments | ||
| contents: read | ||
| on: | ||
| pull_request: | ||
| types: [opened, synchronize, reopened, ready_for_review] | ||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | ||
| cancel-in-progress: true | ||
| jobs: | ||
| security: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| if: github.event.pull_request.draft == false | ||
| env: | ||
| SLACK_WEBHOOK_URL: ${{ secrets.SAST_SECURITY_SLACK_WEBHOOK }} | ||
| SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK | ||
| PR_URL: ${{ github.event.pull_request.html_url }} | ||
| PR_CREATOR: ${{ github.event.pull_request.user.login }} | ||
| PR_HEAD_COMMIT_URL: ${{ github.event.pull_request.html_url }}/commits/${{ github.event.pull_request.head.sha }} | ||
| WORKFLOW_RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | ||
| GITHUB_SENDER: ${{ github.event.sender.login }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.pull_request.head.sha || github.sha }} | ||
| fetch-depth: 2 | ||
| - name: Generate Custom Instruction File | ||
| run: | | ||
| cat <<EOF > custom_instruction.md | ||
| You are a Principal Application Security Engineer performing a security-focused code review. Analyze all changes in this PR for security vulnerabilities and provide actionable feedback. | ||
| ## Review Scope & Priority | ||
| ### CRITICAL - Block PR if found: | ||
| - Hardcoded secrets, API keys, passwords, tokens | ||
| - SQL injection vulnerabilities | ||
| - Remote Code Execution (RCE) risks | ||
| - Path traversal vulnerabilities | ||
| - Unsafe deserialization | ||
| - Missing authentication/authorization on sensitive endpoints | ||
| - Exposed sensitive data in logs/responses | ||
| ### HIGH - Require immediate fix: | ||
| - Cross-Site Scripting (XSS) vulnerabilities | ||
| - Server-Side Request Forgery (SSRF) | ||
| - Insecure Direct Object References (IDOR) | ||
| - Cross-Site Request Forgery (CSRF) missing protections | ||
| - XML External Entity (XXE) injection | ||
| - Weak cryptography or hashing algorithms | ||
| - Race conditions in security controls | ||
| ### MEDIUM - Fix before production: | ||
| - Missing input validation/sanitization | ||
| - Overly permissive CORS policies | ||
| - Missing security headers | ||
| - Insufficient logging for security events | ||
| - Missing rate limiting | ||
| - Dependency vulnerabilities (outdated packages) | ||
| ## Technology-Specific Checks | ||
| ### JavaScript/TypeScript Frontend: | ||
| ```javascript | ||
| // DOM Manipulation & XSS Prevention: | ||
| - innerHTML/outerHTML/document.write() with user input | ||
| - dangerouslySetInnerHTML with unsanitized user input | ||
| - html-react-parser() without DOMPurify or sanitization | ||
| - $.html(), $.append(), $.after() with unsanitized data | ||
| - Unescaped user data in JSX expressions | ||
| - template literals with user input in HTML context | ||
|
|
||
| // Code Execution Risks: | ||
| - eval(), new Function(), setTimeout/setInterval with string arguments | ||
| - Dynamic imports from untrusted sources | ||
| - postMessage without targetOrigin validation | ||
| - window.open() with user-controlled URLs | ||
|
|
||
| // React-Specific Security: | ||
| - dangerouslySetInnerHTML usage (always requires justification) | ||
| - Props spreading (...props) potentially exposing sensitive attributes | ||
| - useEffect/useState with untrusted external data | ||
| - Component injection via dynamic imports without validation | ||
| - Context API exposing sensitive data (tokens, credentials) | ||
| - Ref manipulation allowing XSS | ||
|
|
||
| // Data Storage & Exposure: | ||
| - localStorage/sessionStorage storing tokens, passwords, PII | ||
| - Sensitive data in console.log/console.error/console.debug | ||
| - API keys, secrets, or credentials in frontend code | ||
| - Tokens or sensitive data in URL query parameters | ||
| - Session data persisting after logout | ||
|
|
||
| // Cryptography & Encoding: | ||
| - crypto-js using weak algorithms (MD5, SHA1 for passwords) | ||
| - Hardcoded encryption keys or initialization vectors | ||
| - Base64 encoding used as security measure | ||
| - Math.random() for security-sensitive operations | ||
| - Client-side-only password validation | ||
|
|
||
| // API & WebSocket Security: | ||
| - API responses used without validation/sanitization | ||
| - Credentials transmitted over unencrypted WebSocket | ||
|
|
||
| // Navigation & Redirects: | ||
| - window.location/location.href with user input | ||
| - history.pushState/replaceState with untrusted data | ||
| - Open redirects (redirect parameter not validated) | ||
| - <a href> with javascript: protocol | ||
| - target="_blank" without rel="noopener noreferrer" | ||
|
|
||
| // Configuration & Build: | ||
| - .env files committed to repository | ||
| - Webpack exposing sensitive environment variables to frontend | ||
| - Debug/development mode enabled in production | ||
| - Source maps exposed in production builds | ||
| - Missing Subresource Integrity (SRI) on CDN resources | ||
| - CSP headers missing or overly permissive | ||
|
|
||
| // Deserialization & Parsing: | ||
| - JSON.parse() without try-catch or validation | ||
| - js-yaml.load() without safeLoad (allows code execution) | ||
| - XML parsing without XXE protection | ||
| - User-controlled data in eval-like functions | ||
|
|
||
| // Additional Frontend Risks: | ||
| - CORS policies too permissive (allowing * origin) | ||
| - Clickjacking (missing X-Frame-Options/CSP frame-ancestors) | ||
| - MIME type sniffing (missing X-Content-Type-Options) | ||
| - Reflected XSS in error messages | ||
| - DOM-based XSS via URL fragments (#) | ||
| - Prototype pollution via Object.assign, merge functions | ||
| - ReDoS (Regex Denial of Service) patterns | ||
| - Missing CSRF tokens on state-changing operations | ||
| ``` | ||
| ## Review Output Format | ||
| For each finding, provide: | ||
| ``` | ||
| :red_circle: CRITICAL | :large_yellow_circle: HIGH | :large_orange_circle: MEDIUM | :large_blue_circle: LOW | ||
| **Issue:** [Vulnerability type] | ||
| **Location:** [File:Line] | ||
| **Risk:** [Brief explanation of potential exploit] | ||
| **Fix:** | ||
| ```[Secure code example]``` | ||
| **Reference:** [OWASP/CWE ID if applicable] | ||
| ``` | ||
| ## Additional Checks | ||
| 1. **Dependencies:** | ||
| - Run security audit on package.json | ||
| - Check for known CVEs in dependencies | ||
| - Verify dependency sources are trusted | ||
| 2. **Secrets Detection:** | ||
| - Scan for patterns: API keys, passwords, tokens, certificates | ||
| - Check .env files are gitignored | ||
| - Verify no sensitive data in comments | ||
| 3. **Configuration:** | ||
| - Ensure secure defaults (fail closed) | ||
| - Verify least privilege principle | ||
| - Check for defense-in-depth implementation | ||
| 4. **Data Flow:** | ||
| - Trace user input from entry to processing | ||
| - Verify all boundaries have validation | ||
| - Ensure proper encoding at each layer | ||
| ## Summary Requirements | ||
| At the end of review, provide: | ||
| 1. Security score: PASS :white_check_mark: | FAIL :x: | ||
| 2. Count by severity: Critical(X), High(X), Medium(X), Low(X) | ||
| 3. Must-fix items before merge | ||
| 4. Recommended improvements | ||
| 5. Positive security practices observed | ||
| ## Review Principles | ||
| - Assume all input is malicious | ||
| - Verify trust boundaries | ||
| - Check fail-safe defaults | ||
| - Validate defense-in-depth | ||
| - Ensure least privilege | ||
| - Confirm secure communication | ||
| - Verify proper error handling | ||
| - Check audit logging presence | ||
| Focus only on security. Do not comment on code style, performance, or non-security bugs unless they have security implications. | ||
| EOF | ||
| - uses: anthropics/claude-code-security-review@68982a6bf10d545e94dd0390af08306d94ef684c | ||
| with: | ||
| comment-pr: true | ||
| claude-api-key: ${{ secrets.ANTHROPIC_API_KEY }} | ||
| run-every-commit: true | ||
| custom-security-scan-instructions: custom_instruction.md | ||
| claude-model: ${{ vars.CLAUDE_MODEL || 'claude-opus-4-5-20251101' }} | ||
| - name: Send Failure Notification to Slack | ||
| if: failure() | ||
| uses: slackapi/slack-github-action@6c661ce58804a1a20f6dc5fbee7f0381b469e001 | ||
| with: | ||
| # For posting a rich message using Block Kit | ||
| payload: | | ||
| { | ||
| "blocks": [ | ||
| { | ||
| "type": "section", | ||
| "text": { | ||
| "type": "mrkdwn", | ||
| "text": ":red-alert: *Security NCLC Review Checks Failed*" | ||
| } | ||
| }, | ||
| { | ||
| "type": "section", | ||
| "text": { | ||
| "type": "mrkdwn", | ||
| "text": "`Workflow Run:` ${{ env.WORKFLOW_RUN_URL }}\n\n`Pull Request:` ${{ env.PR_URL }}\n\n`Head Commit:` ${{ env.PR_HEAD_COMMIT_URL }}\n\n`PR Creator:` *${{ env.PR_CREATOR }}*\n\n`Latest Committer:` *${{ env.GITHUB_SENDER }}*\n\n" | ||
| } | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,22 +1,6 @@ | ||
| #!/bin/sh | ||
| . "$(dirname "$0")/_/husky.sh" | ||
|
|
||
| # ShiftAI Pre-push Hook - Intercept push for AI analysis and PR management | ||
| # Git pre-push hook passes: $1=remote_name, $2=remote_url | ||
|
|
||
| # 🗑️ EARLY EXIT: Check for delete operations at shell level | ||
| if ps aux | grep -v grep | grep -q "git.*push.*--delete"; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| fi | ||
| # Check command line arguments in current process tree | ||
| if pgrep -f "git.*push.*--delete" > /dev/null 2>&1; then | ||
| exit 0 | ||
| fi | ||
|
|
||
| export GIT_PUSH_REMOTE_NAME="$1" | ||
| export GIT_PUSH_REMOTE_URL="$2" | ||
|
|
||
| npx @deriv-com/shiftai-cli hook pre-push | ||
|
|
||
| fi | ||
| exit $? |
Check warning
Code scanning / CodeQL
Unpinned tag for a non-immutable Action in workflow Medium