All skills
Skillintermediate

Action Security Profiles

Security-relevant configuration fields, default behaviors, dangerous configuration patterns, and remediation guidance for each supported AI action. Referenced by SKILL.md Step 5 for action-specific remediation.

Claude Code Knowledge Pack7/10/2026

Overview

Action Security Profiles

Security-relevant configuration fields, default behaviors, dangerous configuration patterns, and remediation guidance for each supported AI action. Referenced by SKILL.md Step 5 for action-specific remediation.

Claude Code Action

Default Security Posture

  • Bash tool disabled by default; commands must be explicitly allowed via --allowedTools in claude_args
  • Only users with repository write access can trigger (default when allowed_non_write_users is omitted)
  • GitHub Apps and bots blocked by default (when allowed_bots is omitted)
  • Commits to new branch, does NOT auto-create PRs (requires human review)
  • Built-in prompt sanitization strips HTML comments, invisible characters, markdown image alt text, hidden HTML attributes, HTML entities
  • show_full_output: false by default (prevents secret leakage in workflow logs)

Dangerous Configurations

ConfigurationRisk
claude_args: "--allowedTools Bash(*)"Unrestricted shell access; any prompt injection achieves full RCE
allowed_non_write_users: "*"Any GitHub user can trigger the action, including external contributors and attackers
allowed_bots: "*"Any bot can trigger, enables automated attack chains via bot-to-bot escalation
show_full_output: true (in public repos)Exposes full conversation including potential secrets in workflow logs
prompt containing ${{ github.event.* }}Direct expression injection of attacker-controlled content into AI prompt

Remediation Patterns

Restrict shell access: Replace Bash(*) with specific tool patterns:

claude_args: '--allowedTools "Bash(npm test:*) Bash(git diff:*)"'

Restrict user access: Remove wildcard allowlists or replace with explicit user lists:

allowed_non_write_users: "trusted-user1,trusted-user2"

Restrict bot access: Remove allowed_bots: "*" or list specific trusted bots:

allowed_bots: "dependabot[bot],renovate[bot]"

Prevent prompt injection: Never pass attacker-controlled event data (issue body, PR title, comment body) to the prompt field via env vars or direct ${{ }} expressions. Validate and sanitize input in a prior step.

Protect log output: Keep show_full_output: false (default) in public repositories.

OpenAI Codex

Default Security Posture

  • Sandbox defaults to workspace-write (read/edit in workspace, run commands locally, no network)
  • Safety strategy defaults to drop-sudo (removes sudo privileges before running Codex)
  • Empty allow-users permits only write-access repository members (default)
  • allow-bots: false by default
  • Network off by default (must be explicitly enabled)
  • Protected paths: .git, .agents/, .codex/ directories are read-only even in writable sandbox

Dangerous Configurations

ConfigurationRisk
sandbox: danger-full-accessNo sandbox, no approvals, unrestricted filesystem and network access
safety-strategy: unsafeDisables all safety enforcement including sudo restrictions
allow-users: "*"Any GitHub user can trigger the action
allow-bots: trueAny bot can trigger, enables automated attack chains
danger-full-access + unsafe combinedMaximum exposure: no sandbox, no safety, full system access

Remediation Patterns

Restrict sandbox: Use the default or a more restrictive mode:

sandbox: workspace-write    # default: workspace access only, no network
sandbox: read-only          # for analysis-only tasks

Restrict safety strategy: Use the default or a stricter option:

safety-strategy: drop-sudo          # default: removes sudo privileges
safety-strategy: unprivileged-user  # stronger: runs as unprivileged user

Restrict user access: Remove wildcard or replace with explicit user list:

allow-users: "maintainer1,maintainer2"

Restrict bot access: Keep allow-bots: false (default) unless specific trusted bots need access.

Organization-level enforcement: Use requirements.toml to block danger-full-access at the organization level, preventing individual repos from weakening sandbox policy.

Gemini CLI

Default Security Posture

  • Sandbox off by default for the GitHub Action (no --sandbox flag set)
  • When sandbox is enabled, default profile is permissive-open (restricts writes outside project directory)
  • Default approval mode requires confirmation for tool calls
  • When --yolo is used, sandbox is enabled automatically (safety measure)
  • Tool restriction via tools.core allowlist in settings JSON (e.g., ["run_shell_command(echo)"])
  • No built-in user allowlist field -- access controlled by workflow trigger permissions only

Dangerous Configurations

ConfigurationRisk
settings: '{"sandbox": false}'Explicitly disables sandbox (note: JSON inside YAML string)
--yolo or --approval-mode=yolo in CLI argsDisables approval prompts for all tool calls
tools.core containing run_shell_command(echo)Enables subshell expansion bypass -- confirmed RCE vector (Vector F)
tools.allowed: ["*"]Bypasses confirmation for all tools

Remediation Patterns

Enable sandbox: Add sandbox configuration to the settings JSON:

settings: '{"sandbox": true}'

Or pass the --sandbox flag in CLI arguments.

Remove dangerous approval modes: Remove --yolo and --approval-mode=yolo from CLI args. Use the default approval mode that requires confirmation for tool calls.

Restrict tool lists: Remove run_shell_command(echo) and other expandable commands from tools.core. Use specific non-shell tools only:

{
  "tools": {
    "core": ["read_file", "write_file", "list_directory"]
  }
}

Container-based sandboxing: If shell access is required, use container-based sandboxing to limit blast radius rather than relying on the built-in sandbox profile alone.

GitHub AI Inference

Default Security Posture

  • Inference-only API call -- no shell access, no filesystem access, no sandbox to configure
  • Access controlled by GitHub token scope
  • Primary risks: prompt injection via untrusted event data (Vector B), and AI output flowing to eval in subsequent workflow steps (Vector G)

Dangerous Configurations

ConfigurationRisk
prompt containing ${{ github.event.* }}Attacker-controlled event contexts injected directly into AI prompt (Vector B)
Overly scoped token parameterGrants more permissions than needed, expanding blast radius of any exploitation
AI output consumed by eval/exec in subsequent stepsConverts inference-only action into code execution vector (Vector G)

Remediation Patterns

Sanitize prompt inputs: Validate and sanitize event data before including in prompts. Do not pass raw ${{ github.event.issue.body }} or similar attacker-controlled fields.

Minimize token scope: Use minimum-scope tokens following the principle of least privilege. Only grant permissions the inference call actually needs.

Protect AI output consumption: Never pass AI output through eval, exec, or unquoted $() in subsequent workflow steps:

# DANGEROUS: AI output executed as code
- run: eval "${{ steps.inference.outputs.result }}"

# SAFE: AI output stored and validated before use
- run: |
    RESULT='${{ steps.inference.outputs.result }}'
    echo "$RESULT"  # display only, no execution

Validate structured output: If structured output (JSON) is needed from the AI, validate against a schema before using in shell commands.

Per-Action Remediation Quick Reference

Remediation NeedClaude Code ActionOpenAI CodexGemini CLIGitHub AI Inference
Restrict shell access--allowedTools "Bash(specific:*)"sandbox: workspace-writeRemove expandable commands from tools.coreN/A (no shell)
Restrict user accessallowed_non_write_users: "user1,user2"allow-users: "user1,user2"Control via workflow trigger permissionsControl via token scope
Disable dangerous modeRemove Bash(*) from claude_argsRemove danger-full-access from sandboxRemove --yolo from CLI argsN/A
Sandbox enforcementN/A (tool-level restriction)sandbox: read-only"sandbox": true in settings JSONN/A (no execution)
Block bot triggersRemove allowed_bots: "*"Set allow-bots: falseControl via workflow trigger conditionsControl via token scope
Protect output/logsKeep show_full_output: falseN/AN/ANever eval AI output