@@ -220,6 +220,10 @@ def login(self,
220220 return deepcopy (consolidated )
221221
222222 def login_with_managed_identity (self , identity_id = None , allow_no_subscriptions = None ):
223+ if _on_azure_arc_windows ():
224+ return self .login_with_managed_identity_azure_arc_windows (
225+ identity_id = identity_id , allow_no_subscriptions = allow_no_subscriptions )
226+
223227 import jwt
224228 from azure .mgmt .core .tools import is_valid_resource_id
225229 from azure .cli .core .auth .adal_authentication import MSIAuthenticationWrapper
@@ -282,6 +286,33 @@ def login_with_managed_identity(self, identity_id=None, allow_no_subscriptions=N
282286 self ._set_subscriptions (consolidated )
283287 return deepcopy (consolidated )
284288
289+ def login_with_managed_identity_azure_arc_windows (self , identity_id = None , allow_no_subscriptions = None ):
290+ import jwt
291+ identity_type = MsiAccountTypes .system_assigned
292+ from .auth .msal_credentials import ManagedIdentityCredential
293+
294+ cred = ManagedIdentityCredential ()
295+ token = cred .get_token (* self ._arm_scope ).token
296+ logger .info ('Managed identity: token was retrieved. Now trying to initialize local accounts...' )
297+ decode = jwt .decode (token , algorithms = ['RS256' ], options = {"verify_signature" : False })
298+ tenant = decode ['tid' ]
299+
300+ subscription_finder = SubscriptionFinder (self .cli_ctx )
301+ subscriptions = subscription_finder .find_using_specific_tenant (tenant , cred )
302+ base_name = ('{}-{}' .format (identity_type , identity_id ) if identity_id else identity_type )
303+ user = _USER_ASSIGNED_IDENTITY if identity_id else _SYSTEM_ASSIGNED_IDENTITY
304+ if not subscriptions :
305+ if allow_no_subscriptions :
306+ subscriptions = self ._build_tenant_level_accounts ([tenant ])
307+ else :
308+ raise CLIError ('No access was configured for the managed identity, hence no subscriptions were found. '
309+ "If this is expected, use '--allow-no-subscriptions' to have tenant level access." )
310+
311+ consolidated = self ._normalize_properties (user , subscriptions , is_service_principal = True ,
312+ user_assigned_identity_id = base_name )
313+ self ._set_subscriptions (consolidated )
314+ return deepcopy (consolidated )
315+
285316 def login_in_cloud_shell (self ):
286317 import jwt
287318 from .auth .msal_credentials import CloudShellCredential
@@ -354,13 +385,18 @@ def get_login_credentials(self, resource=None, client_id=None, subscription_id=N
354385 # Cloud Shell
355386 from .auth .msal_credentials import CloudShellCredential
356387 from azure .cli .core .auth .credential_adaptor import CredentialAdaptor
357- cs_cred = CloudShellCredential ()
358- # The cloud shell credential must be wrapped by CredentialAdaptor so that it can work with Track 1 SDKs.
359- cred = CredentialAdaptor (cs_cred , resource = resource )
388+ # The credential must be wrapped by CredentialAdaptor so that it can work with Track 1 SDKs.
389+ cred = CredentialAdaptor (CloudShellCredential (), resource = resource )
360390
361391 elif managed_identity_type :
362392 # managed identity
363- cred = MsiAccountTypes .msi_auth_factory (managed_identity_type , managed_identity_id , resource )
393+ if _on_azure_arc_windows ():
394+ from .auth .msal_credentials import ManagedIdentityCredential
395+ from azure .cli .core .auth .credential_adaptor import CredentialAdaptor
396+ # The credential must be wrapped by CredentialAdaptor so that it can work with Track 1 SDKs.
397+ cred = CredentialAdaptor (ManagedIdentityCredential (), resource = resource )
398+ else :
399+ cred = MsiAccountTypes .msi_auth_factory (managed_identity_type , managed_identity_id , resource )
364400
365401 else :
366402 # user and service principal
@@ -415,9 +451,13 @@ def get_raw_token(self, resource=None, scopes=None, subscription=None, tenant=No
415451 # managed identity
416452 if tenant :
417453 raise CLIError ("Tenant shouldn't be specified for managed identity account" )
418- from .auth .util import scopes_to_resource
419- cred = MsiAccountTypes .msi_auth_factory (managed_identity_type , managed_identity_id ,
420- scopes_to_resource (scopes ))
454+ if _on_azure_arc_windows ():
455+ from .auth .msal_credentials import ManagedIdentityCredential
456+ cred = ManagedIdentityCredential ()
457+ else :
458+ from .auth .util import scopes_to_resource
459+ cred = MsiAccountTypes .msi_auth_factory (managed_identity_type , managed_identity_id ,
460+ scopes_to_resource (scopes ))
421461
422462 else :
423463 cred = self ._create_credential (account , tenant )
@@ -918,3 +958,8 @@ def _create_identity_instance(cli_ctx, *args, **kwargs):
918958 return Identity (* args , encrypt = encrypt , use_msal_http_cache = use_msal_http_cache ,
919959 enable_broker_on_windows = enable_broker_on_windows ,
920960 instance_discovery = instance_discovery , ** kwargs )
961+
962+
963+ def _on_azure_arc_windows ():
964+ # This indicates an Azure Arc-enabled Windows server
965+ return "IDENTITY_ENDPOINT" in os .environ and "IMDS_ENDPOINT" in os .environ
0 commit comments