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
11 changes: 11 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# Microsoft 365 Agents SDK for Python - Release Notes v1.5.0 (Unreleased)

**Release Date:** Unreleased
**Previous Version:** 1.4.0 (Released 2026-08-18)

## Developer Experience

- **Authentication Configuration Validation**: Added validation for certificate, federated credential, and workload identity authentication settings

---

# Microsoft 365 Agents SDK for Python - Release Notes v1.4.0

**Release Date:** 2026-08-18
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,31 @@ def __init__(
# JWT-patch: always at least include self for backward compat
self._connections = {str(self.CONNECTION_NAME): self}

self._validate()

def _validate(self) -> None:
"""
Validates the configuration. Raises ValueError if any required fields are missing or invalid.
"""
if self.AUTH_TYPE == AuthTypes.certificate and not self.CERT_PFX_FILE:
raise ValueError(
"CERT_PFX_FILE is required for certificate authentication."
)
if (
self.AUTH_TYPE == AuthTypes.federated_credentials
and not self.FEDERATED_CLIENT_ID
):
raise ValueError(
"FEDERATED_CLIENT_ID is required for federated_credentials authentication."
)
if (
self.AUTH_TYPE == AuthTypes.workload_identity
and not self.FEDERATED_TOKEN_FILE
):
raise ValueError(
"FEDERATED_TOKEN_FILE is required for workload_identity authentication."
)

@property
def ISSUERS(self) -> list[str]:
"""
Expand Down
17 changes: 8 additions & 9 deletions tests/authentication_msal/test_msal_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -284,17 +284,16 @@ def test_create_client_application_reads_projected_token(self, mocker, tmp_path)
token_file.write_text("\trefreshed-token\n", encoding="utf-8")
assert client_assertion() == "refreshed-token"

def test_create_client_application_requires_token_file(self):
config = AgentAuthConfiguration(
auth_type=AuthTypes.workload_identity,
tenant_id="12345678-1234-1234-1234-123456789abc",
client_id="test-client-id",
)

def test_configuration_requires_token_file(self):
with pytest.raises(
ValueError, match="FEDERATED_TOKEN_FILE must be set in configuration"
ValueError,
match="FEDERATED_TOKEN_FILE is required for workload_identity authentication",
):
MsalAuth(config)._create_client_application()
AgentAuthConfiguration(
auth_type=AuthTypes.workload_identity,
tenant_id="12345678-1234-1234-1234-123456789abc",
client_id="test-client-id",
)


class TestMsalAuthIdentityProxyManager:
Expand Down
45 changes: 45 additions & 0 deletions tests/hosting_core/test_auth_configuration.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
from os import environ

import pytest

from microsoft_agents.activity import load_configuration_from_env
from microsoft_agents.hosting.core import AgentAuthConfiguration, AuthTypes

Expand Down Expand Up @@ -102,6 +105,48 @@ def test_empty_settings(self):
assert auth_config.SCOPES is None
assert auth_config.AZURE_REGION is None

@pytest.mark.parametrize(
("auth_type", "expected_message"),
[
(
AuthTypes.certificate,
"CERT_PFX_FILE is required for certificate authentication.",
),
(
AuthTypes.federated_credentials,
"FEDERATED_CLIENT_ID is required for "
"federated_credentials authentication.",
),
(
AuthTypes.workload_identity,
"FEDERATED_TOKEN_FILE is required for "
"workload_identity authentication.",
),
],
)
def test_auth_type_requires_credential_setting(self, auth_type, expected_message):
with pytest.raises(ValueError, match=expected_message):
AgentAuthConfiguration(auth_type=auth_type)

@pytest.mark.parametrize(
("auth_type", "credential"),
[
(AuthTypes.certificate, {"cert_pfx_file": "test-cert.pfx"}),
(
AuthTypes.federated_credentials,
{"federated_client_id": "test-federated-client-id"},
),
(
AuthTypes.workload_identity,
{"federated_token_file": "test-token-file"},
),
],
)
def test_auth_type_accepts_required_credential_setting(self, auth_type, credential):
auth_config = AgentAuthConfiguration(auth_type=auth_type, **credential)

assert auth_config.AUTH_TYPE == auth_type

def test_workload_identity_token_file_from_kwargs(self):
auth_config = AgentAuthConfiguration(
AUTHTYPE="WorkloadIdentity",
Expand Down
Loading