mirror of
https://github.com/anthropics/claude-code-action.git
synced 2026-08-22 03:18:54 +08:00
557 lines
22 KiB
Markdown
557 lines
22 KiB
Markdown
# Claude Code Base Action
|
||
|
||
This GitHub Action allows you to run [Claude Code](https://www.anthropic.com/claude-code) within your GitHub Actions workflows. You can use this to build any custom workflow on top of Claude Code.
|
||
|
||
For simply tagging @claude in issues and PRs out of the box, [check out the Claude Code action and GitHub app](https://github.com/anthropics/claude-code-action).
|
||
|
||
## Trust model
|
||
|
||
This action is a thin wrapper that installs and runs Claude Code with the inputs you provide. It does **not** enforce any trust boundaries on its own. Running this action in a directory is equivalent to running Claude Code in that directory — Claude reads project-level configuration (`.claude/`, `CLAUDE.md`, `.mcp.json`, etc.) from the working directory, and the action's own setup steps run from there as well.
|
||
|
||
**The caller is responsible for ensuring the working directory and prompt are trusted.** If your workflow processes untrusted input (issues, fork pull requests, external comments), use [`anthropics/claude-code-action`](https://github.com/anthropics/claude-code-action) instead — it provides actor permission checks, restores project configuration from the base ref in PR contexts, and is the supported path for those scenarios.
|
||
|
||
See [Claude Code's security documentation](https://docs.anthropic.com/en/docs/claude-code/security) and the [GitHub Actions guidance on `pull_request_target`](https://securitylab.github.com/research/github-actions-preventing-pwn-requests/) for background.
|
||
|
||
## Usage
|
||
|
||
Add the following to your workflow file:
|
||
|
||
```yaml
|
||
# Using a direct prompt
|
||
- name: Run Claude Code with direct prompt
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"'
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# Or using a prompt from a file
|
||
- name: Run Claude Code with prompt file
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt_file: "/path/to/prompt.txt"
|
||
claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"'
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# Or limiting the conversation turns
|
||
- name: Run Claude Code with limited turns
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
claude_args: |
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
--max-turns 5
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# Using custom system prompts
|
||
- name: Run Claude Code with custom system prompt
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Build a REST API"
|
||
claude_args: |
|
||
--system-prompt "You are a senior backend engineer. Focus on security, performance, and maintainability."
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# Or appending to the default system prompt
|
||
- name: Run Claude Code with appended system prompt
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Create a database schema"
|
||
claude_args: |
|
||
--append-system-prompt "After writing code, be sure to code review yourself."
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# Using custom environment variables
|
||
- name: Run Claude Code with custom environment variables
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Deploy to staging environment"
|
||
settings: |
|
||
{
|
||
"env": {
|
||
"ENVIRONMENT": "staging",
|
||
"API_URL": "https://api-staging.example.com",
|
||
"DEBUG": "true"
|
||
}
|
||
}
|
||
claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"'
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# Using fallback model for handling API errors
|
||
- name: Run Claude Code with fallback model
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Review and fix TypeScript errors"
|
||
claude_args: |
|
||
--model "claude-opus-4-1-20250805"
|
||
--fallback-model "claude-sonnet-4-20250514"
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# Using OAuth token instead of API key
|
||
- name: Run Claude Code with OAuth token
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Update dependencies"
|
||
claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"'
|
||
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
|
||
```
|
||
|
||
### Workload Identity Federation
|
||
|
||
Instead of a static API key or OAuth token, you can authenticate via [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation): the action fetches the workflow's GitHub OIDC token and the Claude Code CLI exchanges it for a short-lived access token. Requires the `id-token: write` permission on the job:
|
||
|
||
```yaml
|
||
permissions:
|
||
contents: read
|
||
id-token: write
|
||
|
||
steps:
|
||
- name: Run Claude Code with workload identity federation
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
anthropic_federation_rule_id: fdrl_xxxxxxxxxxxx
|
||
anthropic_organization_id: 00000000-0000-0000-0000-000000000000
|
||
anthropic_service_account_id: svac_xxxxxxxxxxxx
|
||
```
|
||
|
||
Do not set `anthropic_api_key` or `claude_code_oauth_token` alongside the federation inputs — a static credential takes precedence and federation will not be used.
|
||
|
||
## Inputs
|
||
|
||
| Input | Description | Required | Default |
|
||
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ------------- |
|
||
| `prompt` | The prompt to send to Claude Code | No\* | `''` |
|
||
| `prompt_file` | Path to a file containing the prompt to send to Claude Code | No\* | `''` |
|
||
| `settings` | Claude Code settings as a JSON string or path to a settings JSON file | No | `''` |
|
||
| `claude_args` | Additional arguments to pass directly to the Claude CLI | No | `''` |
|
||
| `anthropic_api_key` | Anthropic API key for direct Anthropic API authentication | No | `''` |
|
||
| `claude_code_oauth_token` | Claude Code OAuth token as an alternative to an Anthropic API key | No | `''` |
|
||
| `anthropic_federation_rule_id` | Workload identity federation rule ID (fdrl\_...). Requires `id-token: write` permission | No | `''` |
|
||
| `anthropic_organization_id` | Anthropic organization UUID used for workload identity federation | No | `''` |
|
||
| `anthropic_service_account_id` | Service account ID (svac\_...) the federated token acts as | No | `''` |
|
||
| `anthropic_workspace_id` | Workspace ID (wrkspc\_...) for federation | No | `''` |
|
||
| `anthropic_oidc_audience` | Audience for the GitHub OIDC token request | No | `''` |
|
||
| `use_bedrock` | Use Amazon Bedrock with OIDC authentication | No | `'false'` |
|
||
| `use_vertex` | Use Google Vertex AI with OIDC authentication | No | `'false'` |
|
||
| `use_foundry` | Use Microsoft Foundry with OIDC authentication | No | `'false'` |
|
||
| `use_node_cache` | Enable Node.js dependency caching for projects with lock files | No | `'false'` |
|
||
| `path_to_claude_code_executable` | Path to a custom Claude Code executable | No | `''` |
|
||
| `path_to_bun_executable` | Path to a custom Bun executable | No | `''` |
|
||
| `show_full_output` | Show full JSON output (⚠️ May expose secrets - see [security docs](../docs/security.md#️-full-output-security-warning)) | No | `'false'`\*\* |
|
||
| `plugins` | Newline-separated Claude Code plugin names to install | No | `''` |
|
||
| `plugin_marketplaces` | Newline-separated plugin marketplace Git URLs to install | No | `''` |
|
||
|
||
\*Either `prompt` or `prompt_file` must be provided, but not both.
|
||
|
||
\*\*`show_full_output` is automatically enabled when GitHub Actions debug mode is active. See [security documentation](../docs/security.md#️-full-output-security-warning) for important security considerations.
|
||
|
||
## Outputs
|
||
|
||
| Output | Description |
|
||
| ------------------- | ------------------------------------------------------------------------------------------------- |
|
||
| `conclusion` | Execution status of Claude Code ('success' or 'failure') |
|
||
| `execution_file` | Path to the JSON file containing Claude Code execution log |
|
||
| `structured_output` | JSON string containing structured output fields when `--json-schema` is provided in `claude_args` |
|
||
| `session_id` | The Claude Code session ID that can be used with `--resume` to continue this conversation |
|
||
|
||
## Environment Variables
|
||
|
||
The following environment variables can be used to configure the action:
|
||
|
||
| Variable | Description | Default |
|
||
| -------------- | ----------------------------------------------------- | ------- |
|
||
| `NODE_VERSION` | Node.js version to use (e.g., '18.x', '20.x', '22.x') | '18.x' |
|
||
|
||
Example usage:
|
||
|
||
```yaml
|
||
- name: Run Claude Code with Node.js 20
|
||
uses: anthropics/claude-code-base-action@beta
|
||
env:
|
||
NODE_VERSION: "20.x"
|
||
with:
|
||
prompt: "Your prompt here"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
## Custom Environment Variables
|
||
|
||
You can pass custom environment variables to Claude Code through the `env` object in `settings`:
|
||
|
||
```yaml
|
||
- name: Deploy with custom environment
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Deploy the application to the staging environment"
|
||
settings: |
|
||
{
|
||
"env": {
|
||
"ENVIRONMENT": "staging",
|
||
"API_BASE_URL": "https://api-staging.example.com",
|
||
"DATABASE_URL": "${{ secrets.STAGING_DB_URL }}",
|
||
"DEBUG": "true",
|
||
"LOG_LEVEL": "debug"
|
||
}
|
||
}
|
||
claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"'
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
The `settings` input accepts either inline JSON or a path to a settings JSON file. Values in the `env` object are available during the Claude Code session and can reference GitHub secrets.
|
||
|
||
## Using Settings Configuration
|
||
|
||
You can provide Claude Code settings configuration in two ways:
|
||
|
||
### Option 1: Settings Configuration File
|
||
|
||
Provide a path to a JSON file containing Claude Code settings:
|
||
|
||
```yaml
|
||
- name: Run Claude Code with settings file
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
settings: "path/to/settings.json"
|
||
claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"'
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
### Option 2: Inline Settings Configuration
|
||
|
||
Provide the settings configuration directly as a JSON string:
|
||
|
||
```yaml
|
||
- name: Run Claude Code with inline settings
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
settings: |
|
||
{
|
||
"model": "claude-opus-4-1-20250805",
|
||
"env": {
|
||
"DEBUG": "true",
|
||
"API_URL": "https://api.example.com"
|
||
},
|
||
"permissions": {
|
||
"allow": ["Bash", "Read"],
|
||
"deny": ["WebFetch"]
|
||
},
|
||
"hooks": {
|
||
"PreToolUse": [{
|
||
"matcher": "Bash",
|
||
"hooks": [{
|
||
"type": "command",
|
||
"command": "echo Running bash command..."
|
||
}]
|
||
}]
|
||
}
|
||
}
|
||
claude_args: '--allowedTools "Bash(git:*),Read,Glob,Grep"'
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
The settings file supports all Claude Code settings options including:
|
||
|
||
- `model`: Override the default model
|
||
- `env`: Environment variables for the session
|
||
- `permissions`: Tool usage permissions
|
||
- `hooks`: Pre/post tool execution hooks
|
||
- `includeCoAuthoredBy`: Include co-authored-by in git commits
|
||
- And more...
|
||
|
||
**Note**: The `enableAllProjectMcpServers` setting is always set to `true` by this action to ensure MCP servers work correctly.
|
||
|
||
## Using MCP Config
|
||
|
||
You can provide MCP configuration in two ways:
|
||
|
||
### Option 1: MCP Configuration File
|
||
|
||
Provide a path to a JSON file containing MCP configuration:
|
||
|
||
```yaml
|
||
- name: Run Claude Code with MCP config file
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
claude_args: |
|
||
--mcp-config "path/to/mcp-config.json"
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
### Option 2: Inline MCP Configuration
|
||
|
||
Provide the MCP configuration directly as a JSON string:
|
||
|
||
```yaml
|
||
- name: Run Claude Code with inline MCP config
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
claude_args: >-
|
||
--mcp-config '{"mcpServers":{"server-name":{"command":"node","args":["./server.js"],"env":{"API_KEY":"your-api-key"}}}}'
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
The MCP config file should follow this format:
|
||
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"server-name": {
|
||
"command": "node",
|
||
"args": ["./server.js"],
|
||
"env": {
|
||
"API_KEY": "your-api-key"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
You can combine MCP config with other inputs like allowed tools:
|
||
|
||
```yaml
|
||
# Using multiple inputs together
|
||
- name: Run Claude Code with MCP and custom tools
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Access the custom MCP server and use its tools"
|
||
claude_args: |
|
||
--mcp-config "mcp-config.json"
|
||
--allowedTools "Bash(git:*),Read,mcp__server-name__custom_tool"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
## Example: PR Code Review
|
||
|
||
```yaml
|
||
name: Claude Code Review
|
||
|
||
on:
|
||
pull_request:
|
||
types: [opened, synchronize]
|
||
|
||
jobs:
|
||
code-review:
|
||
runs-on: ubuntu-latest
|
||
steps:
|
||
- name: Checkout code
|
||
uses: actions/checkout@v6
|
||
with:
|
||
fetch-depth: 0
|
||
|
||
- name: Run Code Review with Claude
|
||
id: code-review
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Review the PR changes. Focus on code quality, potential bugs, and performance issues. Suggest improvements where appropriate. Write your review as markdown text."
|
||
claude_args: '--allowedTools "Bash(git diff --name-only HEAD~1),Bash(git diff HEAD~1),Read,Glob,Grep,Write"'
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
- name: Extract and Comment PR Review
|
||
if: steps.code-review.outputs.conclusion == 'success'
|
||
uses: actions/github-script@v7
|
||
with:
|
||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||
script: |
|
||
const fs = require('fs');
|
||
const executionFile = '${{ steps.code-review.outputs.execution_file }}';
|
||
const executionLog = JSON.parse(fs.readFileSync(executionFile, 'utf8'));
|
||
|
||
// Extract the review content from the execution log.
|
||
// The SDK writes top-level events with `type`; assistant text is nested
|
||
// under `message.content`.
|
||
let review = '';
|
||
|
||
// Prefer the final result event when it is available.
|
||
for (let i = executionLog.length - 1; i >= 0; i--) {
|
||
const entry = executionLog[i];
|
||
if (entry?.type === 'result' && typeof entry.result === 'string') {
|
||
review = entry.result;
|
||
break;
|
||
}
|
||
}
|
||
|
||
// Fallback to the last assistant text block if no result event was written.
|
||
if (!review) {
|
||
for (let i = executionLog.length - 1; i >= 0; i--) {
|
||
const entry = executionLog[i];
|
||
if (entry?.type !== 'assistant' || !Array.isArray(entry.message?.content)) {
|
||
continue;
|
||
}
|
||
|
||
review = entry.message.content
|
||
.filter((block) => block?.type === 'text' && typeof block.text === 'string')
|
||
.map((block) => block.text)
|
||
.join('\n');
|
||
|
||
if (review) {
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (review) {
|
||
github.rest.issues.createComment({
|
||
issue_number: context.issue.number,
|
||
owner: context.repo.owner,
|
||
repo: context.repo.repo,
|
||
body: "## Claude Code Review\n\n" + review + "\n\n*Generated by Claude Code*"
|
||
});
|
||
}
|
||
```
|
||
|
||
For typed automation output, prefer passing `--json-schema` in `claude_args`
|
||
and reading `steps.<id>.outputs.structured_output` instead of parsing the full
|
||
execution log.
|
||
|
||
Check out additional examples in [`./examples`](./examples).
|
||
|
||
## Using Cloud Providers
|
||
|
||
You can authenticate with Claude using any of these methods:
|
||
|
||
1. Direct Anthropic API (default) - requires API key or OAuth token
|
||
2. Amazon Bedrock - requires OIDC authentication and automatically uses cross-region inference profiles
|
||
3. Google Vertex AI - requires OIDC authentication
|
||
|
||
**Note**:
|
||
|
||
- Bedrock and Vertex use OIDC authentication exclusively
|
||
- AWS Bedrock automatically uses cross-region inference profiles for certain models
|
||
- For cross-region inference profile models, you need to request and be granted access to the Claude models in all regions that the inference profile uses
|
||
- The Bedrock API endpoint URL is automatically constructed using the AWS_REGION environment variable (e.g., `https://bedrock-runtime.us-west-2.amazonaws.com`)
|
||
- You can override the Bedrock API endpoint URL by setting the `ANTHROPIC_BEDROCK_BASE_URL` environment variable
|
||
|
||
### Model Configuration
|
||
|
||
Use provider-specific model names based on your chosen provider:
|
||
|
||
```yaml
|
||
# For direct Anthropic API (default)
|
||
- name: Run Claude Code with Anthropic API
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
claude_args: "--model claude-3-7-sonnet-20250219"
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
|
||
# For Amazon Bedrock (requires OIDC authentication)
|
||
- name: Configure AWS Credentials (OIDC)
|
||
uses: aws-actions/configure-aws-credentials@v4
|
||
with:
|
||
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
|
||
aws-region: us-west-2
|
||
|
||
- name: Run Claude Code with Bedrock
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
claude_args: "--model anthropic.claude-3-7-sonnet-20250219-v1:0"
|
||
use_bedrock: "true"
|
||
|
||
# For Google Vertex AI (requires OIDC authentication)
|
||
- name: Authenticate to Google Cloud
|
||
uses: google-github-actions/auth@v2
|
||
with:
|
||
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
|
||
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
|
||
|
||
- name: Run Claude Code with Vertex AI
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
claude_args: "--model claude-3-7-sonnet@20250219"
|
||
use_vertex: "true"
|
||
```
|
||
|
||
## Example: Using OIDC Authentication for AWS Bedrock
|
||
|
||
This example shows how to use OIDC authentication with AWS Bedrock:
|
||
|
||
```yaml
|
||
- name: Configure AWS Credentials (OIDC)
|
||
uses: aws-actions/configure-aws-credentials@v4
|
||
with:
|
||
role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
|
||
aws-region: us-west-2
|
||
|
||
- name: Run Claude Code with AWS OIDC
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
use_bedrock: "true"
|
||
claude_args: |
|
||
--model "anthropic.claude-3-7-sonnet-20250219-v1:0"
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
```
|
||
|
||
## Example: Using OIDC Authentication for GCP Vertex AI
|
||
|
||
This example shows how to use OIDC authentication with GCP Vertex AI:
|
||
|
||
```yaml
|
||
- name: Authenticate to Google Cloud
|
||
uses: google-github-actions/auth@v2
|
||
with:
|
||
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }}
|
||
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT }}
|
||
|
||
- name: Run Claude Code with GCP OIDC
|
||
uses: anthropics/claude-code-base-action@beta
|
||
with:
|
||
prompt: "Your prompt here"
|
||
use_vertex: "true"
|
||
claude_args: |
|
||
--model "claude-3-7-sonnet@20250219"
|
||
--allowedTools "Bash(git:*),Read,Glob,Grep"
|
||
```
|
||
|
||
## Security Best Practices
|
||
|
||
**⚠️ IMPORTANT: Never commit API keys directly to your repository! Always use GitHub Actions secrets.**
|
||
|
||
To securely use your Anthropic API key:
|
||
|
||
1. Add your API key as a repository secret:
|
||
|
||
- Go to your repository's Settings
|
||
- Navigate to "Secrets and variables" → "Actions"
|
||
- Click "New repository secret"
|
||
- Name it `ANTHROPIC_API_KEY`
|
||
- Paste your API key as the value
|
||
|
||
2. Reference the secret in your workflow:
|
||
```yaml
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
**Never do this:**
|
||
|
||
```yaml
|
||
# ❌ WRONG - Exposes your API key
|
||
anthropic_api_key: "sk-ant-..."
|
||
```
|
||
|
||
**Always do this:**
|
||
|
||
```yaml
|
||
# ✅ CORRECT - Uses GitHub secrets
|
||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||
```
|
||
|
||
This applies to all sensitive values including API keys, access tokens, and credentials.
|
||
We also recommend that you always use short-lived tokens when possible
|
||
|
||
## License
|
||
|
||
This project is licensed under the MIT License—see the LICENSE file for details.
|