Skip to content
Draft
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
6 changes: 5 additions & 1 deletion src/azure-cli-core/azure/cli/core/_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ def login(self,
is_service_principal,
tenant,
scopes=None,
use_broker_sso=False,
use_device_code=False,
allow_no_subscriptions=False,
use_cert_sn_issuer=None,
Expand Down Expand Up @@ -176,7 +177,10 @@ def login(self,
if use_device_code:
user_identity = identity.login_with_device_code(scopes=scopes, claims_challenge=claims_challenge)
else:
user_identity = identity.login_with_auth_code(scopes=scopes, claims_challenge=claims_challenge)
user_identity = identity.login_with_auth_code(
scopes=scopes,
claims_challenge=claims_challenge,
use_broker_sso=use_broker_sso)
else:
if not is_service_principal:
user_identity = identity.login_with_username_password(username, password, scopes=scopes)
Expand Down
5 changes: 5 additions & 0 deletions src/azure-cli-core/azure/cli/core/auth/agentic_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@
COPILOT_AGENT_SESSION_ID = "COPILOT_AGENT_SESSION_ID"


def is_agentic_session():
"""Determine if we're in an agentic session based on the presence of COPILOT_AGENT_SESSION_ID."""
return os.environ.get(COPILOT_AGENT_SESSION_ID) is not None


def build_agentic_session_params():
"""Read COPILOT_AGENT_SESSION_ID and build the agentic claims challenge.
Expand Down
21 changes: 18 additions & 3 deletions src/azure-cli-core/azure/cli/core/auth/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ def _service_principal_store(self):
Identity._service_principal_store_instance = ServicePrincipalStore(store)
return Identity._service_principal_store_instance

def login_with_auth_code(self, scopes, claims_challenge=None):
def login_with_auth_code(self, scopes, claims_challenge=None, use_broker_sso=False):
# Emit a warning to inform that a browser is opened.
# Only show the path part of the URL and hide the query string.

Expand All @@ -161,15 +161,30 @@ def _prompt_launching_ui(ui=None, **_):
from .util import read_response_templates
success_template, error_template = read_response_templates()

from .agentic_session import is_agentic_session
is_agentic_session_value = is_agentic_session()
# Broker is available only on Windows for now
broker_sso_available = sys.platform.startswith('win') and self._enable_broker_on_windows
logger.debug("use_broker_sso: %s, is_agentic_session: %s, broker_sso_available: %s",
use_broker_sso, is_agentic_session_value, broker_sso_available)
use_broker_sso = (use_broker_sso or is_agentic_session_value) and broker_sso_available
prompt = 'none' if use_broker_sso else 'select_account'

# For AAD, use port 0 to let the system choose arbitrary unused ephemeral port to avoid port collision
# on port 8400 from the old design. However, ADFS only allows port 8400.
result = self._msal_app.acquire_token_interactive(
scopes, prompt='select_account', port=8400 if self._is_adfs else None,
scopes,
prompt=prompt,
port=8400 if self._is_adfs else None,
success_template=success_template, error_template=error_template,
parent_window_handle=self._msal_app.CONSOLE_WINDOW_HANDLE, on_before_launching_ui=_prompt_launching_ui,
enable_msa_passthrough=True,
claims_challenge=claims_challenge)
return check_result(result)
parsed = check_result(result)
if use_broker_sso:
# log parsed result in debug level
logger.debug("Result from broker SSO login: %s", json.dumps(parsed, indent=4))
return parsed

def login_with_device_code(self, scopes, claims_challenge=None):
flow = self._msal_app.initiate_device_flow(scopes, claims_challenge=claims_challenge)
Expand Down
2 changes: 2 additions & 0 deletions src/azure-cli/azure/cli/command_modules/profile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ def load_arguments(self, command):
c.argument('claims_challenge',
help="Base64-encoded claims challenge requested by a resource API in the "
"WWW-Authenticate header.")
c.argument('use_broker_sso', action='store_true',
help="(Experimental) Enable broker SSO for login.")
c.ignore('_subscription') # hide the global subscription parameter

# Skip subscription discovery
Expand Down
12 changes: 11 additions & 1 deletion src/azure-cli/azure/cli/command_modules/profile/custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def _select_and_set_active(profile, subscriptions):

# pylint: disable=too-many-branches, too-many-locals
def login(cmd, username=None, password=None, tenant=None, scopes=None, allow_no_subscriptions=False,
claims_challenge=None,
claims_challenge=None, use_broker_sso=False,
# Device code flow
use_device_code=False,
# Service principal
Expand Down Expand Up @@ -169,6 +169,15 @@ def login(cmd, username=None, password=None, tenant=None, scopes=None, allow_no_
logger.warning(USERNAME_PASSWORD_DEPRECATION_WARNING_AZURE_CLOUD)
else:
logger.warning(USERNAME_PASSWORD_DEPRECATION_WARNING_OTHER_CLOUD)
# broker_sso incompatible with workload identities
# broker_sso relies on the presence of a broker, which is only available on Windows (for now)
enable_broker_on_windows = cmd.cli_ctx.config.getboolean('core', 'enable_broker_on_windows', fallback=True)
broker_sso_available = sys.platform.startswith('win') and enable_broker_on_windows
if use_broker_sso and not broker_sso_available:
raise CLIError("usage error: '--use-broker-sso' is only supported on Windows with broker enabled")
if use_broker_sso and (service_principal or identity):
raise CLIError("usage error: '--use-broker-sso' is not applicable "
"to service principal or managed identity login")

if claims_challenge:
from azure.cli.core.util import b64decode
Expand Down Expand Up @@ -219,6 +228,7 @@ def login(cmd, username=None, password=None, tenant=None, scopes=None, allow_no_
service_principal,
tenant,
scopes=scopes,
use_broker_sso=use_broker_sso,
use_device_code=use_device_code,
allow_no_subscriptions=allow_no_subscriptions,
use_cert_sn_issuer=use_cert_sn_issuer,
Expand Down
Loading