Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/patch-copilot-app-auth.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .changeset/patch-document-copilot-github-app-auth.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions .github/workflows/shared/copilot-app.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
engine:
id: copilot
app:
app-id: ${{ vars.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}
---

<!--

# GitHub Copilot with App Authentication

Copy link
Contributor

Choose a reason for hiding this comment

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

The content of the body should be a xml comment @copilot

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 7659c0f - wrapped body content in XML comment following shared workflow pattern

This shared workflow configures the GitHub Copilot engine to use GitHub App authentication instead of personal access tokens.

## Configuration

When imported, this provides:
- **GitHub App authentication** for Copilot CLI
- **Short-lived tokens** with `copilot-requests: read` permission
- **Automatic token invalidation** after workflow completion

## Usage

Import this workflow to enable GitHub App authentication for Copilot:

```yaml
---
engine: copilot
imports:
- shared/copilot-app.md
---
```

## Requirements

Configure the following in your repository:
- **vars.APP_ID** - GitHub App ID
- **secrets.APP_PRIVATE_KEY** - GitHub App private key (PEM format)

## Permissions

The generated token will have:
- `copilot-requests: read` - Required for GitHub Copilot CLI access

Additional permissions can be inherited from workflow-level `permissions:` configuration.

## Benefits

- **Security**: Short-lived tokens (max 1 hour) instead of long-lived PATs
- **Audit**: App activity tracked separately in GitHub audit logs
- **Rotation**: No need to rotate tokens manually
- **Least privilege**: Minimal permissions for Copilot access

-->
49 changes: 43 additions & 6 deletions .github/workflows/smoke-copilot.lock.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .github/workflows/smoke-copilot.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ permissions:
discussions: read
actions: read
name: Smoke Copilot
engine: copilot
imports:
- shared/copilot-app.md
- shared/gh.md
- shared/reporting.md
- shared/github-queries-safe-input.md
Expand Down
61 changes: 61 additions & 0 deletions actions/setup/sh/validate_app_support_engine_field.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/bin/bash
set -e

# validate_app_support_engine_field.sh - Validate GitHub App configuration for engine authentication
#
# Usage: validate_app_support_engine_field.sh ENGINE_NAME DOCS_URL
#
# Arguments:
# ENGINE_NAME : Name of the engine requiring GitHub App authentication (e.g., "GitHub Copilot CLI")
# DOCS_URL : Documentation URL for GitHub App configuration
#
# Environment variables (required):
# APP_ID : GitHub App ID (e.g., "${{ vars.APP_ID }}")
# APP_PRIVATE_KEY: GitHub App private key (e.g., "${{ secrets.APP_PRIVATE_KEY }}")
#
# Exit codes:
# 0 - GitHub App configuration is valid
# 1 - GitHub App configuration is invalid or missing

# Parse arguments
if [ "$#" -ne 2 ]; then
echo "Usage: $0 ENGINE_NAME DOCS_URL" >&2
exit 1
fi

ENGINE_NAME="$1"
DOCS_URL="$2"

echo "Validating GitHub App configuration for $ENGINE_NAME..."
echo ""

# Validate app-id variable
if [ -z "$APP_ID" ]; then
echo "❌ ERROR: GitHub App ID is not set"
echo ""
echo "To use GitHub App authentication with $ENGINE_NAME, you need to configure:"
echo " - vars.APP_ID (GitHub App ID)"
echo " - secrets.APP_PRIVATE_KEY (GitHub App private key)"
echo ""
echo "Documentation: $DOCS_URL"
exit 1
fi

# Validate private-key secret
if [ -z "$APP_PRIVATE_KEY" ]; then
echo "❌ ERROR: GitHub App private key is not set"
echo ""
echo "To use GitHub App authentication with $ENGINE_NAME, you need to configure:"
echo " - vars.APP_ID (GitHub App ID)"
echo " - secrets.APP_PRIVATE_KEY (GitHub App private key)"
echo ""
echo "Documentation: $DOCS_URL"
exit 1
fi

echo "✅ GitHub App configuration validated successfully"

# Set step output to indicate verification succeeded
if [ -n "$GITHUB_OUTPUT" ]; then
echo "verification_result=success" >> "$GITHUB_OUTPUT"
fi
109 changes: 50 additions & 59 deletions pkg/parser/schemas/main_workflow_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -5615,39 +5615,47 @@
},
"dispatch-workflow": {
"oneOf": [
{
"type": "array",
"minItems": 1,
"items": {
"type": "string"
},
"description": "Shorthand format: array of workflow names to dispatch (without .md extension). Workflows must exist in same directory and support workflow_dispatch trigger. Self-reference not allowed. Max defaults to 1."
},
{
"type": "object",
"description": "Configuration for dispatching other workflows from this workflow. Allows workflows to trigger other workflows via workflow_dispatch events. Includes self-reference prevention and path traversal protection.",
"description": "Configuration for dispatching workflow_dispatch events to other workflows. Orchestrators use this to delegate work to worker workflows.",
"properties": {
"workflows": {
"type": "array",
"minItems": 1,
"description": "List of workflow names (without .md extension) to allow dispatching. Each workflow must exist in .github/workflows/.",
"items": {
"type": "string"
"type": "string",
"minLength": 1
},
"description": "List of workflow names to dispatch (without .md extension). Workflows must exist in same directory and support workflow_dispatch trigger. Self-reference not allowed."
"minItems": 1,
"maxItems": 50
},
"max": {
"type": "integer",
"description": "Maximum number of workflow dispatch operations per run (default: 1, max: 50)",
"minimum": 1,
"maximum": 50,
"description": "Maximum number of concurrent workflow dispatches (default: 1, maximum: 50)"
"default": 1
},
"github-token": {
"$ref": "#/$defs/github_token",
"description": "GitHub token to use for dispatching workflows. Overrides global github-token if specified."
}
},
"required": ["workflows"],
"additionalProperties": false
},
{
"type": "array",
"description": "Shorthand array format: list of workflow names (without .md extension) to allow dispatching",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"maxItems": 50
}
],
"$comment": "Self-reference prevention: workflow cannot dispatch itself (prevents infinite loops). Path traversal protection: all paths validated with isPathWithinDir(). Validation: pkg/workflow/dispatch_workflow_validation.go",
"description": "Enable dispatching other workflows from this workflow. Allows workflows to trigger other workflows via workflow_dispatch events with security constraints."
"description": "Dispatch workflow_dispatch events to other workflows. Used by orchestrators to delegate work to worker workflows with controlled maximum dispatch count."
},
"missing-tool": {
"oneOf": [
Expand Down Expand Up @@ -6192,50 +6200,6 @@
"runs-on": {
"type": "string",
"description": "Runner specification for all safe-outputs jobs (activation, create-issue, add-comment, etc.). Single runner label (e.g., 'ubuntu-slim', 'ubuntu-latest', 'windows-latest', 'self-hosted'). Defaults to 'ubuntu-slim'. See https://github.blog/changelog/2025-10-28-1-vcpu-linux-runner-now-available-in-github-actions-in-public-preview/"
},
"dispatch-workflow": {
"oneOf": [
{
"type": "object",
"description": "Configuration for dispatching workflow_dispatch events to other workflows. Orchestrators use this to delegate work to worker workflows.",
"properties": {
"workflows": {
"type": "array",
"description": "List of workflow names (without .md extension) to allow dispatching. Each workflow must exist in .github/workflows/.",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"maxItems": 50
},
"max": {
"type": "integer",
"description": "Maximum number of workflow dispatch operations per run (default: 1, max: 50)",
"minimum": 1,
"maximum": 50,
"default": 1
},
"github-token": {
"$ref": "#/$defs/github_token",
"description": "GitHub token to use for dispatching workflows. Overrides global github-token if specified."
}
},
"required": ["workflows"],
"additionalProperties": false
},
{
"type": "array",
"description": "Shorthand array format: list of workflow names (without .md extension) to allow dispatching",
"items": {
"type": "string",
"minLength": 1
},
"minItems": 1,
"maxItems": 50
}
],
"description": "Dispatch workflow_dispatch events to other workflows. Used by orchestrators to delegate work to worker workflows with controlled maximum dispatch count."
}
},
"additionalProperties": false
Expand Down Expand Up @@ -6744,6 +6708,33 @@
"type": "string"
},
"description": "Optional array of command-line arguments to pass to the AI engine CLI. These arguments are injected after all other args but before the prompt."
},
"app": {
"type": "object",
"description": "GitHub App configuration for token minting (alternative to COPILOT_GITHUB_TOKEN secret). When configured, the engine will use a GitHub App to mint short-lived tokens with copilot-requests:read permission.",
"properties": {
"app-id": {
"type": "string",
"description": "GitHub App ID (e.g., ${{ vars.APP_ID }})"
},
"private-key": {
"type": "string",
"description": "GitHub App private key in PEM format (e.g., ${{ secrets.APP_PRIVATE_KEY }})"
},
"owner": {
"type": "string",
"description": "Optional: owner of the GitHub App installation (defaults to current repository owner)"
},
"repositories": {
"type": "array",
"items": {
"type": "string"
},
"description": "Optional: list of repositories to grant access to (defaults to current repository)"
}
},
"required": ["app-id", "private-key"],
"additionalProperties": false
}
},
"required": ["id"],
Expand Down
1 change: 0 additions & 1 deletion pkg/workflow/action_pins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1464,4 +1464,3 @@ func TestFormatActionCacheKey(t *testing.T) {
})
}
}

Loading