Add trusted cloud configuration - #20294
Tate Smalligan (tsmallig33) wants to merge 7 commits into
Conversation
|
Test this change out locally with the following install scripts (Action run 34899956247) VSCode
Azure CLI
|
There was a problem hiding this comment.
🔵 Needs a closer look
ACR completion ARM client construction currently ignores the configured cloud environment options, which can break non-public-cloud endpoint behavior.
Pull request overview
Adds a “trusted cloud” gate to prevent credentials/tokens and registry/ARM traffic from being directed through attacker-controlled custom cloud profiles unless explicitly approved via BICEP_TRUSTED_CLOUDS. This fits into Bicep’s security model alongside trusted registries by ensuring the cloud profile itself is trusted before any networked Azure/registry operations occur.
Changes:
- Introduces
CloudConfigurationTrustPolicy(built-ins trusted; custom/modified requireBICEP_TRUSTED_CLOUDS) and wires it into DI. - Blocks OCI/module restore/publish, Template Spec restore, ARM client creation, and completion-time registry discovery when the active cloud is untrusted (new diagnostics
BCP456/BCP457). - Updates built-in cloud profiles (Bleu/Germany) and VS Code bicepconfig schema, with new/updated unit tests.
File summaries
| File | Description |
|---|---|
| src/vscode-bicep/resources/configuration/bicepconfig.schema.json | Document trust model + new built-ins |
| src/Bicep.Wasm/WasmModuleRegistryProvider.cs | Pass trust policy into OCI registry |
| src/Bicep.LangServer/Features/Language/Completion/ModuleReferenceCompletionProvider.cs | Skip unsafe registry completions |
| src/Bicep.LangServer/Features/Language/Completion/AzureContainerRegistriesProvider.cs | Enforce trusted cloud before ARM queries |
| src/Bicep.LangServer/Features/Custom/InsertResource/AzResourceProvider.cs | Enforce trusted cloud before ARM client |
| src/Bicep.LangServer.UnitTests/Handlers/BicepExternalSourceDocumentLinkHandlerTests.cs | Update config manager construction |
| src/Bicep.LangServer.UnitTests/Configuration/BicepConfigChangeHandlerTests.cs | Update config manager construction |
| src/Bicep.LangServer.UnitTests/Completions/ModuleReferenceCompletionProviderTests.cs | Add/adjust untrusted-cloud completion tests |
| src/Bicep.Core/Registry/TemplateSpecModuleRegistry.cs | Block Template Spec restore on untrusted cloud |
| src/Bicep.Core/Registry/OciArtifactRegistry.cs | Block OCI operations on untrusted cloud |
| src/Bicep.Core/Registry/DefaultArtifactRegistryProvider.cs | Plumb trust policy into registries |
| src/Bicep.Core/Registry/ContainerRegistryClientFactory.cs | Enforce trusted cloud before ACR clients |
| src/Bicep.Core/Registry/Catalog/Implementation/RegistryModuleCatalog.cs | Enforce trusted cloud before catalog providers |
| src/Bicep.Core/Diagnostics/DiagnosticBuilder.cs | Add BCP456/BCP457 diagnostics |
| src/Bicep.Core/Configuration/CloudConfigurationTrustPolicy.cs | New: trust policy + env parsing/normalization |
| src/Bicep.Core/Configuration/BicepConfigurationManager.cs | Add trust diagnostics at config bind time |
| src/Bicep.Core/Configuration/bicepconfig.json | Add built-in Bleu/Germany profiles |
| src/Bicep.Core/BicepCoreServiceCollectionExtensions.cs | Register trust policy from environment |
| src/Bicep.Core/AzureApi/TokenCredentialFactory.cs | Gate credential acquisition by trusted authority |
| src/Bicep.Core/AzureApi/ArmClientProvider.cs | Gate ARM client creation by trusted cloud |
| src/Bicep.Core.UnitTests/Utils/RegistryHelper.cs | Update config manager construction |
| src/Bicep.Core.UnitTests/Utils/OciRegistryHelper.cs | Pass trust policy into OCI registry |
| src/Bicep.Core.UnitTests/Registry/TokenCredentialFactoryTests.cs | Add authority trust test + ctor update |
| src/Bicep.Core.UnitTests/Registry/TemplateSpecModuleRegistryTests.cs | New: untrusted-cloud Template Spec restore test |
| src/Bicep.Core.UnitTests/Registry/OciModuleRegistryTests.cs | Add untrusted-cloud OCI tests |
| src/Bicep.Core.UnitTests/Configuration/CloudTrustGateTests.cs | New: verify trust gate precedes credential/client |
| src/Bicep.Core.UnitTests/Configuration/CloudConfigurationTrustPolicyTests.cs | New: trust policy behavior tests |
| src/Bicep.Core.UnitTests/Configuration/CloudConfigurationTrustPolicyRegistrationTests.cs | New: env var registration tests |
| src/Bicep.Core.UnitTests/Configuration/BicepConfigurationManagerTests.cs | Add trusted/untrusted cloud config-chain tests |
| src/Bicep.Core.UnitTests/BicepTestConstants.cs | Add shared test trust policy constant |
| src/Bicep.Core.UnitTests/Registry/Catalog/PrivateAcrModuleMetadataProviderTests.cs | Update config manager construction |
| src/Bicep.Core.UnitTests/Mock/Registry/RegistryCatalogMocks.cs | Pass trust policy into catalog |
| src/Bicep.Core.UnitTests/Features/FeatureProviderTests.cs | Update config manager construction |
| src/Bicep.Core.UnitTests/Configuration/ProviderConfigurationTests.cs | Update config manager construction |
| src/Bicep.Core.UnitTests/Configuration/ConfigurationManagerTests.cs | Update built-in profile baselines + ctor updates |
Review details
Suppressed comments (1)
src/Bicep.LangServer/Features/Language/Completion/AzureContainerRegistriesProvider.cs:76
GetArmClientbuilds anArmClientOptionswith the cloud-specific environment/auth scope, but the options are never passed toArmClient. As a result, ACR discovery will run against the default public cloud even when the selected built-in profile is China/Gov/etc (or a trusted custom cloud), which breaks the intent of cloud-specific configuration.
- Files reviewed: 35/35 changed files
- Comments generated: 0
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| "AzureGermanyCloud": { | ||
| "resourceManagerEndpoint": "https://management.sovcloud-api.de", | ||
| "activeDirectoryAuthority": "https://login.sovcloud-identity.de" | ||
| }, |
There was a problem hiding this comment.
I notice this isn't yet checked in to AzureCLI. Are we OK to include it here?
There was a problem hiding this comment.
Thanks, good catch. I will remove for now and match just the list here: https://github.com/Azure/azure-cli/blob/4308f9e91fcabc170032efd08455238140bd0c3f/src/azure-cli-core/azure/cli/core/cloud.py#L522
|
|
||
| public ContainerRegistryClient CreateAnonymousContainerClient(IBicepCloudConfiguration cloud, Uri registryUri) | ||
| { | ||
| cloudTrustPolicy.ThrowIfCloudIsUntrusted(cloud); |
There was a problem hiding this comment.
Rather than having to remember to check this everywhere (which could be fragile if someone adds a new code path and forgets to copy this logic), would it be worth just refusing to build the configuration with untrusted values in the first place?
There was a problem hiding this comment.
Updated to add the trusted cloud check to where we build the configuration and raise a diagnostic similar to if we cannot parse the config file. If this happens, we raise an error and the built in config is used instead.
|
|
||
| public sealed class CloudConfigurationTrustPolicy | ||
| { | ||
| public const string TrustedCloudsEnvironmentVariable = "BICEP_TRUSTED_CLOUDS"; |
There was a problem hiding this comment.
Could we store all env variable names in one place, to make it easier to keep track of them?
There was a problem hiding this comment.
Added all env variable names I could find to BicepEnvironmentVariables.cs
| } | ||
| } | ||
|
|
||
| public static CloudConfigurationTrustPolicy FromEnvironmentValue(string? value) |
There was a problem hiding this comment.
This feels unnecessarily complex. I think it's perfectly reasonable to just parse the entire variable in one go, and just fail if it isn't valid.
I think you could replace the entire method with something like:
public static CloudConfigurationTrustPolicy FromEnvironmentValue(string? value)
=> value is {} ? JsonSerializer.Deserialize<value, SerializationContext.Default.CloudConfigurationTrustPolicy>() : null);
Description
Add Trusted Cloud Configuration. Custom Clouds will require setting env variable BICEP_TRUSTED_CLOUDS similar to the Trusted Registries Implementation.
Example Usage
Note: Custom Clouds which are not included in the built in list will need to set the trusted clouds environment variable
$env:BICEP_TRUSTED_CLOUDS = '[{"resourceManagerEndpoint":"https://management.example.com","activeDirectoryAuthority":"https://login.example.com"}]'
Checklist
Microsoft Reviewers: Open in CodeFlow