diff --git a/docs/src/content/docs/agent-factory-status.mdx b/docs/src/content/docs/agent-factory-status.mdx index b1345ecc05..f0b05d0131 100644 --- a/docs/src/content/docs/agent-factory-status.mdx +++ b/docs/src/content/docs/agent-factory-status.mdx @@ -1,5 +1,5 @@ --- -title: Agent Factory Status +title: Agent Factory description: Experimental agentic workflows used by the team to learn and build. sidebar: order: 1000 @@ -110,6 +110,7 @@ These are experimental agentic workflows used by the GitHub Next team to learn, | [Scout](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/scout.md) | claude | [![Scout](https://github.com/githubnext/gh-aw/actions/workflows/scout.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/scout.lock.yml) | - | `/scout` | | [Security Compliance Campaign](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/security-compliance.md) | copilot | [![Security Compliance Campaign](https://github.com/githubnext/gh-aw/actions/workflows/security-compliance.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/security-compliance.lock.yml) | - | - | | [Security Fix PR](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/security-fix-pr.md) | copilot | [![Security Fix PR](https://github.com/githubnext/gh-aw/actions/workflows/security-fix-pr.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/security-fix-pr.lock.yml) | - | - | +| [Security Review Agent 🔒](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/security-review.md) | copilot | [![Security Review Agent 🔒](https://github.com/githubnext/gh-aw/actions/workflows/security-review.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/security-review.lock.yml) | - | `/security` | | [Semantic Function Refactoring](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/semantic-function-refactor.md) | claude | [![Semantic Function Refactoring](https://github.com/githubnext/gh-aw/actions/workflows/semantic-function-refactor.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/semantic-function-refactor.lock.yml) | - | - | | [Sergo - Serena Go Expert](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/sergo.md) | claude | [![Sergo - Serena Go Expert](https://github.com/githubnext/gh-aw/actions/workflows/sergo.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/sergo.lock.yml) | - | - | | [Slide Deck Maintainer](https://github.com/githubnext/gh-aw/blob/main/.github/workflows/slide-deck-maintainer.md) | copilot | [![Slide Deck Maintainer](https://github.com/githubnext/gh-aw/actions/workflows/slide-deck-maintainer.lock.yml/badge.svg)](https://github.com/githubnext/gh-aw/actions/workflows/slide-deck-maintainer.lock.yml) | `0 16 * * 1-5` | - | diff --git a/docs/src/content/docs/reference/schema-design.md b/docs/src/content/docs/reference/schema-design.md new file mode 100644 index 0000000000..c4be73827c --- /dev/null +++ b/docs/src/content/docs/reference/schema-design.md @@ -0,0 +1,320 @@ +--- +title: Schema Design Philosophy +description: Security model and design philosophy behind main workflows and included files, explaining why certain properties are restricted and how to choose the right workflow type. +sidebar: + order: 350 +--- + +GitHub Agentic Workflows uses two distinct JSON schemas to validate workflow files: one for main workflows (entry points with triggers) and one for included files (reusable components). The schemas enforce different capabilities based on security and semantic requirements. + +## Security Model + +The schema architecture separates workflows by trust level and execution context: + +### Main Workflows + +Main workflows are **trusted entry points** that define when and how automation runs. They have full capabilities including: + +- Defining workflow triggers (`on:` field) +- Executing custom commands (`engine.command`) +- Configuring GitHub Actions runtime +- Defining approval gates and manual controls +- Setting up sandbox environments + +Main workflows are validated against `pkg/parser/schemas/main_workflow_schema.json`. + +### Included Files + +Included files are **reusable components** that provide configuration and instructions without controlling workflow execution. They have restricted capabilities to maintain security boundaries: + +- Cannot define triggers (no `on:` field) +- Cannot execute custom commands (no `engine.command`) +- Cannot override sandbox configuration +- Cannot define custom jobs or GitHub Actions configuration + +Included files are validated against `pkg/parser/schemas/included_file_schema.json`. + +> [!NOTE] +> This separation ensures that imported components cannot subvert security controls or change workflow behavior in unexpected ways. + +## Property Availability Matrix + +The following table shows which properties are available in each schema type: + +| Property | Main Workflow | Included File | Notes | +|----------|---------------|---------------|-------| +| **Common Properties (13)** | | | | +| `description` | ✅ | ✅ | Workflow description | +| `engine` | ✅ | ✅ | AI engine configuration | +| `mcp-servers` | ✅ | ✅ | MCP server definitions | +| `metadata` | ✅ | ✅ | Custom metadata key-value pairs | +| `network` | ✅ | ✅ | Network permissions | +| `permissions` | ✅ | ✅ | GitHub Actions permissions | +| `runtimes` | ✅ | ✅ | Runtime version overrides | +| `safe-inputs` | ✅ | ✅ | Custom input tool definitions | +| `safe-outputs` | ✅ | ✅ | Safe output handlers | +| `secret-masking` | ✅ | ✅ | Secret masking configuration | +| `services` | ✅ | ✅ | Docker services | +| `steps` | ✅ | ✅ | Workflow steps | +| `tools` | ✅ | ✅ | Tool configurations | +| **Main-Only Properties (25)** | | | | +| `bots` | ✅ | ❌ | Bot user filtering | +| `cache` | ✅ | ❌ | GitHub Actions cache | +| `command` | ✅ | ❌ | Custom engine command path | +| `concurrency` | ✅ | ❌ | Concurrency controls | +| `container` | ✅ | ❌ | Container configuration | +| `env` | ✅ | ❌ | Environment variables | +| `environment` | ✅ | ❌ | GitHub environment | +| `features` | ✅ | ❌ | Feature flags | +| `github-token` | ✅ | ❌ | GitHub token configuration | +| `if` | ✅ | ❌ | Conditional execution | +| `imports` | ✅ | ❌ | Import other files | +| `jobs` | ✅ | ❌ | Custom GitHub Actions jobs | +| `labels` | ✅ | ❌ | Workflow categorization | +| `name` | ✅ | ❌ | Workflow name | +| `on` | ✅ | ❌ | Workflow triggers | +| `post-steps` | ✅ | ❌ | Post-execution steps | +| `roles` | ✅ | ❌ | Role-based access control | +| `run-name` | ✅ | ❌ | GitHub Actions run name | +| `runs-on` | ✅ | ❌ | Runner specification | +| `sandbox` | ✅ | ❌ | Sandbox configuration | +| `source` | ✅ | ❌ | Source tracking | +| `strict` | ✅ | ❌ | Strict validation mode | +| `timeout-minutes` | ✅ | ❌ | Workflow timeout | +| `timeout_minutes` | ✅ | ❌ | Workflow timeout (deprecated) | +| `tracker-id` | ✅ | ❌ | External tracker ID | +| **Included-Only Properties (2)** | | | | +| `applyTo` | ❌ | ✅ | Target workflow filter | +| `inputs` | ❌ | ✅ | Parameterized inputs | + +**Summary**: 38 properties in main workflows, 15 in included files, 13 common between both. + +## Design Rationale + +### Why Triggers (`on:`) are Main-Only + +**Semantic Model**: Triggers define the entry point of workflow execution. Allowing included files to define triggers would create ambiguity about when workflows run. + +**Security**: Entry points should be explicitly defined in the repository's main workflow files where they can be reviewed and audited. + +**Design Decision**: Workflows without `on:` fields are automatically recognized as shared components and skipped during compilation, preventing generation of incomplete GitHub Actions workflows. + +### Why Custom Commands (`engine.command`) are Main-Only + +**Security**: The `engine.command` property allows specifying arbitrary executables to run as the AI engine. This capability must be restricted to main workflows where it can be properly reviewed. + +**Attack Surface**: If included files could override the engine command, a malicious import could execute arbitrary code by pointing to a compromised binary. + +**Safe Alternative**: Included files can still configure engine settings like `model`, `max-turns`, and `args`, but cannot change the fundamental execution path. + +### Why Sandbox Configuration is Main-Only + +**Isolation Boundary**: The `sandbox` property controls fundamental security boundaries like the MCP gateway and sandbox runtime environment. These settings define the trust model for the entire workflow. + +**Consistency**: All imported components execute within the sandbox defined by the main workflow, ensuring consistent security policies. + +**Configuration Scope**: Sandbox settings are workflow-wide and cannot be mixed between different imported files without creating security confusion. + +### Why MCP Servers are Simplified in Included Files + +While both main workflows and included files support `mcp-servers`, the merge behavior differs: + +- **Main workflows**: Full control over all MCP configurations +- **Included files**: Can define MCP servers, but imported definitions take precedence during merge +- **Security**: This prevents included files from hijacking existing MCP server definitions +- **Flexibility**: Shared components can still provide MCP server configurations that work across multiple workflows + +See [Imports](/gh-aw/reference/imports/#mcp-servers-mcp-servers) for detailed merge semantics. + +## Usage Guidance + +### When to Create a Main Workflow + +Create a main workflow (`.github/workflows/*.md`) when you need: + +- **Entry point**: Define when automation runs using `on:` triggers +- **Full control**: Access to all configuration options +- **Custom execution**: Override engine commands or sandbox settings +- **GitHub Actions**: Custom jobs, environments, or runner configurations +- **Standalone execution**: Workflow runs independently without imports + +**Example use cases**: +- Issue responder triggered by issue events +- PR reviewer triggered by pull request events +- Scheduled maintenance workflows +- Manual approval workflows with `/command` triggers + +### When to Create an Included File + +Create an included file (`.github/workflows/shared/*.md` or similar) when you need: + +- **Reusability**: Share configuration across multiple workflows +- **Modularity**: Organize related tools and settings together +- **Version control**: Maintain consistent configurations +- **Safe imports**: Provide functionality without security risks +- **Parameterization**: Use `inputs` field for configurable shared components + +**Example use cases**: +- Common tool configurations (GitHub, web-fetch, bash permissions) +- MCP server definitions used by multiple workflows +- Standard network permission sets +- Reusable setup steps or safe-output configurations + +### Migration Strategies + +#### From Main to Included + +If you have duplicate configuration in multiple main workflows: + +1. Identify common properties (tools, mcp-servers, network, etc.) +2. Extract to shared file in `.github/workflows/shared/` +3. Remove `on:`, `name`, and other main-only properties +4. Add to main workflows using `imports:` field +5. Test compilation to ensure merge behavior is correct + +#### From Included to Main + +If an included file needs workflow-specific capabilities: + +1. Copy included file to `.github/workflows/` +2. Add required `on:` trigger +3. Add `name` property for workflow identification +4. Add any needed main-only properties (sandbox, jobs, etc.) +5. Remove `applyTo` and `inputs` if present +6. Compile and test as standalone workflow + +## Examples + +### Valid Main Workflow + +```aw wrap +--- +name: Issue Responder +on: + issues: + types: [opened] + +engine: copilot + +permissions: + issues: write + contents: read + +tools: + github: + toolsets: [issues] + bash: + allowed: [read, list] + +network: + allowed: + - github.com + +sandbox: + mode: mcp-gateway +--- + +# Issue Responder + +Read the newly opened issue and provide helpful resources based on the issue content. +``` + +### Valid Included File + +```aw wrap +--- +description: Common GitHub tools and permissions + +tools: + github: + toolsets: [issues, pull_requests] + bash: + allowed: [read, list] + web-fetch: {} + +network: + allowed: + - github.com + - api.github.com + +permissions: + contents: read + issues: write +--- + +# Shared GitHub Configuration + +This file provides standard GitHub tool configurations used across multiple workflows. +``` + +### Common Mistakes and Fixes + +#### ❌ Mistake: Adding Triggers to Included File + +```yaml wrap +# shared/common.md - INVALID +--- +on: issues # ERROR: 'on' is not allowed in included files +tools: + github: + toolsets: [issues] +--- +``` + +**Fix**: Remove `on:` field. Included files are triggered through main workflows that import them. + +#### ❌ Mistake: Using Custom Command in Included File + +```yaml wrap +# shared/custom-engine.md - INVALID +--- +engine: + id: copilot + command: /custom/copilot # ERROR: 'command' not allowed in included files +--- +``` + +**Fix**: Move engine command configuration to main workflow. Included files can only configure non-security-sensitive engine properties. + +#### ❌ Mistake: Expecting Imported Permissions to Merge + +```yaml wrap +# shared/perms.md +--- +permissions: + contents: read + issues: write +--- + +# main.md - INVALID +--- +on: issues +imports: + - shared/perms.md +# ERROR: Permissions not automatically inherited +--- +``` + +**Fix**: Explicitly declare all required permissions in main workflow. Imported permissions are validated, not merged. + +```yaml wrap +# main.md - VALID +--- +on: issues +imports: + - shared/perms.md +permissions: + contents: read + issues: write +--- +``` + +## Related Documentation + +- [Imports](/gh-aw/reference/imports/) - Importing and merging workflow components +- [Frontmatter](/gh-aw/reference/frontmatter/) - Complete frontmatter reference +- [Workflow Structure](/gh-aw/reference/workflow-structure/) - Basic workflow organization +- [Engines](/gh-aw/reference/engines/) - AI engine configuration +- [Network](/gh-aw/reference/network/) - Network permission configuration +- [Sandbox](/gh-aw/reference/sandbox/) - Sandbox environment details +- [Compilation Process](/gh-aw/reference/compilation-process/) - How workflows are compiled and validated diff --git a/pkg/workflow/data/action_pins.json b/pkg/workflow/data/action_pins.json index 0262bcec27..b8a317833e 100644 --- a/pkg/workflow/data/action_pins.json +++ b/pkg/workflow/data/action_pins.json @@ -1,3 +1,194 @@ { - "entries": {} + "entries": { + "actions/ai-inference@v2": { + "repo": "actions/ai-inference", + "version": "v2", + "sha": "334892bb203895caaed82ec52d23c1ed9385151e" + }, + "actions/attest-build-provenance@v2": { + "repo": "actions/attest-build-provenance", + "version": "v2", + "sha": "96b4a1ef7235a096b17240c259729fdd70c83d45" + }, + "actions/cache/restore@v4.3.0": { + "repo": "actions/cache/restore", + "version": "v4.3.0", + "sha": "0057852bfaa89a56745cba8c7296529d2fc39830" + }, + "actions/cache/save@v4.3.0": { + "repo": "actions/cache/save", + "version": "v4.3.0", + "sha": "0057852bfaa89a56745cba8c7296529d2fc39830" + }, + "actions/cache@v4.3.0": { + "repo": "actions/cache", + "version": "v4.3.0", + "sha": "0057852bfaa89a56745cba8c7296529d2fc39830" + }, + "actions/checkout@v4": { + "repo": "actions/checkout", + "version": "v4", + "sha": "34e114876b0b11c390a56381ad16ebd13914f8d5" + }, + "actions/checkout@v5.0.1": { + "repo": "actions/checkout", + "version": "v5.0.1", + "sha": "93cb6efe18208431cddfb8368fd83d5badbf9bfd" + }, + "actions/create-github-app-token@v2.2.1": { + "repo": "actions/create-github-app-token", + "version": "v2.2.1", + "sha": "29824e69f54612133e76f7eaac726eef6c875baf" + }, + "actions/download-artifact@v6.0.0": { + "repo": "actions/download-artifact", + "version": "v6.0.0", + "sha": "018cc2cf5baa6db3ef3c5f8a56943fffe632ef53" + }, + "actions/github-script@v7.0.1": { + "repo": "actions/github-script", + "version": "v7.1.0", + "sha": "f28e40c7f34bde8b3046d885e986cb6290c5673b" + }, + "actions/github-script@v8.0.0": { + "repo": "actions/github-script", + "version": "v8.0.0", + "sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd" + }, + "actions/setup-dotnet@v4": { + "repo": "actions/setup-dotnet", + "version": "v4.3.1", + "sha": "67a3573c9a986a3f9c594539f4ab511d57bb3ce9" + }, + "actions/setup-go@v6": { + "repo": "actions/setup-go", + "version": "v6", + "sha": "7a3fe6cf4cb3a834922a1244abfce67bcef6a0c5" + }, + "actions/setup-go@v6.1.0": { + "repo": "actions/setup-go", + "version": "v6.1.0", + "sha": "4dc6199c7b1a012772edbd06daecab0f50c9053c" + }, + "actions/setup-java@v4": { + "repo": "actions/setup-java", + "version": "v4.8.0", + "sha": "c1e323688fd81a25caa38c78aa6df2d33d3e20d9" + }, + "actions/setup-node@v6": { + "repo": "actions/setup-node", + "version": "v6", + "sha": "6044e13b5dc448c55e2357c09f80417699197238" + }, + "actions/setup-node@v6.1.0": { + "repo": "actions/setup-node", + "version": "v6.1.0", + "sha": "395ad3262231945c25e8478fd5baf05154b1d79f" + }, + "actions/setup-python@v5.6.0": { + "repo": "actions/setup-python", + "version": "v5.6.0", + "sha": "a26af69be951a213d495a4c3e4e4022e16d87065" + }, + "actions/upload-artifact@v4": { + "repo": "actions/upload-artifact", + "version": "v4.6.2", + "sha": "ea165f8d65b6e75b540449e92b4886f43607fa02" + }, + "actions/upload-artifact@v5.0.0": { + "repo": "actions/upload-artifact", + "version": "v5.0.0", + "sha": "330a01c490aca151604b8cf639adc76d48f6c5d4" + }, + "actions/upload-artifact@v6.0.0": { + "repo": "actions/upload-artifact", + "version": "v6.0.0", + "sha": "b7c566a772e6b6bfb58ed0dc250532a479d7789f" + }, + "anchore/sbom-action@v0.20.10": { + "repo": "anchore/sbom-action", + "version": "v0.20.10", + "sha": "fbfd9c6c189226748411491745178e0c2017392d" + }, + "anchore/sbom-action@v0.20.11": { + "repo": "anchore/sbom-action", + "version": "v0.20.11", + "sha": "43a17d6e7add2b5535efe4dcae9952337c479a93" + }, + "astral-sh/setup-uv@v5.4.2": { + "repo": "astral-sh/setup-uv", + "version": "v5.4.2", + "sha": "d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86" + }, + "cli/gh-extension-precompile@v2.1.0": { + "repo": "cli/gh-extension-precompile", + "version": "v2.1.0", + "sha": "9e2237c30f869ad3bcaed6a4be2cd43564dd421b" + }, + "denoland/setup-deno@v2": { + "repo": "denoland/setup-deno", + "version": "v2.0.3", + "sha": "e95548e56dfa95d4e1a28d6f422fafe75c4c26fb" + }, + "docker/build-push-action@v6": { + "repo": "docker/build-push-action", + "version": "v6", + "sha": "263435318d21b8e681c14492fe198d362a7d2c83" + }, + "docker/login-action@v3": { + "repo": "docker/login-action", + "version": "v3", + "sha": "5e57cd118135c172c3672efd75eb46360885c0ef" + }, + "docker/setup-buildx-action@v3": { + "repo": "docker/setup-buildx-action", + "version": "v3", + "sha": "8d2750c68a42422c14e847fe6c8ac0403b4cbd6f" + }, + "erlef/setup-beam@v1": { + "repo": "erlef/setup-beam", + "version": "v1.20.4", + "sha": "dff508cca8ce57162e7aa6c4769a4f97c2fed638" + }, + "github/codeql-action/upload-sarif@v3": { + "repo": "github/codeql-action/upload-sarif", + "version": "v3.31.9", + "sha": "70c165ac82ca0e33a10e9741508dd0ccb4dcf080" + }, + "github/stale-repos@v3": { + "repo": "github/stale-repos", + "version": "v3", + "sha": "3477b6488008d9411aaf22a0924ec7c1f6a69980" + }, + "github/stale-repos@v3.0.2": { + "repo": "github/stale-repos", + "version": "v3.0.2", + "sha": "a21e55567b83cf3c3f3f9085d3038dc6cee02598" + }, + "haskell-actions/setup@v2": { + "repo": "haskell-actions/setup", + "version": "v2.9.1", + "sha": "55073cbd0e96181a9abd6ff4e7d289867dffc98d" + }, + "oven-sh/setup-bun@v2": { + "repo": "oven-sh/setup-bun", + "version": "v2.0.2", + "sha": "735343b667d3e6f658f44d0eca948eb6282f2b76" + }, + "ruby/setup-ruby@v1": { + "repo": "ruby/setup-ruby", + "version": "v1.275.0", + "sha": "d354de180d0c9e813cfddfcbdc079945d4be589b" + }, + "super-linter/super-linter@v8.2.1": { + "repo": "super-linter/super-linter", + "version": "v8.2.1", + "sha": "2bdd90ed3262e023ac84bf8fe35dc480721fc1f2" + }, + "super-linter/super-linter@v8.3.1": { + "repo": "super-linter/super-linter", + "version": "v8.3.1", + "sha": "47984f49b4e87383eed97890fe2dca6063bbd9c3" + } + } }