diff --git a/packages/typespec-rust/src/codegen/clients.ts b/packages/typespec-rust/src/codegen/clients.ts index a273be8da..4d9c08c8a 100644 --- a/packages/typespec-rust/src/codegen/clients.ts +++ b/packages/typespec-rust/src/codegen/clients.ts @@ -126,7 +126,7 @@ export function emitClients(module: rust.ModuleContainer): ClientModules | undef } // if there's a credential param, create the necessary auth policy - const authPolicy = getAuthPolicy(constructor, use); + const authPolicy = getAuthPolicy(constructor, use, endpointParamName); if (authPolicy) { body += `${indent.get()}${authPolicy}\n`; } @@ -680,11 +680,19 @@ function getHeaderTraitDocComment(indent: helpers.indentation, module: rust.Modu * @param use the use statement builder currently in scope * @returns the auth policy instantiation code or undefined if not required */ -function getAuthPolicy(ctor: rust.Constructor, use: Use): string | undefined { +function getAuthPolicy(ctor: rust.Constructor, use: Use, endpointParamName: string): string | undefined { for (const param of ctor.params) { const arcTokenCred = utils.asTypeOf(param.type, 'tokenCredential', 'arc'); if (arcTokenCred) { use.add('azure_core::http::policies', 'auth::BearerTokenAuthorizationPolicy', 'Policy'); + const hasRelativeScopes = arcTokenCred.scopes.some(s => !s.startsWith('http')); + if (hasRelativeScopes) { + // Relative scopes (e.g. "user_impersonation" from ARM specs) must be + // qualified at runtime using the service endpoint so that sovereign + // clouds work correctly. The standard Azure SDK pattern is + // "{endpoint_origin}/.default". + return `let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new(credential, vec![format!("{}/.default", ${endpointParamName}.origin().ascii_serialization())]));`; + } const scopes = new Array(); for (const scope of arcTokenCred.scopes) { scopes.push(`"${scope}"`); diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/common-properties/src/generated/clients/common_properties_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/common-properties/src/generated/clients/common_properties_client.rs index c8c375dd9..6a1658253 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/common-properties/src/generated/clients/common_properties_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/common-properties/src/generated/clients/common_properties_client.rs @@ -62,7 +62,10 @@ impl CommonPropertiesClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/large-header/src/generated/clients/large_header_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/large-header/src/generated/clients/large_header_client.rs index 31b4e17a3..a1500057e 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/large-header/src/generated/clients/large_header_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/large-header/src/generated/clients/large_header_client.rs @@ -60,7 +60,10 @@ impl LargeHeaderClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/method-subscription-id/src/generated/clients/method_subscription_id_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/method-subscription-id/src/generated/clients/method_subscription_id_client.rs index 8ef711758..599d2b065 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/method-subscription-id/src/generated/clients/method_subscription_id_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/method-subscription-id/src/generated/clients/method_subscription_id_client.rs @@ -64,7 +64,10 @@ impl MethodSubscriptionIdClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-older-versions/src/generated/clients/combined_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-older-versions/src/generated/clients/combined_client.rs index 99793f126..45a541fc9 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-older-versions/src/generated/clients/combined_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-older-versions/src/generated/clients/combined_client.rs @@ -64,7 +64,10 @@ impl CombinedClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-shared-models/src/generated/clients/combined_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-shared-models/src/generated/clients/combined_client.rs index ea1292867..5989009ea 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-shared-models/src/generated/clients/combined_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/multi-service-shared-models/src/generated/clients/combined_client.rs @@ -65,7 +65,10 @@ impl CombinedClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/multi-service/src/generated/clients/combined_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/multi-service/src/generated/clients/combined_client.rs index 6075b0fa3..3a5933095 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/multi-service/src/generated/clients/combined_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/multi-service/src/generated/clients/combined_client.rs @@ -64,7 +64,10 @@ impl CombinedClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/non-resource/src/generated/clients/non_resource_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/non-resource/src/generated/clients/non_resource_client.rs index 819047c92..5b8fa2df6 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/non-resource/src/generated/clients/non_resource_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/non-resource/src/generated/clients/non_resource_client.rs @@ -60,7 +60,10 @@ impl NonResourceClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/operation-templates/src/generated/clients/operation_templates_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/operation-templates/src/generated/clients/operation_templates_client.rs index 6a3e15f77..63856781e 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/operation-templates/src/generated/clients/operation_templates_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/operation-templates/src/generated/clients/operation_templates_client.rs @@ -64,7 +64,10 @@ impl OperationTemplatesClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint, diff --git a/packages/typespec-rust/test/spector/azure/resource-manager/resources/src/generated/clients/resources_client.rs b/packages/typespec-rust/test/spector/azure/resource-manager/resources/src/generated/clients/resources_client.rs index 01737c30d..3f3c201d5 100644 --- a/packages/typespec-rust/test/spector/azure/resource-manager/resources/src/generated/clients/resources_client.rs +++ b/packages/typespec-rust/test/spector/azure/resource-manager/resources/src/generated/clients/resources_client.rs @@ -63,7 +63,10 @@ impl ResourcesClient { } let auth_policy: Arc = Arc::new(BearerTokenAuthorizationPolicy::new( credential, - vec!["user_impersonation"], + vec![format!( + "{}/.default", + endpoint.origin().ascii_serialization() + )], )); Ok(Self { endpoint,