@@ -220,6 +220,10 @@ def login(self,
220
220
return deepcopy (consolidated )
221
221
222
222
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
+
223
227
import jwt
224
228
from azure .mgmt .core .tools import is_valid_resource_id
225
229
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
282
286
self ._set_subscriptions (consolidated )
283
287
return deepcopy (consolidated )
284
288
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
+
285
316
def login_in_cloud_shell (self ):
286
317
import jwt
287
318
from .auth .msal_credentials import CloudShellCredential
@@ -354,13 +385,18 @@ def get_login_credentials(self, resource=None, client_id=None, subscription_id=N
354
385
# Cloud Shell
355
386
from .auth .msal_credentials import CloudShellCredential
356
387
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 )
360
390
361
391
elif managed_identity_type :
362
392
# 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 )
364
400
365
401
else :
366
402
# user and service principal
@@ -415,9 +451,13 @@ def get_raw_token(self, resource=None, scopes=None, subscription=None, tenant=No
415
451
# managed identity
416
452
if tenant :
417
453
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 ))
421
461
422
462
else :
423
463
cred = self ._create_credential (account , tenant )
@@ -918,3 +958,8 @@ def _create_identity_instance(cli_ctx, *args, **kwargs):
918
958
return Identity (* args , encrypt = encrypt , use_msal_http_cache = use_msal_http_cache ,
919
959
enable_broker_on_windows = enable_broker_on_windows ,
920
960
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