Skip to content

Add safe-outputs.allowed-url-domains for additive URL domain allowlisting#21083

Merged
pelikhan merged 3 commits intomainfrom
copilot/add-safe-outputs-allowed-domains
Mar 15, 2026
Merged

Add safe-outputs.allowed-url-domains for additive URL domain allowlisting#21083
pelikhan merged 3 commits intomainfrom
copilot/add-safe-outputs-allowed-domains

Conversation

Copy link
Contributor

Copilot AI commented Mar 15, 2026

Adds safe-outputs.allowed-url-domains: a new field for specifying additional domains allowed in URL sanitization. Unlike the existing allowed-domains (full override), this field unions with the engine defaults and network.allowed.

Changes

  • New field safe-outputs.allowed-url-domains

    • Supports same ecosystem identifier syntax as network.allowed (python, node, dev-tools, default-redaction, etc.)
    • Expands ecosystem identifiers via expandAllowedURLDomains; merged into the engine/network base set via computeAllowedURLDomainsForSanitization
    • Always includes localhost and github.com in the final set
  • New dev-tools ecosystem (pkg/workflow/data/ecosystem_domains.json)

    • Common CI/CD and code-quality tool domains: codecov.io, snyk.io, circleci.com, shields.io, readthedocs.org, sonarcloud.io, etc.
  • New default-redaction compound ecosystem

    • Expands to the union of defaults (infrastructure/cert domains) + dev-tools (CI/CD/code-quality domains)
    • Implemented via a compoundEcosystems map in domains.go — no data duplication, resolved at lookup time
    • Recommended baseline for safe-outputs.allowed-url-domains in most workflows
  • Applied to all smoke- workflows* — all 19 smoke-*.md workflows now include allowed-url-domains: [default-redaction]

  • ValidationvalidateSafeOutputsAllowedURLDomains skips ecosystem identifiers (same as validateNetworkAllowedDomains); plain domains go through validateDomainPattern

  • Schemaallowed-url-domains added to main_workflow_schema.json

Example

safe-outputs:
  create-issue:
  allowed-url-domains:
    - default-redaction  # expands to defaults infra + dev-tools (codecov.io, snyk.io, shields.io, …)
    - python             # expands to pypi.org, files.pythonhosted.org, …
    - custom-api.com     # plain domain

Result: GH_AW_ALLOWED_DOMAINS = engine defaults ∪ network.allowedallowed-url-domains + localhost + github.com

Original prompt

Add a frontmatter field safe-outputs.allowed-url-domains: string[] that provides additional allowed domains for URL redaction.

  • same syntax as network.allowed
  • supports domain sets from network.allowed as well
  • unionized with network.allowed when computing the final set
  • built custom set for dev-tools domains, ...
  • always allows the GitHub page of the current repo (approximate to public repo syntax), localhost

This is to allow additional domains on URLs


📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

… URL domain allowlisting

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Add frontmatter field for allowed URL domains Add safe-outputs.allowed-url-domains for additive URL domain allowlisting Mar 15, 2026
Copilot AI requested a review from pelikhan March 15, 2026 15:27
Copy link
Contributor

@pelikhan pelikhan left a comment

Choose a reason for hiding this comment

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

@copilot create a default set for redaction that includes the default network + dev-tools (default-redaction)

Apply to smoke-* workflows.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Mar 15, 2026

@copilot create a default set for redaction that includes the default network + dev-tools (default-redaction)

Apply to smoke-* workflows.

Done in 0d4c530.

Added a default-redaction compound ecosystem (= defaults + dev-tools) implemented via a compoundEcosystems map in domains.go — domains are expanded at lookup time without duplicating any data.

All 19 smoke-* workflows now include:

safe-outputs:
  allowed-url-domains: [default-redaction]

The resulting GH_AW_ALLOWED_DOMAINS in the lock files now includes the full union: engine defaults + network.allowed + defaults infra + dev-tools (codecov.io, snyk.io, shields.io, readthedocs.org, etc.) + localhost + github.com.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/graphql
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw ithub/workflows//opt/hostedtoolcache/node/24.14.0/x64/bin/npx ithub/workflows/prettier x_amd64/link ithu�� ithub/workflows/!../../../pkg/workflow/js/**/*.json .cfg 64/pkg/tool/linu../../../.prettierignore (http block)
    • Triggering command: /usr/bin/gh /usr/bin/gh api graphql -f query=query($owner: String!, $name: String!) { repository(owner: $owner, name: $name) { hasDiscussionsEnabled } } -f owner=github -f name=gh-aw flow (http block)
  • https://api.github.com/repos/actions/ai-inference/git/ref/tags/v1
    • Triggering command: /usr/bin/gh gh api /repos/actions/ai-inference/git/ref/tags/v1 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v3
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v5
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha ck &#39;scripts/**/*GOINSECURE GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE sh (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /usr/bin/git GOINSECURE GOMOD GOMODCACHE git (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v5 --jq .object.sha --show-toplevel node /usr/bin/git run lint:cjs 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git &#34;prettier&#34; --chegit git 64/bin/go git (http block)
  • https://api.github.com/repos/actions/checkout/git/ref/tags/v6
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/checkout/git/ref/tags/v6 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git npx prettier --cgit GOPROXY 64/bin/go git (http block)
  • https://api.github.com/repos/actions/github-script/git/ref/tags/v8
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
    • Triggering command: /usr/bin/gh gh api /repos/actions/github-script/git/ref/tags/v8 --jq .object.sha --show-toplevel go /usr/bin/git -json GO111MODULE 64/bin/go git rev-�� --show-toplevel sh /usr/bin/git npx prettier --cgit GOPROXY 64/bin/go git (http block)
  • https://api.github.com/repos/actions/setup-go/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-go/git/ref/tags/v4 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/setup-node/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/setup-node/git/ref/tags/v4 --jq .object.sha -json GO111MODULE ache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE /opt/hostedtoolcache/go/1.25.0/x64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/actions/upload-artifact/git/ref/tags/v4
    • Triggering command: /usr/bin/gh gh api /repos/actions/upload-artifact/git/ref/tags/v4 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b
    • Triggering command: /usr/bin/gh gh api /repos/astral-sh/setup-uv/git/ref/tags/eac588ad8def6316056a12d4907a9d4d84ff7a3b --jq .object.sha h ../../../.prettierignore (http block)
  • https://api.github.com/repos/github/gh-aw
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw --jq .visibility json&#39; --ignore-premote.origin.url user.email ache/go/1.25.0/x64/pkg/tool/linu../../../.prettierignore (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.0.0 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw-actions/git/ref/tags/v1.2.3
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw-actions/git/ref/tags/v1.2.3 --jq .object.sha -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go env -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/github/gh-aw/git/ref/tags/v1.0.0
    • Triggering command: /usr/bin/gh gh api /repos/github/gh-aw/git/ref/tags/v1.0.0 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go ache�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)
  • https://api.github.com/repos/githubnext/agentics/git/ref/tags/
    • Triggering command: /usr/bin/gh gh api /repos/githubnext/agentics/git/ref/tags/# --jq .object.sha re --log-level=error .cfg $name) { hasDiscussionsEnabled } } (http block)
  • https://api.github.com/repos/nonexistent/action/git/ref/tags/v999.999.999
    • Triggering command: /usr/bin/gh gh api /repos/nonexistent/action/git/ref/tags/v999.999.999 --jq .object.sha GOSUMDB GOWORK 64/bin/go GOINSECURE GOMOD GOMODCACHE go ache�� -json GO111MODULE 64/bin/go GOINSECURE GOMOD GOMODCACHE go (http block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI requested a review from pelikhan March 15, 2026 16:43
@pelikhan pelikhan marked this pull request as ready for review March 15, 2026 18:25
Copilot AI review requested due to automatic review settings March 15, 2026 18:25
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new safe-outputs.allowed-url-domains frontmatter field to additively expand the URL-sanitization allowlist (unioned with engine defaults + network.allowed), including new ecosystem domain groups (dev-tools, default-redaction) and updates smoke workflows to use the new baseline.

Changes:

  • Introduce safe-outputs.allowed-url-domains parsing, validation, schema support, and allowlist computation/unioning.
  • Add dev-tools ecosystem domains and a default-redaction compound ecosystem (defaults ∪ dev-tools).
  • Apply allowed-url-domains: [default-redaction] across smoke workflows and update generated lock files; add/extend tests.

Reviewed changes

Copilot reviewed 49 out of 49 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
pkg/workflow/safe_outputs_validation.go Adds validation for safe-outputs.allowed-url-domains (skipping ecosystem identifiers).
pkg/workflow/safe_outputs_config.go Parses allowed-url-domains from safe-outputs frontmatter into SafeOutputsConfig.
pkg/workflow/domains.go Adds compound ecosystem expansion and computes the unioned URL-sanitization allowlist.
pkg/workflow/domains_test.go Adds unit tests for URL domain expansion/unioning and compound ecosystem behavior.
pkg/workflow/data/ecosystem_domains.json Adds dev-tools domain set used by URL allowlisting.
pkg/workflow/compiler_yaml.go Emits GH_AW_ALLOWED_DOMAINS using the new unioned computation when allowed-url-domains is set.
pkg/workflow/compiler_safe_outputs_steps.go Same as above for the consolidated safe-outputs handler manager step.
pkg/workflow/compiler_types.go Extends SafeOutputsConfig with AllowedURLDomains.
pkg/workflow/compiler.go Hooks allowed-url-domains validation into workflow compilation.
pkg/workflow/allowed_domains_sanitization_test.go Adds integration-style tests verifying union behavior via compiled lock output.
pkg/parser/schemas/main_workflow_schema.json Adds schema support for safe-outputs.allowed-url-domains (plus some unrelated unicode-escape updates).
.github/workflows/smoke-workflow-call.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-workflow-call.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-workflow-call-with-inputs.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-workflow-call-with-inputs.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-update-cross-repo-pr.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-update-cross-repo-pr.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-test-tools.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-test-tools.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-temporary-id.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-temporary-id.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-project.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-project.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-multi-pr.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-multi-pr.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-gemini.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-gemini.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-create-cross-repo-pr.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-create-cross-repo-pr.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-copilot.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-copilot.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-copilot-arm.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-copilot-arm.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-codex.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-codex.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-claude.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-claude.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-call-workflow.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-call-workflow.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-agent-scoped-approved.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-agent-scoped-approved.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-agent-public-none.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-agent-public-none.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-agent-public-approved.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-agent-public-approved.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-agent-all-none.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-agent-all-none.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.
.github/workflows/smoke-agent-all-merged.md Adds safe-outputs.allowed-url-domains: [default-redaction].
.github/workflows/smoke-agent-all-merged.lock.yml Regenerates lock output with expanded GH_AW_ALLOWED_DOMAINS.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +1033 to +1036
// Should include both defaults and dev-tools (at least 34+21 = 55 domains)
if len(result) < 50 {
t.Errorf("Expected at least 50 domains in default-redaction, got %d", len(result))
}
Comment on lines +103 to +108
for i, domain := range config.AllowedURLDomains {
// Skip ecosystem identifiers - they don't need domain pattern validation
if isEcosystemIdentifier(domain) {
safeOutputsDomainsValidationLog.Printf("Skipping ecosystem identifier: %s", domain)
continue
}
Comment on lines 695 to 701
if data.SafeOutputs != nil && len(data.SafeOutputs.AllowedDomains) > 0 {
// Use manually configured allowed domains
// Use manually configured allowed domains (legacy override behavior)
domainsStr = strings.Join(data.SafeOutputs.AllowedDomains, ",")
} else if data.SafeOutputs != nil && len(data.SafeOutputs.AllowedURLDomains) > 0 {
// allowed-url-domains: additional domains unioned with engine/network base set
domainsStr = c.computeAllowedURLDomainsForSanitization(data)
} else {
Comment on lines 321 to 329
var domainsStr string
if data.SafeOutputs != nil && len(data.SafeOutputs.AllowedDomains) > 0 {
domainsStr = strings.Join(data.SafeOutputs.AllowedDomains, ",")
} else if data.SafeOutputs != nil && len(data.SafeOutputs.AllowedURLDomains) > 0 {
// allowed-url-domains: additional domains unioned with engine/network base set
domainsStr = c.computeAllowedURLDomainsForSanitization(data)
} else {
domainsStr = c.computeAllowedDomainsForSanitization(data)
}
Comment on lines +672 to +686
// expandAllowedURLDomains expands a list of domain entries (which may include ecosystem
// identifiers like "python", "node", "dev-tools") into a deduplicated, sorted list of
// concrete domain strings. This uses the same expansion logic as network.allowed.
func expandAllowedURLDomains(entries []string) []string {
domainMap := make(map[string]bool)
for _, entry := range entries {
ecosystemDomains := getEcosystemDomains(entry)
if len(ecosystemDomains) > 0 {
for _, d := range ecosystemDomains {
domainMap[d] = true
}
} else {
domainMap[entry] = true
}
}
Comment on lines +229 to 251
"dev-tools": [
"app.renovatebot.com",
"appveyor.com",
"badgen.net",
"circleci.com",
"codacy.com",
"codeclimate.com",
"codecov.io",
"coveralls.io",
"deepsource.io",
"docs.github.com",
"drone.io",
"img.shields.io",
"readthedocs.io",
"readthedocs.org",
"renovatebot.com",
"semaphoreci.com",
"shields.io",
"snyk.io",
"sonarcloud.io",
"sonarqube.com",
"travis-ci.com"
]
@pelikhan pelikhan merged commit e45ae5c into main Mar 15, 2026
86 checks passed
@pelikhan pelikhan deleted the copilot/add-safe-outputs-allowed-domains branch March 15, 2026 18:34
github-actions bot added a commit that referenced this pull request Mar 15, 2026
Document two user-facing features merged on 2026-03-15 after DDUw's
04:31 UTC scan:

- gh aw domains (PR #21086): new CLI command to list effective network
  domains for each workflow, including ecosystem-expanded domains and
  engine defaults. Added to the Monitoring section of cli.md.

- safe-outputs.allowed-url-domains (PR #21083): new safe-outputs field
  that additively extends the URL sanitization domain allowlist (unions
  with the engine/network base set). Distinct from allowed-domains, which
  replaces the default set. Updated the Text Sanitization section of
  safe-outputs.md.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants