@@ -44,6 +44,118 @@ Every publish requires explicitly entering a version and selecting a destination
4444
4545---
4646
47+ ## ESRP App Registration — Add PyPI to the existing MSAL ESRP app (one-time)
48+
49+ > ** Why ESRP?** Microsoft policy requires production OSS package releases to go through ESRP
50+ > (Engineering System Release Pipeline) rather than direct API token uploads. ESRP handles
51+ > authenticated publishing to PyPI on behalf of the team using a managed identity and approved
52+ > Key Vault certificate — no long-lived API tokens are needed.
53+ >
54+ > The MSAL team already has an ESRP app registration (` MSALJavaReleaseBuilds ` ) used for MSAL Java
55+ > (Maven). PyPI must be added to that same app so the pipeline can reuse the same ADO service
56+ > connection (` MSAL-ESRP-AME ` ), Key Vault (` MSALVault ` ), and release signing cert
57+ > (` MSAL-ESRP-Release-Signing ` ).
58+
59+ ### Existing app reference values
60+
61+ | Field | Value |
62+ | -------| -------|
63+ | ** Client Name** | ` MSALJavaReleaseBuilds ` |
64+ | ** Client Id** | ` 8650ce2b-38d4-466a-9144-bc5c19c88112 ` |
65+ | ** Client Id Domain** | AME |
66+ | ** Associated App Id** | ` af541262-ac58-4cdf-9fb9-f7f2e02b2265 ` (AME domain) |
67+ | ** Owners** | ryauld (Ryan Auld), avdunn (Avery Dunn), bogavril (Bogdan Gavril) |
68+
69+ ### Step A1 — Open the ESRP portal and navigate to the Release tab
70+
71+ 1 . Open the ESRP portal and sign in with your AME credentials.
72+ 2 . Find the ** MSALJavaReleaseBuilds** client (Client Id ` 8650ce2b-38d4-466a-9144-bc5c19c88112 ` ).
73+ 3 . Click ** Release** in the tab bar (between Scan and PKI).
74+ - You will see the ** Publishing Details** section with the current Maven configuration.
75+
76+ ### Step A2 — Enable PyPI
77+
78+ 1 . Under ** Content Type** , check ** PyPI** (keep ** Maven** checked — both coexist).
79+ 2 . In the ** Package(s) Name** field, add ` msal ` alongside the existing ` msal4j ` entry.
80+ Enter the value exactly as it appears on PyPI: ` msal `
81+ 3 . Confirm the remaining fields match:
82+
83+ | Field | Value |
84+ | -------| -------|
85+ | ** Workflow** | Releasing OSS to Package Manager Repo ✅ |
86+ | ** Link to ADO Org** | ` https://identitydivision.visualstudio.com/IDDP ` |
87+ | ** Content Type** | Maven ✅ + ** PyPI** ✅ |
88+ | ** Package(s) Name** | ` msal4j ` (Maven), ` msal ` (PyPI) |
89+ | ** Main Publisher** | ` ESRPRELPACMAN ` |
90+ | ** Service Tree ID** | ` 38bfcbed-2abb-4fe1-9eb7-7df98a14bcfb ` |
91+ | ** AAD Subscription ID** | ` 73d86754-e73c-4c3d-8934-f7ca99f5d632 ` |
92+ | ** # Submissions** | 2 per Month |
93+ | ** Files per Submission** | 20 |
94+ | ** Avg File Size** | 2 MBytes |
95+ | ** Avg Submission Size** | 40 MBytes |
96+
97+ 4 . Click ** Save** / ** Update** .
98+
99+ ### Step A3 — Wait for approval
100+
101+ After saving, the ** Release** row under ** Service Status of your Account** will show
102+ ` UpdateInProgress ` . Refresh the page until it shows ` Approved ` before proceeding.
103+
104+ The ** Approval and Verification Status** panel (top-right of the page) shows:
105+ - ** Status:** Approved (once processed)
106+ - ** One Cert Domain Verification Status:** Registered - Pass ✅
107+
108+ > No new Key Vault, cert, or ADO service connection is needed — these are shared with the Java
109+ > app registration.
110+
111+ ### Step A4 — Authorize the MSAL Python pipeline to use ` MSAL-ESRP-AME `
112+
113+ The ` MSAL-ESRP-AME ` ADO service connection lives in the ** IDDP** project. The MSAL Python pipeline
114+ must be authorized to use it:
115+
116+ 1 . In ADO, go to ** IDDP → Project Settings → Service connections → MSAL-ESRP-AME** .
117+ 2 . Click ** Security** (or the ` ⋮ ` menu → ** Security** ).
118+ 3 . Under ** Pipeline permissions** , click ** +** and add the ** MSAL Python · Publish** pipeline
119+ (or grant access to all pipelines if preferred).
120+
121+ ### Step A5 — Update the pipeline YAML
122+
123+ Once the ESRP app registration shows ` Approved ` with PyPI enabled, replace the ` TwineAuthenticate@1 ` +
124+ ` twine upload ` steps in the production Publish stage of ` template-pipeline-stages.yml ` with
125+ ` EsrpRelease@9 ` . The ` folderlocation ` points to where ` DownloadPipelineArtifact@2 ` placed the dist
126+ files — no portal configuration needed for the folder path.
127+
128+ ``` yaml
129+ - task : EsrpRelease@9
130+ displayName : ' Publish to PyPI via ESRP'
131+ inputs :
132+ connectedservicename : ' MSAL-ESRP-AME'
133+ usemanagedidentity : true
134+ keyvaultname : ' MSALVault'
135+ signcertname : ' MSAL-ESRP-Release-Signing'
136+ clientid : ' 8650ce2b-38d4-466a-9144-bc5c19c88112'
137+ intent : ' PackageDistribution'
138+ contenttype : ' PyPi'
139+ contentsource : ' Folder'
140+ folderlocation : ' $(Pipeline.Workspace)/python-dist'
141+ waitforreleasecompletion : true
142+ owners : ' ryauld@microsoft.com;avdunn@microsoft.com'
143+ approvers : ' avdunn@microsoft.com;bogavril@microsoft.com'
144+ serviceendpointurl : ' https://api.esrp.microsoft.com'
145+ mainpublisher : ' ESRPRELPACMAN'
146+ domaintenantid : ' 33e01921-4d64-4f8c-a055-5bdaffd5e33d'
147+ ` ` `
148+
149+ > **Note:** ` contenttype: 'PyPi'` is case-sensitive. Once ESRP is in use for production,
150+ > the `MSAL-Prod-Python-Upload` Twine service connection is no longer needed. The test.pypi.org
151+ > publish stage (preview/RC) can continue using `TwineAuthenticate@1` since ESRP is only required
152+ > for production PyPI releases.
153+
154+ > **Note:** `EsrpRelease@9` requires a **Windows** agent. Update the `PublishPyPI` stage
155+ > `pool: vmImage: ubuntu-latest` to `windows-latest` when switching to ESRP.
156+
157+ ---
158+
47159# # Step 2 — Connect ADO to the GitHub Repository
48160
491611. In your ADO project go to **Project Settings → Service connections → New service connection**.
0 commit comments