Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions packages/typespec-rust/src/codegen/clients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`;
}
Expand Down Expand Up @@ -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<rust.TokenCredential>(param.type, 'tokenCredential', 'arc');
if (arcTokenCred) {
use.add('azure_core::http::policies', 'auth::BearerTokenAuthorizationPolicy', 'Policy');
const hasRelativeScopes = arcTokenCred.scopes.some(s => !s.startsWith('http'));
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

!s.startsWith('http') misclassifies non-HTTP absolute scopes (e.g., api://{client-id}/.default) as “relative”, which would incorrectly replace them with {endpoint_origin}/.default. Consider detecting “absolute” scopes by checking for a URI scheme (e.g., s.includes('://')) or using URL parsing where possible, and only treating truly relative bare scopes as relative.

Suggested change
const hasRelativeScopes = arcTokenCred.scopes.some(s => !s.startsWith('http'));
const hasRelativeScopes = arcTokenCred.scopes.some(s => !s.includes('://'));

Copilot uses AI. Check for mistakes.
if (hasRelativeScopes) {
Comment on lines +688 to +689
Copy link

Copilot AI Apr 7, 2026

Choose a reason for hiding this comment

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

This introduces new branching behavior for scope classification. Add an emitter test that covers (1) relative scopes (user_impersonation), (2) absolute https scopes (https://vault.azure.net/.default), and (3) non-HTTP absolute scopes (e.g., api://.../.default) to prevent regressions in the relative/absolute detection.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@copilot apply changes based on active feedback

// 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<dyn Policy> = Arc::new(BearerTokenAuthorizationPolicy::new(credential, vec![format!("{}/.default", ${endpointParamName}.origin().ascii_serialization())]));`;
}
const scopes = new Array<string>();
for (const scope of arcTokenCred.scopes) {
scopes.push(`"${scope}"`);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading