Skip to content

Support github-app: auth and Claude Code plugin registration for dependencies: (APM) #21243

@holwerda

Description

@holwerda

Problem

The dependencies: frontmatter (APM) works for public packages but fails for cross-org private repos because the APM action only has access to the default GITHUB_TOKEN, which is scoped to the current repository's org.

In local Claude Code, we install marketplace plugins like this:

/plugin marketplace add https://github.com/some-org/some-claude-marketplace.git
/plugin install <plugin-name>

This registers the plugin's skills so they're invocable via the Skill tool. We'd like to replicate this in gh-aw workflows using dependencies:, but we've hit two issues:

  1. Auth: APM can't access cross-org private repos (the marketplace add equivalent)
  2. Plugin wiring: It's unclear whether APM-installed plugins are registered with Claude Code's Skill tool (the plugin install equivalent)

What works today

dependencies:
  - acme-platform-org/acme-skills/plugins/dev-tools

engine: claude

This compiles cleanly (v0.57.2) and the APM action runs, but installation fails:

Installing 1 inline dependencies...
/usr/local/bin/apm install acme-platform-org/acme-skills/plugins/dev-tools
✗ acme-platform-org/acme-skills/plugins/dev-tools - not accessible or doesn't exist

The package exists but the workflow runs in a repo under acme-services-org/ — a different org. The default GITHUB_TOKEN has no cross-org access.

Why this matters

Teams commonly keep shared skill packages in a central org (e.g., a platform team org) while the consuming repos live in separate org(s). This is the standard pattern for internal marketplace/plugin ecosystems. Without cross-org auth for APM, dependencies: is limited to same-org or public packages.

Use Case

Our team maintains a Claude Code marketplace plugin (acme-platform-org/acme-skills) with reusable skills (codebase analysis, multi-perspective code review, design analysis). Our service repos live in acme-services-org/. We want to declare the marketplace plugin as a dependency in our workflow frontmatter so it's pre-installed when the agent starts.

We already use a GitHub App for cross-org access in tools: and safe-outputs::

tools:
  github:
    toolsets: [issues, repos, pull_requests]
    github-app:
      app-id: ${{ vars.APP_ID }}
      private-key: ${{ secrets.APP_PRIVATE_KEY }}
      repositories: ["*"]

But the compiled workflow generates the GitHub App token after the APM install step, so APM never gets the cross-org token.

Proposed Solution

Two things need to work for this to be useful:

Part 1: Auth — github-app: for dependencies:

Support github-app: in dependencies:, consistent with how it already works in tools: and safe-outputs:.

Option A: Default github-app: for all dependencies

dependencies:
  github-app:
    app-id: ${{ vars.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
  packages:
    - acme-platform-org/acme-skills/plugins/dev-tools
    - acme-platform-org/another-package

A single GitHub App token is generated before apm install and set as GITHUB_TOKEN for the APM step. All dependencies use the same token.

Option B: Per-dependency github-app: overrides

dependencies:
  github-app:
    app-id: ${{ vars.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
  packages:
    - acme-platform-org/acme-skills/plugins/dev-tools
    - source: partner-org/partner-package
      github-app:
        app-id: ${{ vars.PARTNER_APP_ID }}
        private-key: ${{ secrets.PARTNER_APP_PRIVATE_KEY }}

Each dependency can specify its own GitHub App when packages span multiple orgs with different app installations. A default github-app: applies to all dependencies that don't override it.

Option C: Reuse tools.github.github-app

If a github-app: is already configured under tools.github, the compiler could generate the app token before the APM step and make it available. No additional config needed:

tools:
  github:
    toolsets: [issues, repos]
    github-app:
      app-id: ${{ vars.APP_ID }}
      private-key: ${{ secrets.APP_PRIVATE_KEY }}
      repositories: ["*"]

dependencies:
  - acme-platform-org/acme-skills/plugins/dev-tools
# ^ automatically uses the github-app token from tools.github

This is the simplest option but doesn't support per-dependency overrides.

Recommended: Option A + B combined

Support both a default and per-dependency github-app:, falling back to the simple array syntax when no auth is needed:

# Simple case — public or same-org packages (works today)
dependencies:
  - microsoft/apm-sample-package

# Cross-org with default auth
dependencies:
  github-app:
    app-id: ${{ vars.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
  packages:
    - acme-platform-org/acme-skills/plugins/dev-tools

# Multi-org with per-dependency auth
dependencies:
  github-app:
    app-id: ${{ vars.APP_ID }}
    private-key: ${{ secrets.APP_PRIVATE_KEY }}
  packages:
    - acme-platform-org/acme-skills/plugins/dev-tools
    - source: partner-org/partner-package
      github-app:
        app-id: ${{ vars.PARTNER_APP_ID }}
        private-key: ${{ secrets.PARTNER_APP_PRIVATE_KEY }}

Part 2: Plugin Wiring — Register plugins with Claude Code's Skill tool

When a dependencies: entry points to a Claude Code plugin (a directory containing a plugin.json manifest), the installed plugin's skills should be registered and invocable via the Skill tool at agent runtime.

Currently, APM deploys primitives into .github/ but it's unclear whether Claude Code plugins are wired up so the agent can actually invoke their skills. In our testing, even when APM successfully deployed primitives, the agent's init message still showed "plugins": [].

Expected behavior: If a dependency contains a plugin.json, the agent should see the plugin's skills in its init message and be able to invoke them:

{
  "skills": ["debug", "simplify", "batch", "dev-tools:analyze", "dev-tools:prime", "dev-tools:code-review"],
  "plugins": ["dev-tools"]
}

Question for the team: Is this already supported and we're just missing something in how we reference the plugin path? Or does this require new work to bridge APM-installed plugins into Claude Code's plugin/skill registry?

Implementation Notes

For Part 1 (Auth)

In the compiled lock file, the change would be:

  1. Generate the GitHub App token(s) before the "Install APM dependencies" step
  2. Pass the token to the APM action via environment variable (GITHUB_TOKEN) or a new token input on microsoft/apm-action

Current ordering (broken for cross-org):

1. Install Claude Code CLI
2. Install APM dependencies  ← no cross-org token available
3. Generate GitHub App token ← too late

Fixed ordering:

1. Install Claude Code CLI
2. Generate GitHub App token ← moved up
3. Install APM dependencies  ← now has cross-org access

For Part 2 (Plugin Wiring)

APM needs to either:

  • Deploy the plugin.json to a location that Claude Code scans at startup, or
  • Invoke the equivalent of /plugin install after deploying the plugin files

This may require coordination between gh-aw, APM, and Claude Code CLI.

Environment

  • Compiler: gh-aw v0.57.2
  • APM: v0.7.7 (microsoft/apm-action@v1)
  • Feature: dependencies: (experimental)

Metadata

Metadata

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions