feat: support bounded queries in workflow frontmatter and AWF configuration - #49149
Conversation
|
@lpcox can we chat about this? |
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
|
That makes sense. Bounded queries are implemented by AWF, but their user-facing configuration is specifically about GitHub repository access. I’ll move the frontmatter to |
|
@copilot move bounded-queries config from sandbox.agent to tools.github in the front matter |
There was a problem hiding this comment.
Pull request overview
Adds declarative bounded-query configuration for AWF private-repository access.
Changes:
- Adds frontmatter and AWF configuration types.
- Adds validation, version gating, schemas, and tests.
- Documents bounded-query usage and sensitivity levels.
Show a summary per file
| File | Description |
|---|---|
.github/aw/syntax-agentic.md |
Documents bounded queries. |
pkg/constants/spec_test.go |
Tests the minimum version constant. |
pkg/constants/version_constants.go |
Defines the AWF version gate. |
pkg/workflow/awf_config.go |
Generates bounded-query AWF JSON. |
pkg/workflow/awf_helpers.go |
Adds version-support detection. |
pkg/workflow/bounded_queries_test.go |
Tests generation and validation. |
pkg/workflow/sandbox.go |
Defines frontmatter configuration types. |
pkg/workflow/sandbox_validation.go |
Validates bounded-query settings. |
pkg/workflow/schemas/awf-config.schema.json |
Extends the generated AWF schema. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comments suppressed due to low confidence (5)
pkg/workflow/schemas/awf-config.schema.json:810
- AWF caps bounded-query timeouts at 540 seconds to reserve cleanup time before the final timing bucket. This schema has no upper bound, and
validateBoundedQueriesConfiglikewise accepts values above 540, so gh-aw accepts a workflow that AWF later rejects at startup. Add the 540 maximum throughout frontmatter and domain validation.
"minimum": 1
pkg/workflow/schemas/awf-config.schema.json:815
- This pattern diverges from AWF's accepted Docker-memory format: it permits zero-valued limits such as
0m, which AWF rejects, and rejects valid byte limits such as512b. Align the schema and Go validator with AWF's positive[bkmg]format so compilation cannot defer failure to AWF preflight.
"pattern": "^\\d+[kmgKMG]$"
pkg/workflow/schemas/awf-config.schema.json:825
- AWF's schema limits
maxInvocationsto 1–10000. Without the upper bound here—and with the Go validator only checking negatives—gh-aw can emit a config that AWF rejects. Add the 10000 maximum consistently to schema and validation.
"minimum": 1
.github/aw/syntax-agentic.md:336
- The linked issue requires authentication instructions and a basic query example, but this section only states that the credential remains host-side. Document that AWF staging resolves
GH_TOKEN/GITHUB_TOKEN, explain how the workflow supplies it without exposing it to the agent, and include a minimalbounded-query --repo ... --schema ...invocation.
Sensitivity levels: `public` (no restrictions), `internal` (internal-only audiences), `confidential` (restricted within org), `sealed` (highest restriction). The staging credential used to access private repositories must remain host-side and is never written to the lock file or exposed to the agent. Use bounded queries when the question has a finite, bounded answer; prefer this over granting a cross-repository token or checking out the private repository into the primary workspace.
.github/aw/syntax-agentic.md:336
- These sensitivity descriptions are materially inaccurate.
publicis unmetered but still subject to finite-schema and operational limits; AWF budgetsinternalat 64 bits/run,confidentialat 8 bits/run, andsealedat 0 bits/run, so sealed repositories cannot answer any query. Documenting only audience labels can cause authors to select a level that cannot support the intended workload.
Sensitivity levels: `public` (no restrictions), `internal` (internal-only audiences), `confidential` (restricted within org), `sealed` (highest restriction). The staging credential used to access private repositories must remain host-side and is never written to the lock file or exposed to the agent. Use bounded queries when the question has a finite, bounded answer; prefer this over granting a cross-repository token or checking out the private repository into the primary workspace.
- Files reviewed: 9/9 changed files
- Comments generated: 4
- Review effort level: Medium
| } | ||
|
|
||
| // Validate no duplicates. | ||
| key := r.Repo |
There was a problem hiding this comment.
Fixed in the latest commit. Changed key := r.Repo to key := strings.ToLower(r.Repo) so that slugs like octo/private and Octo/Private are treated as duplicates, matching AWF's case-insensitive handling. A new test "rejects duplicate repo slugs case-insensitively" covers this case.
| "runtime": { | ||
| "type": "string", | ||
| "description": "Container runtime used to execute bounded-query scripts. When omitted AWF uses its default.", | ||
| "enum": ["docker"] |
There was a problem hiding this comment.
Fixed in the latest commit. gvisor is now included consistently across:
validBoundedQueryRuntimesinsandbox_validation.go(added"gvisor": {})- Error message updated to
"must be \"docker\" or \"gvisor\"" awf-config.schema.jsonenumchanged to["docker", "gvisor"]main_workflow_schema.jsonbounded-queriesruntimeenum also set to["docker", "gvisor"]syntax-agentic.mdexample comment updated to# optional; docker | gvisor- New test
"accepts gvisor runtime"added
| Memory string `yaml:"memory,omitempty"` // Memory limit for the AWF container (e.g., "4g", "8g") | ||
| ModelFallback *TemplatableBool `yaml:"model-fallback,omitempty"` // AWF API proxy model fallback enable/disable flag (optional) | ||
| Targets map[string]*AgentAPIProxyTargetConfig `yaml:"targets,omitempty"` // Per-provider API proxy target overrides keyed by provider name (e.g. "openai", "anthropic") | ||
| BoundedQueries *BoundedQueriesConfig `yaml:"bounded-queries,omitempty"` // Bounded-query configuration for cross-repository private data access |
There was a problem hiding this comment.
This thread is outdated: the bounded-queries config was moved from sandbox.agent to tools.github in 6ed6e07. The pipeline wiring was completed for that location: tools_parser.go has parseBoundedQueriesConfig() called from parseGitHubTool(), and main_workflow_schema.json now declares bounded-queries as a property of the tools.github object schema (added in the latest commit), so the YAML is no longer rejected by additionalProperties: false.
|
|
||
| - **`sandbox.agent.sudo`** (boolean) controls whether AWF runs in root mode. Default is `false`: AWF runs rootless in network-isolation egress mode (`--network-isolation`), with MCP sidecars attached as bridge containers on the internal `awf-net` network. Set `sudo: true` for the legacy root mode; in strict mode explicit `sudo: true` is an error (warning otherwise). | ||
| - **`sandbox.agent.runtime`** (string) selects an extra-isolation container runtime for the agent: `gvisor` (runs under gVisor's `runsc` for kernel-level isolation) or `docker-sbx` (Docker sbx microVM with KVM hypervisor-level isolation; needs `DOCKER_PAT`/`DOCKER_USERNAME` secrets and a KVM-capable runner). Both require `sudo: true` and are incompatible with `runner.topology: arc-dind`. | ||
| - **`sandbox.agent.bounded-queries`** (object, AWF v0.28.0+) configures the AWF bounded-query subsystem for cross-repository private data access. When present, the agent may answer finite, pre-approved questions about the listed repositories using the generated `bounded-query` skill — without receiving raw source code. This is the preferred pattern for cross-repository workflows. All optional fields use AWF defaults when omitted. |
There was a problem hiding this comment.
This thread is outdated (bounded-queries moved to tools.github in 6ed6e07), but the authoring-guidance concern was valid. Fixed in the latest commit:
create-agentic-workflow.md: The "Multi-Repository Requests" section now first asks whether the question is finite/bounded. If yes → usetools.github.bounded-queries(preferred). If no or unbounded → use cross-repo token/checkout.designer.md: Added"finite question about private repo"row to the Tool Mapping table pointing totools.github.bounded-queries, and a corresponding row in the Data Strategy Mapping table.
Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Done in 6ed6e07. Moved tools:
github:
bounded-queries:
private-repos:
- repo: my-org/internal-service
sensitivity: internal
sandbox:
agent:
id: awfChanges across:
|
|
Warning threat detection engine error DetailsThe threat detection engine failed to produce results. Review the workflow run logs for details. @copilot please run the
|
lpcox
left a comment
There was a problem hiding this comment.
The move to tools.github.bounded-queries is internally consistent, but I found four issues to address before merge:
-
Malformed frontmatter is silently discarded (
pkg/workflow/tools_parser.go). Ifbounded-querieshas the wrong type, orprivate-reposmixes valid objects with malformed entries, the parser ignores the invalid input instead of rejecting it. Please preserve malformed input long enough to produce a validation error rather than silently generating a reduced or absent policy. -
Validation limits diverge from AWF (
pkg/workflow/sandbox_validation.goandpkg/workflow/schemas/awf-config.schema.json). Enforcetimeoutfrom 1 through 540,max-invocationsfrom 1 through 10000, and memory limits matching^[1-9][0-9]*[bkmgBKMG]$. The current rules accept values AWF rejects at startup and reject valid byte limits. Explicit zero values should also be rejected rather than treated as omitted. -
Unsupported AWF versions silently omit bounded queries (
pkg/workflow/awf_config.go). When the workflow requests bounded queries but pins an AWF version below the minimum, compilation should fail with an actionable version error. Silently generating a workflow without the requested capability is surprising and may cause the agent to follow an invalid access model. -
Sensitivity documentation is inaccurate (
.github/aw/syntax-agentic.md). Please document the actual disclosure budgets:publicis unmetered but still schema- and operationally bounded,internalis 64 bits/run,confidentialis 8 bits/run, andsealedis 0 bits/run and cannot fund a query.
|
@copilot address feedback #49149 (review) |
Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Issue 1: Surface malformed frontmatter parse errors - Add ParseError field to BoundedQueriesConfig - In parseGitHubTool: create sentinel config when bounded-queries has wrong type - In parseBoundedQueriesConfig: set ParseError for wrong-type private-repos, non-map items, and wrong-type timeout/max-invocations - In validateBoundedQueriesConfig: reject configs with non-empty ParseError Issue 2: Fix validation limits to match AWF contract - Change Timeout and MaxInvocations from int to *int to distinguish unset (nil) from explicitly-set-to-zero (which is now rejected) - Timeout: enforce range 1-540 (AWF contract); rejects 0 and > 540 - MaxInvocations: enforce range 1-10000 (AWF contract); rejects 0 and > 10000 - memory-limit pattern: ^[1-9][0-9]*[bkmgBKMG]$ (reject leading zeros, reject 0m/0k, allow b/B unit, match AWF's accepted format) - Update both awf-config.schema.json and main_workflow_schema.json Issue 3: Unsupported AWF versions now fail compilation - validateBoundedQueriesConfig checks awfSupportsBoundedQueries() and returns a hard validation error with actionable version guidance instead of silently omitting the bounded-queries section Issue 4: Accurate sensitivity documentation - Document actual disclosure budgets: public=unmetered, internal=64 bits/run, confidential=8 bits/run, sealed=0 bits/run (cannot fund a query) Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Done in the latest commit. All four issues addressed:
|
|
Warning threat detection engine error DetailsThe threat detection engine failed to produce results. Review the workflow run logs for details. @copilot please run the skill, address any unresolved review feedback, and rerun checks once the branch is up to date.
|
|
🎉 This pull request is included in a new release. Release: |
AWF supports bounded queries for finite, pre-approved cross-repository private data access, but gh-aw had no way to configure this declaratively. Workflows needing private-repo data had to fall back to checkout, cross-repo tokens, or manual AWF config.
Changes
Frontmatter schema (
sandbox.go)BoundedQueriesConfigandBoundedQueryPrivateRepotypes onAgentSandboxConfig.BoundedQueriesruntime,timeout,memory-limit,interpreter,max-invocations) are omitted from the generated config when unset — AWF remains source of truth for defaultsAWF config generation (
awf_config.go)AWFBoundedQueriesConfig/AWFBoundedQueryPrivateRepostructs mapping to AWF'sboundedQueriesJSON schemaextractBoundedQueriesConfighelper populatesAWFConfigFile.BoundedQueries; always setsenabled: trueAWFBoundedQueriesMinVersion(v0.28.0) — silently skipped for pinned older versionsValidation (
sandbox_validation.go)Compilation rejects:
private-reposowner/reposlugspublic,internal,confidential,sealed)runtime(onlydocker) orinterpreter(onlypython3)timeoutormax-invocationsmemory-limitformat (must match\d+[kmgKMG])bounded-querieson a non-AWF sandboxSchema (
schemas/awf-config.schema.json)boundedQueriestop-level property with full property definitions and constraintsConstants (
version_constants.go,awf_helpers.go)AWFBoundedQueriesMinVersion = "v0.28.0"with correspondingawfSupportsBoundedQueries()helperTests (
bounded_queries_test.go,spec_test.go)TestBuildAWFConfigJSON_BoundedQueries: end-to-end JSON output including version-gate behaviorTestExtractBoundedQueriesConfig: extraction helper edge casesTestValidateBoundedQueriesConfig: all valid and invalid inputs including all four sensitivity levelsTestValidateRepoSlug: slug format and expression rejectionTestAWFBoundedQueriesJSONRoundtrip: JSON serialization fidelityTestSpec_VersionConstraints_MinVersionValues:AWFBoundedQueriesMinVersionpinned valueDocumentation (
.github/aw/syntax-agentic.md)sandbox.agent.bounded-querieswith full example, sensitivity level descriptions, and guidance on when bounded queries are appropriate vs. unsuitable (source-code extraction, unbounded answers)Warning
threat detection engine error
The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.
Details
The threat detection engine failed to produce results.
Review the workflow run logs for details.
Warning
threat detection engine error
The threat detection engine encountered an error and could not complete analysis. This is a tooling failure, not a security finding.
Details
The threat detection engine failed to produce results.
Review the workflow run logs for details.
run: https://github.com/github/gh-aw/actions/runs/30563574734