fix: enforce known host values in azure.yaml schema#8877
Conversation
📋 Prioritization NoteThanks for the contribution! The linked issue isn't in the current milestone yet. |
There was a problem hiding this comment.
Pull request overview
This PR tightens the azure.yaml JSON schemas (v1.0 and alpha) by changing services.*.host from an unconstrained string to a fixed set of known host values, so YAML validation (e.g., VS Code redhat YAML via ajv) can flag misspellings that previously slipped through.
Changes:
- Add an
enumforservices.*.hostin the v1.0 schema to enforce known host values. - Add the same
enumforservices.*.hostin the alpha schema to keep validation behavior consistent across schema versions.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| schemas/v1.0/azure.yaml.json | Adds an enum of known host values to enforce schema validation for service hosts. |
| schemas/alpha/azure.yaml.json | Mirrors the same host enum enforcement in the alpha schema for parity. |
jongio
left a comment
There was a problem hiding this comment.
The goal here (IDE squiggles on misspelled hosts) is good, but a strict enum conflicts with azd's extension architecture. parseServiceHost() in service_target.go:68-75 explicitly allows any non-empty host value through because extensions register custom service-target providers at runtime via gRPC. This makes the host field intentionally open-ended; locking it down in the schema means every extension-provided host will show a spurious validation error in the user's editor.
Beyond the extensibility concern (already noted by the earlier review), several of the proposed enum values don't actually correspond to registered service-target providers in the codebase or extension registry:
microsoft.foundryazure.ai.projectazure.ai.connectionazure.ai.toolboxazure.ai.skillazure.ai.routine
None of these appear in the registry, extension providers declarations, or Go source as valid host identifiers. Only azure.ai.agent (from the azure.ai.agents extension) and the 6 built-in targets (appservice, containerapp, function, staticwebapp, aks, ai.endpoint) are actually resolvable today. Including unregistered names in the enum would validate misspelled-but-close values while still rejecting valid extension hosts not on the list.
A possible alternative: keep host as type: string (preserving extensibility) but expand the examples array so the YAML extension offers autocomplete for all known hosts without rejecting unknown ones.
jongio
left a comment
There was a problem hiding this comment.
Thanks for removing springapp, microsoft.foundry, and the redundant examples array. The updated description acknowledging extension hosts is also a good addition.
Two issues remain from my earlier review:
1. enum still breaks extensibility
The description says "hosts contributed by extensions are resolved by azd at runtime and may not be listed here," which is accurate, but enum in JSON Schema rejects any value not in the list. That means any extension-registered host that isn't listed will produce a spurious validation error in the editor. parseServiceHost() (service_target.go:68-75) explicitly allows any non-empty host value because extensions register custom service targets at runtime via gRPC. Using examples instead of enum would give autocomplete without rejecting unknown hosts.
2. Five enum values don't correspond to registered service-target providers
I checked every extension under cli/azd/extensions/:
azure.ai.projects(capabilities: custom-commands, metadata) - noservice-target-provider, noproviders:sectionazure.ai.connections(capabilities: custom-commands, metadata) - sameazure.ai.toolboxes(capabilities: custom-commands, metadata) - sameazure.ai.skills(capabilities: custom-commands, metadata) - sameazure.ai.routines(capabilities: custom-commands, metadata) - same
Only azure.ai.agents declares service-target-provider capability and registers azure.ai.agent as a provider. The other five names (azure.ai.project, azure.ai.connection, azure.ai.toolbox, azure.ai.skill, azure.ai.routine) aren't resolvable as host values today. Including them in an enum validates misspelled-but-close values while failing to catch actual typos in the names azd can resolve.
Suggestion: switch back to examples (keeps autocomplete, doesn't reject extension hosts), and trim the list to only the 7 hosts that are actually resolvable: appservice, containerapp, function, staticwebapp, aks, ai.endpoint, azure.ai.agent.
jongio
left a comment
There was a problem hiding this comment.
Two issues from my prior feedback remain unaddressed:
-
enum rejects valid extension hosts:
parseServiceHost()(service_target.go:68-75) allows any non-empty host value because extensions register custom service-target providers at runtime via gRPC.enumin JSON Schema rejects any value not in the list, so every extension-provided host will show a spurious validation error in the editor. The description acknowledges this butenumstill rejects them. Useexamplesinstead to give autocomplete without blocking unknown hosts. -
5 enum values aren't registered service-target providers:
azure.ai.project,azure.ai.connection,azure.ai.toolbox,azure.ai.skill,azure.ai.routinedon't appear asservice-target-providercapabilities in any extension manifest. Onlyazure.ai.agentsdeclares that capability. Including unresolvable host names validates typo-adjacent values while rejecting valid extension hosts.
Suggested fix: revert to examples (preserves autocomplete, doesn't reject extension hosts) and trim to the 7 actually-resolvable hosts: appservice, containerapp, function, staticwebapp, aks, ai.endpoint, azure.ai.agent.
| "description": "The Azure service that will be used as the target for deployment operations for the service.", | ||
| "examples": [ | ||
| "description": "The Azure service that will be used as the target for deployment operations for the service. Limited to the host types azd recognizes; hosts contributed by extensions are resolved by azd at runtime and may not be listed here.", | ||
| "enum": [ |
There was a problem hiding this comment.
enum will reject any host value not in this list. Since extensions register arbitrary service-target providers at runtime (azure.ai.agents does this today), users of those extensions will get false validation errors in their editor. Switch back to examples so the YAML extension offers autocomplete for known hosts without rejecting unknown ones.
What
Add an
enumof the knownhostvalues to the per-service schema in bothschemas/v1.0/azure.yaml.jsonandschemas/alpha/azure.yaml.json, mirroring the existingexampleslist.Why
Fixes #8856. In VS Code (redhat YAML extension) the unified Foundry
azure.yamlgave autocomplete but no validation squiggles. Root cause:hostwas a free-formtype: string, so a misspelled host likeazure.ai.projctwas a valid string and matched noif/thenbranch — no error. yaml-language-server validates withajv, so this reproduces exactly; with theenum, misspelled hosts now squiggle ("must be equal to one of the allowed values").Scope
Minimal and low-risk: the
enummirrors the curatedexamplesthe schema already advertises, so every valid host still passes.containerapp-dotnetis intentionally excluded (internal-only host, not valid inazure.yaml). Unknown-field detection was intentionally left out of scope to avoid surfacing squiggles in existingazure.yamlfiles that rely on the schema'sadditionalProperties: true.Verification
ajv(same engine as the YAML extension): misspelled host → invalid; baseline Foundry sample, classiccontainerappsample, andsimple.azure.yaml→ valid.jsonlintandjsonschema2mdon both schema files.