@@ -499,6 +499,9 @@ func ConvertConfig(instrument *promoauth.Factory, entries []codersdk.ExternalAut
499
499
if entry .Type == string (codersdk .EnhancedExternalAuthProviderAzureDevops ) {
500
500
oauthConfig = & jwtConfig {oc }
501
501
}
502
+ if entry .Type == string (codersdk .EnhancedExternalAuthProviderAzureDevopsEntra ) {
503
+ oauthConfig = & jwtConfigEntra {oc }
504
+ }
502
505
if entry .Type == string (codersdk .EnhancedExternalAuthProviderJFrog ) {
503
506
oauthConfig = & exchangeWithClientSecret {oc }
504
507
}
@@ -705,6 +708,11 @@ var staticDefaults = map[codersdk.EnhancedExternalAuthProvider]codersdk.External
705
708
Regex : `^(https?://)?dev\.azure\.com(/.*)?$` ,
706
709
Scopes : []string {"vso.code_write" },
707
710
},
711
+ codersdk .EnhancedExternalAuthProviderAzureDevopsEntra : {
712
+ DisplayName : "Azure DevOps (Entra)" ,
713
+ DisplayIcon : "/icon/azure-devops.svg" ,
714
+ Regex : `^(https?://)?dev\.azure\.com(/.*)?$` ,
715
+ },
708
716
codersdk .EnhancedExternalAuthProviderBitBucketCloud : {
709
717
AuthURL : "https://bitbucket.org/site/oauth2/authorize" ,
710
718
TokenURL : "https://bitbucket.org/site/oauth2/access_token" ,
@@ -777,6 +785,25 @@ func (c *jwtConfig) Exchange(ctx context.Context, code string, opts ...oauth2.Au
777
785
)
778
786
}
779
787
788
+ // When authenticating via Entra ID ADO only supports v1 tokens that requires the 'resource' rather than scopes
789
+ type jwtConfigEntra struct {
790
+ * oauth2.Config
791
+ }
792
+
793
+ func (c * jwtConfigEntra ) AuthCodeURL (state string , opts ... oauth2.AuthCodeOption ) string {
794
+ return c .Config .AuthCodeURL (state , append (opts , oauth2 .SetAuthURLParam ("resource" , "499b84ac-1321-427f-aa17-267ca6975798" ))... )
795
+ }
796
+
797
+ func (c * jwtConfigEntra ) Exchange (ctx context.Context , code string , opts ... oauth2.AuthCodeOption ) (* oauth2.Token , error ) {
798
+ return c .Config .Exchange (ctx , code ,
799
+ append (opts ,
800
+ oauth2 .SetAuthURLParam ("client_id" , c .ClientID ),
801
+ oauth2 .SetAuthURLParam ("resource" , "499b84ac-1321-427f-aa17-267ca6975798" ),
802
+ oauth2 .SetAuthURLParam ("client_secret" , c .ClientSecret ),
803
+ )... ,
804
+ )
805
+ }
806
+
780
807
// exchangeWithClientSecret wraps an OAuth config and adds the client secret
781
808
// to the Exchange request as a Bearer header. This is used by JFrog Artifactory.
782
809
type exchangeWithClientSecret struct {
0 commit comments