You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I generated this issue with an agent that used .github/agents/ado-aw.agent.md.
I reviewed the generated issue and confirm it is being filed directly in githubnext/ado-aw.
Problem summary
Workflow authors need to publish custom, secret-bearing safe-output integrations once in a shared repository and consume them from many ado-aw workflows.
A typical author wants an agent to propose a typed operation, have Detection inspect that proposal, and let a separate privileged job perform the side effect with credentials the agent never receives. Today this requires either adding a built-in Rust safe output to ado-aw or hand-authoring raw pipeline steps. Neither option provides a reusable, typed, cross-repository extension point with the existing Agent → Detection → approval → SafeOutputs trust boundary.
Upstream github/gh-aw provides precedent through safe-outputs.jobs, safe-outputs.scripts, and safe-outputs.actions. Its custom jobs generate agent-callable MCP tools from typed input schemas, consume the agent-output artifact only after threat detection, isolate job secrets from the agent, support shared component imports, and encourage immutable source pinning. Azure DevOps should adopt the security properties, but not mechanically copy GitHub Actions concepts that lack an ADO equivalent.
Current ado-aw limitations include:
Safe-output MCP routes, proposal/result types, executor dispatch, budgets, and validation are statically compiled into Rust.
Unknown safe-outputs: keys fail compilation, so consumers cannot register an external tool schema.
Raw setup:, steps:, post-steps:, and teardown: are reusable only by copy/paste and do not become gated agent-callable tools.
repos: can emit type, name, and ref, but cannot currently emit the repository resource endpoint required for type: githubenterprise.
target: job and target: stage omit top-level repository resources, so the parent pipeline must declare and authorize shared repositories.
Audit understands built-in proposal and execution records, but has no external executor contract or provenance record.
Personas
A platform maintainer publishes reviewed safe-output integrations with schemas, execution steps, policy, and documentation in one shared repository.
A workflow author imports a pinned component, supplies non-secret configuration, and enables the generated tool without copying executor code.
A pipeline administrator binds service connections, variable groups, or secret variables in the consumer pipeline while keeping those values unavailable to Agent and Detection.
A reviewer/auditor can identify exactly which component revision ran, what was proposed, whether Detection and approval cleared it, and what the executor reported.
A consumer should be able to import an immutable revision and opt into approval:
---name: Release observerdescription: Analyze a release and propose notifications when operator attention is needed.imports:
- uses: platform/shared-agentic-components/ado-aw/send-notification.md@0123456789abcdef0123456789abcdef01234567repository:
type: githubenterpriseendpoint: shared-components-connectionwith:
destination: release-operationssafe-outputs:
send-notification:
require-approval:
approvers: [release-reviewers]on-timeout: reject---
Analyze the release evidence. Propose `send-notification` only when a person should act.
The exact syntax is open for design, but compilation should fail unless the remote source resolves to an immutable full commit SHA and the imported manifest is valid. For target: standalone and target: 1es, ado-aw can emit the required repository resource, including endpoint. For target: job and target: stage, the generated template should declare a typed parameter/contract and a precise header diagnostic requiring the parent pipeline to define and authorize the pinned resource.
The desired execution path is:
The compiler resolves and validates the pinned component manifest and merges its tool declaration without allowing silent name collisions.
The SafeOutputs MCP server exposes a generated tool with a closed JSON Schema (additionalProperties: false).
Agent writes the normal proposal NDJSON; it never receives executor secrets or the privileged repository/service-connection credential.
Detection examines the same proposal artifact and fails closed on missing, malformed, or unsafe analysis.
Optional require-approval uses the existing proposal-aware ManualReview behavior.
A dedicated custom safe-output job downloads only the analyzed artifact, validates the selected proposals again, executes the pinned component steps, and emits the standard execution-record contract.
Implement an MVP limited to importable safe-outputs.jobs.
MVP behavior
Add a shared-component manifest format with import-schema plus safe-outputs.jobs.<name>.
Support typed inputs (string, number, boolean, and bounded choice initially), required fields, descriptions, positive max, and conservative size limits.
Generate an MCP tool schema with additionalProperties: false; reject invalid names, unsupported schema constructs, duplicate normalized names, and collisions with built-in tools.
Resolve cross-repository imports at compile time, record source provenance, and require a full 40-character commit SHA. Never execute branch- or tag-floating component code.
Add endpoint to repository-resource types and lowering for GitHub/GitHub Enterprise service connections. Require the endpoint for repository types that need it.
Compile each custom safe-output job after Detection. If approval applies, use the existing automatic/reviewed partitioning and proposal-aware ManualReview gate.
Inject only compiler-owned paths and mode flags into the job, for example ADO_AW_SAFE_OUTPUT_PROPOSALS, ADO_AW_SAFE_OUTPUT_RESULTS, and ADO_AW_SAFE_OUTPUTS_STAGED. Do not expose Agent credentials or arbitrary Agent-job environment.
Require the executor to append one result record per attempted proposal using a versioned schema containing tool name, proposal index/id, status, sanitized message, optional data, component source SHA, and attempt metadata.
Treat missing/malformed result records, unknown proposal types, budget overflow, or executor failure as failed execution rather than success-shaped fallback.
Preserve existing per-tool max semantics. Failed attempts consume budget so retries cannot become an unbounded side-effect loop.
Default to no automatic retry for non-idempotent writes. A component may declare a small retry policy only with an explicit idempotency-key contract; retry transient failures only, with bounded exponential backoff.
Support staged/dry-run mode as a first-class compiler-provided contract. Staged mode must validate and report intended effects without performing network writes.
Extend the safe-output summary and ado-aw audit to show imported tool provenance, proposal counts, detection/approval state, execution status, and sanitized result data across automatic and reviewed jobs.
Include component source, resolved SHA, manifest digest, generated schema digest, and executor job identity in artifacts/telemetry. Never log secret values.
Verify downloaded/checked-out content against the resolved SHA before execution. Repository/service-connection authorization remains an explicit pipeline-administrator action; the compiler must not broaden access automatically.
Security and supply-chain invariants
Agent and Detection never receive custom executor secrets.
No custom executor runs before Detection returns safe.
Approval-gated proposals never execute before approval and fail closed on rejection/timeout.
Every executed component is immutable, provenance-recorded, and schema-validated.
Import merge semantics are deterministic: imports apply in declaration order for additive content, but duplicate tool names and secret/env collisions are hard errors; the consumer may configure a tool but may not replace imported executor steps.
Secrets may be referenced only from the privileged custom job through approved variable groups/service connections. Import inputs are non-secret and must not be interpolated into shell or YAML unsafely.
Raw component steps receive the same advisory task validation as current inline steps, plus strict checks for forbidden secret projection, unsupported checkout/resource mutation, unsafe template expressions, and unpinned external task/container dependencies where enforceable.
Apply explicit limits for imports, nesting, manifest size, tools per workflow, proposals per tool, input lengths, total proposal artifact size, job timeout, and result artifact size.
Scope
Cross-repository, immutable shared manifests.
Generated MCP tool schemas.
One isolated Azure Pipelines job per custom safe-output definition or an equivalent compiler-controlled job boundary.
Replacing deterministic post-run reporters; those summarize completed work and are distinct from agent-callable safe outputs that can create new side effects.
Acceptance criteria
A shared repository can publish a valid custom safe-output job manifest with typed agent inputs and non-secret import parameters.
A consumer can import it by full commit SHA and compile all four targets.
GitHub Enterprise repository resources support a validated endpoint; template targets clearly require the parent resource declaration.
The generated MCP tool appears only when imported/configured and rejects extra, missing, mistyped, or oversized inputs.
Name, schema, environment, and import conflicts fail deterministically at compile time.
Agent and Detection jobs contain none of the custom executor's secret bindings.
The custom job cannot run unless Detection is safe; reviewed tools additionally require successful manual approval.
Automatic and reviewed custom proposals preserve current split-execution behavior.
Staged mode performs no external write and produces an auditable planned result.
Per-tool limits, bounded timeout, result validation, and no-retry-by-default behavior are enforced.
Follow-up work may evaluate trusted in-process scripts for simple deterministic handlers, typed wrappers around pinned Azure DevOps tasks/templates, component discovery/update tooling, signed release metadata, policy allowlists, and a curated component catalog. Those should build on the job-based security and artifact contracts rather than weakening the job boundary.
Submission requirements
.github/agents/ado-aw.agent.md.githubnext/ado-aw.Problem summary
Workflow authors need to publish custom, secret-bearing safe-output integrations once in a shared repository and consume them from many ado-aw workflows.
A typical author wants an agent to propose a typed operation, have Detection inspect that proposal, and let a separate privileged job perform the side effect with credentials the agent never receives. Today this requires either adding a built-in Rust safe output to ado-aw or hand-authoring raw pipeline steps. Neither option provides a reusable, typed, cross-repository extension point with the existing Agent → Detection → approval → SafeOutputs trust boundary.
Upstream
github/gh-awprovides precedent throughsafe-outputs.jobs,safe-outputs.scripts, andsafe-outputs.actions. Its custom jobs generate agent-callable MCP tools from typed input schemas, consume the agent-output artifact only after threat detection, isolate job secrets from the agent, support shared component imports, and encourage immutable source pinning. Azure DevOps should adopt the security properties, but not mechanically copy GitHub Actions concepts that lack an ADO equivalent.Current ado-aw limitations include:
safe-outputs:keys fail compilation, so consumers cannot register an external tool schema.setup:,steps:,post-steps:, andteardown:are reusable only by copy/paste and do not become gated agent-callable tools.repos:can emittype,name, andref, but cannot currently emit the repository resourceendpointrequired fortype: githubenterprise.target: jobandtarget: stageomit top-level repository resources, so the parent pipeline must declare and authorize shared repositories.Personas
Reproduction details
A neutral shared component might look like:
A consumer should be able to import an immutable revision and opt into approval:
The exact syntax is open for design, but compilation should fail unless the remote source resolves to an immutable full commit SHA and the imported manifest is valid. For
target: standaloneandtarget: 1es, ado-aw can emit the required repository resource, includingendpoint. Fortarget: jobandtarget: stage, the generated template should declare a typed parameter/contract and a precise header diagnostic requiring the parent pipeline to define and authorize the pinned resource.The desired execution path is:
additionalProperties: false).require-approvaluses the existing proposal-awareManualReviewbehavior.Proposed next step
Implement an MVP limited to importable
safe-outputs.jobs.MVP behavior
import-schemaplussafe-outputs.jobs.<name>.string,number,boolean, and boundedchoiceinitially), required fields, descriptions, positivemax, and conservative size limits.additionalProperties: false; reject invalid names, unsupported schema constructs, duplicate normalized names, and collisions with built-in tools.endpointto repository-resource types and lowering for GitHub/GitHub Enterprise service connections. Require the endpoint for repository types that need it.ManualReviewgate.ADO_AW_SAFE_OUTPUT_PROPOSALS,ADO_AW_SAFE_OUTPUT_RESULTS, andADO_AW_SAFE_OUTPUTS_STAGED. Do not expose Agent credentials or arbitrary Agent-job environment.maxsemantics. Failed attempts consume budget so retries cannot become an unbounded side-effect loop.ado-aw auditto show imported tool provenance, proposal counts, detection/approval state, execution status, and sanitized result data across automatic and reviewed jobs.Security and supply-chain invariants
Scope
require-approval, safe-output summaries, execution artifacts, Conclusion, and audit integration.Non-goals for the MVP
Acceptance criteria
endpoint; template targets clearly require the parent resource declaration.ado-aw auditcorrelate successfully.Follow-up work may evaluate trusted in-process scripts for simple deterministic handlers, typed wrappers around pinned Azure DevOps tasks/templates, component discovery/update tooling, signed release metadata, policy allowlists, and a curated component catalog. Those should build on the job-based security and artifact contracts rather than weakening the job boundary.