Skip to content

fix: credentials JSON 生成を python3 に統一し特殊文字問題を解消 - #636

Merged
keito4 merged 1 commit into
mainfrom
fix/plugin-install-as-vscode-user
Mar 23, 2026
Merged

fix: credentials JSON 生成を python3 に統一し特殊文字問題を解消#636
keito4 merged 1 commit into
mainfrom
fix/plugin-install-as-vscode-user

Conversation

@keito4

@keito4 keito4 commented Mar 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • トークンの credentials JSON 生成を heredoc から python3 json.dump に変更
  • トークン文字列に $ や backtick 等の特殊文字が含まれる場合のシェル展開問題を解消

Why

前回の修正(PR #635)でビルドは成功したが、プラグインインストールがトークン変換直後にクラッシュしていた。原因は heredoc 内でのトークン展開時にシェルの特殊文字が展開されていたため。

Test plan

  • ビルドログで known_marketplaces.json を生成しました まで到達すること
  • Claude version: x.x.x が表示されること

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Improved the credential installation process for Claude plugins by refactoring token handling logic.

heredoc でトークンを展開すると $ や backtick 等の特殊文字で
シェルが壊れる問題があった。python3 の json.dump で安全に生成。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Mar 23, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Refactored credential JSON construction in the Claude plugin installer script by replacing heredoc-based syntax with Python-based JSON serialization. The change affects token-providing branches (BuildKit secrets and OAuth tokens) while maintaining existing control flow and the JSON-secret copy-as-is path.

Changes

Cohort / File(s) Summary
Credential JSON Generation
script/install-claude-plugins.sh
Replaced heredoc-based multi-line JSON literals with python3 -c calls using json.dump() for programmatic serialization. Updated token-providing branches (CREDENTIALS_SECRET, CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY) to construct claudeAiOauth.accessToken and expiresAt fields dynamically.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Suggested labels

released, size/XS

Poem

🐰 A token finds its Python home,
No heredoc forests need to roam,
JSON serialized, oh what a sight,
Credentials flowing, oh so tight! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: replacing heredoc-based JSON credential generation with python3 to fix special character issues.
Description check ✅ Passed The description follows the template structure with Summary, Why, and test plan sections. All critical sections are present and adequately filled out.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/plugin-install-as-vscode-user

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@keito4

keito4 commented Mar 23, 2026

Copy link
Copy Markdown
Owner Author

🔍 AI Code Review (Local Hook)

Models: Codex (default) / Gemini (default)

🤖 Codex Review

指摘事項はありません。

判定
patch is correct。変更はJSON生成をPython経由に置き換えただけで、既存の挙動・依存関係(python3)を壊さず、出力も有効なJSONのままです。
信頼度: 0.62


🤖 Generated by post_pr_ai_review.py hook

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 96040713d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

creds = {'claudeAiOauth': {'accessToken': token, 'expiresAt': 9999999999999}}
with open(sys.argv[2], 'w') as f:
json.dump(creds, f, indent=2)
" "$SECRET_CONTENT" "${CLAUDE_DIR}/.credentials.json"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Avoid leaking OAuth tokens via process arguments

Passing "$SECRET_CONTENT"/"$CLAUDE_CODE_OAUTH_TOKEN"/"$ANTHROPIC_API_KEY" as positional args to python3 -c exposes the raw credential in the child process command line (/proc/<pid>/cmdline, ps), so any co-tenant process with proc access during build can read the token. This regression is introduced by the new Python conversion path and is a security downgrade from the previous heredoc approach, which did not place secrets in argv.

Useful? React with 👍 / 👎.

@keito4 keito4 self-assigned this Mar 23, 2026
@claude

claude Bot commented Mar 23, 2026

Copy link
Copy Markdown
Contributor

コードレビュー: CI はすべて通過。特殊文字問題への json.dump 対処は正しいです。気になった点: (1) セキュリティ: トークンを sys.argv[1] で渡すと ps aux に平文表示される可能性あり。TOKEN 環境変数経由が安全です。(2) DRY 違反: 同一 python3 スニペットが 3 箇所重複。ヘルパー関数への抽出を推奨。良い点: json.dump で正確なエスケープ、3 パス一貫対処、python3 は既存依存。Reviewed by Claude Sonnet 4.6

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
script/install-claude-plugins.sh (2)

71-77: Consider passing the token via stdin instead of command-line argument.

Command-line arguments are visible in process listings (ps aux). While this is during Docker build time (limited exposure), passing sensitive tokens via stdin is a more secure pattern.

♻️ Proposed fix using stdin
-        python3 -c "
-import json, sys
-token = sys.argv[1]
-creds = {'claudeAiOauth': {'accessToken': token, 'expiresAt': 9999999999999}}
-with open(sys.argv[2], 'w') as f:
-    json.dump(creds, f, indent=2)
-" "$SECRET_CONTENT" "${CLAUDE_DIR}/.credentials.json"
+        printf '%s' "$SECRET_CONTENT" | python3 -c "
+import json, sys
+token = sys.stdin.read()
+creds = {'claudeAiOauth': {'accessToken': token, 'expiresAt': 9999999999999}}
+with open(sys.argv[1], 'w') as f:
+    json.dump(creds, f, indent=2)
+" "${CLAUDE_DIR}/.credentials.json"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@script/install-claude-plugins.sh` around lines 71 - 77, The current inline
Python reads the token from sys.argv[1], exposing it on the command line; change
the inline script used in the python3 -c call to read the token from stdin
(e.g., read and strip sys.stdin content instead of using sys.argv), update the
invocation to pipe the SECRET_CONTENT into python (remove passing the token as a
positional argument), and still write the resulting JSON to
"${CLAUDE_DIR}/.credentials.json"; update references in the script around the
python3 -c block and adjust the use of SECRET_CONTENT and the target file
accordingly.

71-77: Extract repeated JSON generation logic into a helper function.

The same Python snippet appears three times. A shell function would reduce duplication and simplify future maintenance.

♻️ Proposed helper function

Add this function near the top of the script (after library loading):

# Helper: Write credentials JSON from a token string
write_credentials_json() {
    local token="$1"
    local output_file="$2"
    printf '%s' "$token" | python3 -c "
import json, sys
token = sys.stdin.read()
creds = {'claudeAiOauth': {'accessToken': token, 'expiresAt': 9999999999999}}
with open(sys.argv[1], 'w') as f:
    json.dump(creds, f, indent=2)
" "$output_file"
}

Then replace the three code blocks with:

         # プレーンテキスト(トークン文字列): JSON に変換
         log_info "トークン文字列を credentials JSON に変換中..."
-        python3 -c "
-import json, sys
-token = sys.argv[1]
-creds = {'claudeAiOauth': {'accessToken': token, 'expiresAt': 9999999999999}}
-with open(sys.argv[2], 'w') as f:
-    json.dump(creds, f, indent=2)
-" "$SECRET_CONTENT" "${CLAUDE_DIR}/.credentials.json"
+        write_credentials_json "$SECRET_CONTENT" "${CLAUDE_DIR}/.credentials.json"
     log_info "CLAUDE_CODE_OAUTH_TOKEN から認証情報を作成中..."
-    python3 -c "
-import json, sys
-token = sys.argv[1]
-creds = {'claudeAiOauth': {'accessToken': token, 'expiresAt': 9999999999999}}
-with open(sys.argv[2], 'w') as f:
-    json.dump(creds, f, indent=2)
-" "$CLAUDE_CODE_OAUTH_TOKEN" "${CLAUDE_DIR}/.credentials.json"
+    write_credentials_json "$CLAUDE_CODE_OAUTH_TOKEN" "${CLAUDE_DIR}/.credentials.json"
     log_info "ANTHROPIC_API_KEY から認証情報を作成中..."
-    python3 -c "
-import json, sys
-token = sys.argv[1]
-creds = {'claudeAiOauth': {'accessToken': token, 'expiresAt': 9999999999999}}
-with open(sys.argv[2], 'w') as f:
-    json.dump(creds, f, indent=2)
-" "$ANTHROPIC_API_KEY" "${CLAUDE_DIR}/.credentials.json"
+    write_credentials_json "$ANTHROPIC_API_KEY" "${CLAUDE_DIR}/.credentials.json"

Also applies to: 82-88, 91-97

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@script/install-claude-plugins.sh` around lines 71 - 77, Extract the repeated
Python JSON-generation snippet into a shell helper function (e.g.,
write_credentials_json) defined near the top after library loading; the function
should accept a token and an output file, invoke python3 to read the token and
write the creds JSON with the fixed expiresAt, and then replace the three inline
python3 blocks (the occurrences around lines 71-77, 82-88, 91-97) with calls to
write_credentials_json "$SECRET_CONTENT" "${CLAUDE_DIR}/.credentials.json" (or
the appropriate token/output args for each use).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@script/install-claude-plugins.sh`:
- Around line 71-77: The current inline Python reads the token from sys.argv[1],
exposing it on the command line; change the inline script used in the python3 -c
call to read the token from stdin (e.g., read and strip sys.stdin content
instead of using sys.argv), update the invocation to pipe the SECRET_CONTENT
into python (remove passing the token as a positional argument), and still write
the resulting JSON to "${CLAUDE_DIR}/.credentials.json"; update references in
the script around the python3 -c block and adjust the use of SECRET_CONTENT and
the target file accordingly.
- Around line 71-77: Extract the repeated Python JSON-generation snippet into a
shell helper function (e.g., write_credentials_json) defined near the top after
library loading; the function should accept a token and an output file, invoke
python3 to read the token and write the creds JSON with the fixed expiresAt, and
then replace the three inline python3 blocks (the occurrences around lines
71-77, 82-88, 91-97) with calls to write_credentials_json "$SECRET_CONTENT"
"${CLAUDE_DIR}/.credentials.json" (or the appropriate token/output args for each
use).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a10a49f0-4463-4086-a3c2-9d3806667135

📥 Commits

Reviewing files that changed from the base of the PR and between 821a647 and 9604071.

📒 Files selected for processing (1)
  • script/install-claude-plugins.sh

@keito4
keito4 merged commit 5d84b99 into main Mar 23, 2026
21 checks passed
@keito4
keito4 deleted the fix/plugin-install-as-vscode-user branch March 23, 2026 08:27
@github-actions

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.106.4 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

released リリース済み

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant