Skip to content

Feature: allow safe-outputs.threat-detection to be controlled by workflow_call inputs #29171

@bbonafed

Description

@bbonafed

Problem

Reusable workflow_call agentic workflows often need callers to choose whether safe-output threat detection should run for a particular invocation. Today safe-outputs.threat-detection is effectively compile-time: literal booleans and object config are accepted, but a GitHub Actions expression such as ${{ inputs.enable-threat-detection }} is not accepted as the top-level value or as threat-detection.enabled.

This means a reusable workflow cannot expose a simple input that lets callers select stricter or lighter-weight safe-output handling at runtime. Authors have to maintain separate workflow files for configurations that differ only in threat-detection behavior.

Related context: #23724 established appetite for parameterizing frontmatter fields other than engine.id. The earlier follow-ups covered timeout-minutes, engine.version, and some tool timeout fields, but not threat-detection toggles.

Desired Behavior

Both literal and expression forms should work:

on:
  workflow_call:
    inputs:
      enable-threat-detection:
        type: boolean
        required: false
        default: true
---
safe-outputs:
  threat-detection: ${{ inputs.enable-threat-detection }}

And, if the object form is preferred for implementation clarity:

safe-outputs:
  threat-detection:
    enabled: ${{ inputs.enable-threat-detection }}
    continue-on-error: ${{ inputs.detection-continue-on-error }}

Literal forms should remain backward compatible:

safe-outputs:
  threat-detection: false
safe-outputs:
  threat-detection:
    enabled: true
    continue-on-error: false

Implementation Plan

Please implement this as an agentic plan rather than a direct community PR.

  1. Schema updates

    • Update pkg/parser/schemas/main_workflow_schema.json so safe-outputs.threat-detection accepts a GitHub Actions expression string in addition to the current boolean/object forms.
    • Update the object form so enabled and continue-on-error accept templatable booleans.
    • Reuse the existing expression pattern and boolean-templating conventions already used elsewhere in safe-output config.
  2. Parsing and config model

    • Update ThreatDetectionConfig and parseThreatDetectionConfig so boolean literals and expression strings are preserved distinctly.
    • Consider using the existing preprocessBoolFieldAsString / buildTemplatableBoolEnvVar / AddTemplatableBool helpers if they fit this path.
    • Preserve current default behavior: when safe-outputs exists and threat-detection is omitted, detection remains enabled by default.
    • Preserve current explicit-disable behavior for literal false.
  3. Compilation behavior

    • If an expression controls whether detection is enabled, compile a runtime conditional instead of deciding only at compile time.
    • Ensure generated needs and downstream safe-output/conclusion jobs handle the detection job being skipped at runtime.
    • Prefer an explicit job or step if: using the caller expression over shell-time branching.
    • Ensure continue-on-error expression values are passed safely, without direct shell interpolation.
  4. Tests

    • Add schema and parser coverage for:
      • threat-detection: true
      • threat-detection: false
      • threat-detection: ${{ inputs.enable-threat-detection }}
      • object-form enabled and continue-on-error expression values
      • invalid non-expression strings
    • Add compiler tests proving the expression appears in the generated lock YAML in a runtime-evaluable location.
    • Add tests for downstream jobs when detection is conditionally skipped.
  5. Documentation

    • Update the safe outputs and threat detection references to show reusable workflow_call examples.
    • Mention that runtime expression support may compile the detection path and skip it at runtime rather than removing it at compile time.

Acceptance Criteria

  • Literal boolean and object-form threat detection config remain backward compatible.
  • safe-outputs.threat-detection: ${{ inputs.enable-threat-detection }} validates and compiles.
  • safe-outputs.threat-detection.enabled and continue-on-error accept boolean expressions.
  • The compiled workflow evaluates the expression at GitHub Actions runtime.
  • Conditional detection does not break safe-output or conclusion jobs when skipped.
  • Invalid non-expression strings produce clear validation errors.
  • Tests and docs are updated.

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