Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/claude-code-review.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ jobs:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
plugins: 'code-review@claude-code-plugins'
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
# --comment: 리뷰 findings를 PR 인라인 코멘트로 게시. 미지정 시 automation 모드에서 결과가 모델 출력에만 남아 PR엔 안 보임(= success인데 리뷰 없음).
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }} --comment'

# 자동 리뷰 완료 시 프론트엔드 Slack 채널에 알림. 기존 PR open 알림과는 별도 메시지로 구분.
- name: Notify Slack on review complete
Expand Down
27 changes: 25 additions & 2 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,41 @@ jobs:
with:
fetch-depth: 1

# claude-code-action은 working dir의 .mcp.json을 enableAllProjectMcpServers로 자동 로드한다.
# repo에 .mcp.json을 두지 않고(로컬 환경 침범 방지) 워크플로우 실행 중에만 생성하여 Notion MCP를 등록.
# claude_args의 --mcp-config는 v1에서 무시되는 정황이 확인되어 자동 로드 경로를 사용.
- name: Generate .mcp.json for Notion MCP
run: |
cat > .mcp.json <<'JSON'
{
"mcpServers": {
"notion": {
"command": "npx",
"args": ["-y", "@notionhq/notion-mcp-server"]
Comment on lines +42 to +43
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

MCP 서버/외부 액션은 exact pin(버전·커밋)하고, 비신뢰 트리거에 대한 시크릿/쓰기 도구 노출을 차단하세요.

  • .github/workflows/claude.ymlnpx -y @notionhq/notion-mcp-server``는 버전이 고정되어 있지 않아 업스트림 변경 시 워크플로우 재현성과 공급망 안전성이 떨어집니다. exact 버전으로 pin 하세요.
  • anthropics/claude-code-action@v1는 태그로만 고정되어 있고, 해당 실행 경로는 secretscontents/pull-requests/issues: write 권한을 사용합니다. commit SHA로 pin 하세요.
  • 트리거가 @claude 문자열 포함 여부에만 의존해 NOTION_TOKEN 같은 시크릿mcp__notion__*, Bash(npx *) 등 강력 툴이 노출됩니다. github.actor/승인자/브랜치/PR 상태 등으로 신뢰 게이트를 추가하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/claude.yml around lines 42 - 43, Pin the external MCP
invocation and action to immutable versions and add a trust gate: replace the
open npx call "npx -y `@notionhq/notion-mcp-server`" with an exact pin (e.g., use
"`@notionhq/notion-mcp-server`@vX.Y.Z" or a specific commit SHA) and pin
"anthropics/claude-code-action@v1" to its commit SHA instead of the tag;
restrict secrets/permission exposure by gating use of NOTION_TOKEN and write
permissions (mcp__notion__*, contents/pull-requests/issues: write) behind an
approval/allowlist check (use github.actor allowlist, required
reviewers/approval, branch/PR state or a conditional that only runs the MCP step
for trusted actors/branches) so those steps never run on untrusted triggers.

}
}
}
JSON

- name: Run Claude Code
id: claude
uses: anthropics/claude-code-action@v1
env:
# Notion MCP 서버(@notionhq/notion-mcp-server)가 OpenAPI 호출 시 사용할 인증 헤더.
# npx 자식 프로세스가 step env를 자동 상속하므로 MCP config 파일에는 별도로 명시하지 않음.
# 토큰은 "스터디 플랫폼 : 코드 제로투원" 페이지에 connection된 integration의 권한 범위 내에서만 동작.
OPENAPI_MCP_HEADERS: '{"Authorization":"Bearer ${{ secrets.NOTION_TOKEN }}","Notion-Version":"2022-06-28"}'
# @notionhq/notion-mcp-server가 NOTION_TOKEN을 직접 읽는 케이스 fallback.
NOTION_TOKEN: ${{ secrets.NOTION_TOKEN }}
Comment on lines 51 to +58
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the referenced workflow and the area around the reported lines
echo "=== .github/workflows/claude.yml (around lines 40-80) ==="
nl -ba .github/workflows/claude.yml | sed -n '40,90p'

# Check for any other third-party action refs in the workflow
echo
echo "=== action@ refs in .github/workflows/claude.yml ==="
rg -n "uses:\s*[^/\s]+/[^@\s]+@([^\s]+)" .github/workflows/claude.yml || true

# Check whether anthropics/claude-code-action is pinned elsewhere in the repo
echo
echo "=== anthropics/claude-code-action@ occurrences (repo-wide) ==="
rg -n "anthropics/claude-code-action@" . || true

Repository: code-zero-to-one/study-platform-client

Length of output: 201


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Print the reported region with line numbers (using cat -n)
echo "=== .github/workflows/claude.yml (around lines 40-80) ==="
cat -n .github/workflows/claude.yml | sed -n '40,90p'

# 2) Find any action refs of the form owner/name@ref in this workflow
echo
echo "=== action@ refs in .github/workflows/claude.yml ==="
rg -n "uses:\s*[^/\s]+/[^@\s]+@([^\s]+)" .github/workflows/claude.yml || true

# 3) Check if anthropics/claude-code-action is referenced elsewhere
echo
echo "=== anthropics/claude-code-action@ occurrences (repo-wide) ==="
rg -n "anthropics/claude-code-action@" . || true

Repository: code-zero-to-one/study-platform-client

Length of output: 2676


써드파티 GitHub Actions는 커밋 SHA로 pin 하세요 (moving tag 금지)

  • .github/workflows/claude.yml에서 anthropics/claude-code-action@v1를 사용 중이며, 해당 step이 NOTION_TOKEN을 받고(env) claude_argsWrite 도구 허용이 포함되어 있어(--allowedTools ...Write...) tag 이동/탈취 시 즉시 영향이 큽니다.
  • 같은 이유로 slackapi/slack-github-action@v2.1.0도 SHA로 고정하는 것을 권장합니다( SLACK_BOT_TOKEN 사용).
🧰 Tools
🪛 zizmor (1.25.2)

[error] 51-51: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/claude.yml around lines 51 - 58, Replace movable tags for
third-party GitHub Actions with commit SHAs: update the
anthropics/claude-code-action@v1 reference to its specific commit SHA and do the
same for slackapi/slack-github-action@v2.1.0; keep the same env variables
(OPENAPI_MCP_HEADERS and NOTION_TOKEN) and any claude_args settings but point
the actions to immutable SHAs to prevent tag movement or takeover.

with:
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

# This is an optional setting that allows Claude to read CI results on PRs
additional_permissions: |
actions: read

# 프론트엔드 작업에 필요한 패키지 매니저 명령어 허용
claude_args: '--allowed-tools "Bash(npm *),Bash(yarn *),Bash(pnpm *),Bash(npx *)"'
# 자동 로드된 mcp__notion__*가 LLM에 노출되도록 + 프론트엔드 패키지 매니저 명령어 허용
claude_args: '--allowedTools "mcp__notion__*,Bash(npm *),Bash(yarn *),Bash(pnpm *),Bash(npx *),Edit,Write,Read,Glob,Grep,LS"'

# Claude 응답 완료 시 프론트엔드 Slack 채널에 알림. 성공/실패 모두 통지하여 쿼터 소진 등 에러 상황도 추적 가능하게 함.
- name: Notify Slack on Claude response
Expand Down
Loading