Skip to content

claude-assistant.yml accepts no inputs, so callers must inline the action to set claude_args — forcing a choice between fleet conformance and tool restrictions #141

Description

@twistedmelonman

claude-assistant.yml declares no workflow_call inputs at all — only the claude_oauth_token secret:

$ gh api ".../claude-assistant.yml?ref=v3" --jq .content | base64 -d | sed -n '/^on:/,/^jobs:/p'
on:
  workflow_call:
    secrets:
      claude_oauth_token:
        description: 'Claude Code OAuth token (CLAUDE_CODE_OAUTH_TOKEN secret)'
        required: false

That makes it strictly less capable than claude-blocking-review.yml, which has extra_instructions (plus model, max_turns, timeout_minutes). A repo needing any per-repo assistant customization has only one option: inline anthropics/claude-code-action itself and opt out of the fleet entirely.

Concrete cost, observed

claude-code-workflows-agents did exactly that. Its assistant inlined the action with its own pin — 4481e6d3 = v1.0.131, ~62 releases stale and outside the fleet update path, so no tag repoint could ever reach it (#126 item 1).

Migrating it to the standard stub (smartwatermelon/claude-code-workflows-agents#10) necessarily dropped two things the reusable workflow cannot express:

1. A deliberate tool allowlist — this is a security regression, not a convenience loss.

--allowedTools "Edit,Write,Read,Bash(uv:*),Bash(make:*),Bash(python:*),Bash(ruff:*),
  Bash(ty:*),Bash(pytest:*),Bash(gh pr view:*),Bash(gh pr diff:*),...,
  Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git show:*),
  Bash(git rev-parse:*),Bash(git ls-files:*),mcp__github_inline_comment__create_inline_comment"

Note what it enumerates: read-only git subcommands onlystatus, diff, log, show, rev-parse, ls-files. No push, reset, checkout, clean. Same for gh: view/list/comment/edit, no destructive operations. That is defence-in-depth, deliberately written so destructive variants are unreachable regardless of what the action's defaults permit.

After migration the assistant runs the action's default tool policy. If that default is or becomes permissive, this repo has no local backstop — on a workflow holding id-token: write and CLAUDE_CODE_OAUTH_TOKEN.

2. --model claude-opus-4-7 — a per-repo cost/capability choice, now unavailable.

The structural problem

This creates a false dilemma between two things that should not be in tension:

Choice Cost
Inline the action Leaves the fleet update path; misses security remediation (the #126 defect)
Use the reusable workflow Loses tool restrictions and model control

Nothing about the fleet model requires that trade. claude-blocking-review.yml already solved the equivalent problem with extra_instructions.

Suggested fix

Add pass-through inputs to claude-assistant.yml, mirroring what the blocking reviewer already accepts:

  • claude_args (string, optional) — passed to the action's claude_args, letting callers set --allowedTools, --model, etc.
  • or, narrower and safer: allowed_tools and model as discrete inputs, so the surface is explicit rather than an opaque arg blob.

The narrower form is probably better here: a free-form claude_args lets a caller pass anything, including flags that widen permissions, which is the opposite of what the claude-code-workflows-agents allowlist was doing. Discrete allowed_tools / model inputs make the intent auditable from the caller stub.

Whichever shape, validate it the way #17 validated the reviewer's cost-guard inputs.

Until then

claude-code-workflows-agents runs with default tool permissions. That is a deliberate, documented trade to get it back onto the fleet update path — being 62 releases stale on a security-sensitive action was the larger risk — but it should not stay that way.

Found during the #126 fleet conformance work. Credit to the migrating agent and the adversarial reviewer for flagging it rather than letting it pass as a routine conformance diff.

Refs #126

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions