1919// git config --global --add azureCliCredentialHelper.allowedDomain "dev.azure.com"
2020//
2121// # Set resource overrides for specific URLs (uses git's urlmatch):
22- // git config --global "azureCliCredentialHelper.https://goproxyprod.goms.io.resource" "https://microsoft.onmicrosoft.com/AKSGoProxyMSFT"
23- // # Query with: git config --get-urlmatch azureCliCredentialHelper https://goproxyprod.goms.io
22+ // git config --global "azureCliCredentialHelper.https://yourproxy.yourdomain.resource" "https://microsoft.onmicrosoft.com/AKSGoProxyMSFT"
23+ // # Query with: git config --get-urlmatch azureCliCredentialHelper https://yourproxy.yourdomain
24+ //
25+ // # Set tenant overrides for specific URLs (uses git's urlmatch):
26+ // git config --global "azureCliCredentialHelper.https://yourproxy.yourdomain.tenant" "your-tenant-id-or-name"
27+ // # Query with: git config --get-urlmatch azureCliCredentialHelper https://yourproxy.yourdomain
2428//
2529// # Default allowed domains: visualstudio.com,dev.azure.com
2630package main
5559 gitCfg * gitconfig.Configs
5660 allowedDomains []string
5761 resourceOverrides map [string ]string
62+ tenantOverrides map [string ]string
5863)
5964
6065// Verbose level for debug output
@@ -97,19 +102,33 @@ func loadConfig() {
97102 resourceOverrides [k ] = v
98103 }
99104
105+ // Load tenant overrides
106+ // Keys are in format: azureclicredentialhelper.<url>.tenant
107+ tenantOverrides = make (map [string ]string )
108+
100109 const prefix = "azureclicredentialhelper."
101- const suffix = ".resource"
110+ const resourceSuffix = ".resource"
111+ const tenantSuffix = ".tenant"
102112 for _ , key := range gitCfg .List (prefix ) {
103- if ! strings .HasSuffix (key , suffix ) {
104- continue
105- }
106- // Extract URL/host between prefix and suffix
107- urlPart := strings .TrimPrefix (key , prefix )
108- urlPart = strings .TrimSuffix (urlPart , suffix )
109- if urlPart != "" {
110- if resource := gitCfg .Get (key ); resource != "" {
111- resourceOverrides [urlPart ] = resource
112- debugf (2 , "Loaded resource override: %s -> %s" , urlPart , resource )
113+ if strings .HasSuffix (key , resourceSuffix ) {
114+ // Extract URL/host between prefix and suffix
115+ urlPart := strings .TrimPrefix (key , prefix )
116+ urlPart = strings .TrimSuffix (urlPart , resourceSuffix )
117+ if urlPart != "" {
118+ if resource := gitCfg .Get (key ); resource != "" {
119+ resourceOverrides [urlPart ] = resource
120+ debugf (2 , "Loaded resource override: %s -> %s" , urlPart , resource )
121+ }
122+ }
123+ } else if strings .HasSuffix (key , tenantSuffix ) {
124+ // Extract URL/host between prefix and suffix
125+ urlPart := strings .TrimPrefix (key , prefix )
126+ urlPart = strings .TrimSuffix (urlPart , tenantSuffix )
127+ if urlPart != "" {
128+ if tenant := gitCfg .Get (key ); tenant != "" {
129+ tenantOverrides [urlPart ] = tenant
130+ debugf (2 , "Loaded tenant override: %s -> %s" , urlPart , tenant )
131+ }
113132 }
114133 }
115134 }
@@ -128,17 +147,30 @@ func isAllowedHost(host string, allowedDomains []string) bool {
128147
129148func getResourceForHost (protocol , host string ) string {
130149 url := fmt .Sprintf ("%s://%s" , protocol , host )
131- // Check for URL-based override first (e.g., https://goproxyprod.goms.io )
150+ // Check for URL-based override first (e.g., https://yourproxy.yourdomain )
132151 if resource , ok := resourceOverrides [url ]; ok {
133152 return resource
134153 }
135- // Check for host-only override (e.g., goproxyprod.goms.io )
154+ // Check for host-only override (e.g., yourproxy.yourdomain )
136155 if resource , ok := resourceOverrides [host ]; ok {
137156 return resource
138157 }
139158 return url + "/"
140159}
141160
161+ func getTenantForHost (protocol , host string ) string {
162+ url := fmt .Sprintf ("%s://%s" , protocol , host )
163+ // Check for URL-based override first (e.g., https://yourproxy.yourdomain)
164+ if tenant , ok := tenantOverrides [url ]; ok {
165+ return tenant
166+ }
167+ // Check for host-only override (e.g., yourproxy.yourdomain)
168+ if tenant , ok := tenantOverrides [host ]; ok {
169+ return tenant
170+ }
171+ return ""
172+ }
173+
142174func parseInput () (map [string ]string , []string ) {
143175 data := make (map [string ]string )
144176 var wwwauth []string
@@ -230,9 +262,17 @@ func getCredential(cmd *cobra.Command, args []string) {
230262 return
231263 }
232264
233- // Create Azure CLI credential
265+ // Create Azure CLI credential with optional tenant override
234266 ctx := context .Background ()
235- cred , err := azidentity .NewAzureCLICredential (nil )
267+ tenant := getTenantForHost (protocol , host )
268+ var credOpts * azidentity.AzureCLICredentialOptions
269+ if tenant != "" {
270+ debugf (1 , "Using tenant override: %s" , tenant )
271+ credOpts = & azidentity.AzureCLICredentialOptions {
272+ TenantID : tenant ,
273+ }
274+ }
275+ cred , err := azidentity .NewAzureCLICredential (credOpts )
236276 if err != nil {
237277 debugf (1 , "Failed to create Azure CLI credential: %v" , err )
238278 os .Exit (1 )
0 commit comments