Skip to content

Commit 8e8feab

Browse files
committed
MSAL.NET pattern: hardcode LAB_APP_CLIENT_ID in source, remove from YAML
Client ID for RequestMSIDLAB app is not a secret — hardcode it directly in tests/lab_config.py as LAB_APP_CLIENT_ID, matching MSAL.NET's approach (see build/template-install-keyvault-secrets.yaml in that repo). - lab_config.py: add LAB_APP_CLIENT_ID constant, export it, use it in _get_credential() instead of reading from env var - test_e2e.py: import LAB_APP_CLIENT_ID from lab_config, replace all os.getenv/clean_env calls, guard on cert path only - template-pipeline-stages.yml: remove variables block and env entry for LAB_APP_CLIENT_ID — only cert path comes from pipeline
1 parent ae4b5af commit 8e8feab

File tree

3 files changed

+26
-38
lines changed

3 files changed

+26
-38
lines changed

.Pipelines/template-pipeline-stages.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,6 @@ stages:
122122
eq(dependencies.PreBuildCheck.result, 'Succeeded'),
123123
in(dependencies.Validate.result, 'Succeeded', 'Skipped')
124124
)
125-
variables:
126-
# RequestMSIDLAB — the MSID Lab confidential client app used for Key Vault
127-
# access and as a test subject. Matches usage in MSAL.js and MSAL Java pipelines.
128-
# See https://docs.msidlab.com/accounts/confidentialclient.html
129-
LAB_APP_CLIENT_ID: 'f62c5ae3-bf3a-4af5-afa8-a68b800396e9'
130125
jobs:
131126
- job: Test
132127
displayName: 'Run unit tests'
@@ -185,7 +180,6 @@ stages:
185180
pytest -vv --junitxml=test-results/junit.xml 2>&1 | tee test-results/pytest.log
186181
displayName: 'Run tests'
187182
env:
188-
LAB_APP_CLIENT_ID: $(LAB_APP_CLIENT_ID)
189183
LAB_APP_CLIENT_CERT_PFX_PATH: $(LAB_APP_CLIENT_CERT_PFX_PATH)
190184
191185
- task: PublishTestResults@2

tests/lab_config.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
app = get_app_config(AppSecrets.PCA_CLIENT)
2121
2222
Environment Variables:
23-
LAB_APP_CLIENT_ID: Client ID for Key Vault authentication (required)
2423
LAB_APP_CLIENT_CERT_PFX_PATH: Path to .pfx certificate file (required)
2524
"""
2625

@@ -43,6 +42,7 @@
4342
"UserConfig",
4443
"AppConfig",
4544
# Functions
45+
"LAB_APP_CLIENT_ID",
4646
"get_secret",
4747
"get_user_config",
4848
"get_app_config",
@@ -57,6 +57,12 @@
5757
_MSID_LAB_VAULT = "https://msidlabs.vault.azure.net"
5858
_MSAL_TEAM_VAULT = "https://id4skeyvault.vault.azure.net"
5959

60+
# Client ID for the RequestMSIDLAB app used to authenticate against the lab
61+
# Key Vaults. Hardcoded here following the same pattern as MSAL.NET
62+
# (see build/template-install-keyvault-secrets.yaml in that repo).
63+
# See https://docs.msidlab.com/accounts/confidentialclient.html
64+
LAB_APP_CLIENT_ID = "f62c5ae3-bf3a-4af5-afa8-a68b800396e9"
65+
6066
# =============================================================================
6167
# Secret Name Constants
6268
# =============================================================================
@@ -192,19 +198,14 @@ def _get_credential():
192198
Raises:
193199
EnvironmentError: If required environment variables are not set.
194200
"""
195-
client_id = _clean_env("LAB_APP_CLIENT_ID")
196201
cert_path = _clean_env("LAB_APP_CLIENT_CERT_PFX_PATH")
197202
tenant_id = "72f988bf-86f1-41af-91ab-2d7cd011db47" # Microsoft tenant
198-
199-
if not client_id:
200-
raise EnvironmentError(
201-
"LAB_APP_CLIENT_ID environment variable is required for Key Vault access")
202-
203+
203204
if cert_path:
204205
logger.debug("Using certificate credential for Key Vault access")
205206
return CertificateCredential(
206207
tenant_id=tenant_id,
207-
client_id=client_id,
208+
client_id=LAB_APP_CLIENT_ID,
208209
certificate_path=cert_path,
209210
send_certificate_chain=True,
210211
)

tests/test_e2e.py

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
"""If the following ENV VAR were available, many end-to-end test cases would run.
2-
LAB_APP_CLIENT_ID=...
32
LAB_APP_CLIENT_CERT_PFX_PATH=...
43
"""
54
try:
@@ -29,7 +28,7 @@
2928
from tests.broker_util import is_pymsalruntime_installed
3029
from tests.lab_config import (
3130
get_user_config, get_app_config, get_user_password, get_secret,
32-
UserSecrets, AppSecrets,
31+
UserSecrets, AppSecrets, LAB_APP_CLIENT_ID,
3332
)
3433

3534

@@ -348,14 +347,13 @@ def test_access_token_should_be_obtained_for_a_supported_scope(self):
348347
class PublicCloudScenariosTestCase(E2eTestCase):
349348
# Historically this class was driven by tests/config.json for semi-automated runs.
350349
# It now uses lab config + env vars so it can run automatically on any CI
351-
# (including Azure DevOps) as long as LAB_APP_CLIENT_ID and
352-
# LAB_APP_CLIENT_CERT_PFX_PATH are set.
350+
# (including Azure DevOps) as long as LAB_APP_CLIENT_CERT_PFX_PATH is set.
353351

354352
@classmethod
355353
def setUpClass(cls):
356-
if not _clean_env("LAB_APP_CLIENT_ID"):
354+
if not _clean_env("LAB_APP_CLIENT_CERT_PFX_PATH"):
357355
raise unittest.SkipTest(
358-
"LAB_APP_CLIENT_ID not set; skipping PublicCloud e2e tests")
356+
"LAB_APP_CLIENT_CERT_PFX_PATH not set; skipping PublicCloud e2e tests")
359357
pca_app = get_app_config(AppSecrets.PCA_CLIENT)
360358
user = get_user_config(UserSecrets.PUBLIC_CLOUD)
361359
cls.config = {
@@ -436,13 +434,11 @@ def test_client_secret(self):
436434

437435
def test_subject_name_issuer_authentication(self):
438436
from tests.lab_config import get_client_certificate
439-
440-
client_id = os.getenv("LAB_APP_CLIENT_ID")
441-
if not client_id:
442-
self.skipTest("LAB_APP_CLIENT_ID environment variable is required")
437+
if not _clean_env("LAB_APP_CLIENT_CERT_PFX_PATH"):
438+
self.skipTest("LAB_APP_CLIENT_CERT_PFX_PATH not set")
443439

444440
self.app = msal.ConfidentialClientApplication(
445-
client_id,
441+
LAB_APP_CLIENT_ID,
446442
authority="https://login.microsoftonline.com/microsoft.onmicrosoft.com",
447443
client_credential=get_client_certificate(),
448444
http_client=MinimalHttpClient())
@@ -467,23 +463,22 @@ def manual_test_device_flow(self):
467463

468464

469465
def get_lab_app(
470-
env_client_id="LAB_APP_CLIENT_ID",
471466
env_client_cert_path="LAB_APP_CLIENT_CERT_PFX_PATH",
472467
authority="https://login.microsoftonline.com/"
473468
"72f988bf-86f1-41af-91ab-2d7cd011db47", # Microsoft tenant ID
474469
timeout=None,
475470
**kwargs):
476471
"""Returns the lab app as an MSAL confidential client.
477472
478-
Get it from environment variables if defined, otherwise fall back to use MSI.
473+
Uses the hardcoded lab app client ID (RequestMSIDLAB) and a certificate
474+
from the LAB_APP_CLIENT_CERT_PFX_PATH env var.
479475
"""
480476
logger.info(
481-
"Reading ENV variables %s and %s for lab app defined at "
477+
"Reading ENV variable %s for lab app defined at "
482478
"https://docs.msidlab.com/accounts/confidentialclient.html",
483-
env_client_id, env_client_cert_path)
484-
client_id = _clean_env(env_client_id)
479+
env_client_cert_path)
485480
cert_path = _clean_env(env_client_cert_path)
486-
if client_id and cert_path:
481+
if cert_path:
487482
# id came from https://docs.msidlab.com/accounts/confidentialclient.html
488483
client_credential = {
489484
"private_key_pfx_path":
@@ -496,7 +491,7 @@ def get_lab_app(
496491
# See also https://microsoft.sharepoint-df.com/teams/MSIDLABSExtended/SitePages/Programmatically-accessing-LAB-API's.aspx
497492
raise unittest.SkipTest("MSI-based mechanism has not been implemented yet")
498493
return msal.ConfidentialClientApplication(
499-
client_id,
494+
LAB_APP_CLIENT_ID,
500495
client_credential=client_credential,
501496
authority=authority,
502497
http_client=MinimalHttpClient(timeout=timeout),
@@ -1183,15 +1178,13 @@ def _test_acquire_token_for_client(self, configured_region, expected_region):
11831178
import os
11841179
from tests.lab_config import get_client_certificate
11851180

1186-
# Get client ID from environment and certificate from lab_config
1187-
client_id = os.getenv("LAB_APP_CLIENT_ID")
1188-
if not client_id:
1189-
self.skipTest("LAB_APP_CLIENT_ID environment variable is required")
1190-
1181+
# Get client ID from lab_config constant and certificate from lab_config
1182+
if not _clean_env("LAB_APP_CLIENT_CERT_PFX_PATH"):
1183+
self.skipTest("LAB_APP_CLIENT_CERT_PFX_PATH is required")
11911184
client_credential = get_client_certificate()
11921185

11931186
self.app = msal.ConfidentialClientApplication(
1194-
client_id,
1187+
LAB_APP_CLIENT_ID,
11951188
client_credential=client_credential,
11961189
authority="https://login.microsoftonline.com/microsoft.onmicrosoft.com",
11971190
azure_region=configured_region,

0 commit comments

Comments
 (0)