Skip to content

Commit ad25c97

Browse files
authored
Support for Trusted profile authentication (#6458)
1 parent 242faba commit ad25c97

File tree

3 files changed

+68
-19
lines changed

3 files changed

+68
-19
lines changed

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module github.com/IBM-Cloud/terraform-provider-ibm
33
go 1.24.2
44

55
require (
6-
github.com/IBM-Cloud/bluemix-go v0.0.0-20250902164610-b399a22591a0
6+
github.com/IBM-Cloud/bluemix-go v0.0.0-20250912140913-e279174fe80b
77
github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113
88
github.com/IBM-Cloud/power-go-client v1.12.0
99
github.com/IBM/appconfiguration-go-admin-sdk v0.5.1
@@ -97,7 +97,7 @@ require (
9797
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
9898
github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 // indirect
9999
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
100-
github.com/go-logr/logr v1.4.2 // indirect
100+
github.com/go-logr/logr v1.4.3 // indirect
101101
github.com/go-logr/stdr v1.2.2 // indirect
102102
github.com/go-openapi/analysis v0.23.0 // indirect
103103
github.com/go-openapi/errors v0.22.1 // indirect
@@ -214,7 +214,7 @@ require (
214214
google.golang.org/appengine v1.6.8 // indirect
215215
google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect
216216
google.golang.org/grpc v1.67.1 // indirect
217-
google.golang.org/protobuf v1.36.6 // indirect
217+
google.golang.org/protobuf v1.36.7 // indirect
218218
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
219219
gopkg.in/inf.v0 v0.9.1 // indirect
220220
gopkg.in/ini.v1 v1.67.0 // indirect

go.sum

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0
9090
github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
9191
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
9292
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
93-
github.com/IBM-Cloud/bluemix-go v0.0.0-20250902164610-b399a22591a0 h1:xwnO+/6u2UcwtB5YPPBs0zuvAgA8/2pYAQ/O3vKaV50=
94-
github.com/IBM-Cloud/bluemix-go v0.0.0-20250902164610-b399a22591a0/go.mod h1:PVD407jrZx0i/TW5GaTRI12ouzUfrFlZshbnjs9aQvg=
93+
github.com/IBM-Cloud/bluemix-go v0.0.0-20250912140913-e279174fe80b h1:KvUKPR6fCkByNcaXf1DWoWDjjqK5zj9f6gzhK1cc4PQ=
94+
github.com/IBM-Cloud/bluemix-go v0.0.0-20250912140913-e279174fe80b/go.mod h1:uqxINL7UuXasMI5Y3yGBh5izcsIksdIGxgQ78oM+5Dk=
9595
github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113 h1:f2Erqfea1dKpaTFagTJM6W/wnD3JGq/Vn9URh8nuRwk=
9696
github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20240725064144-454a2ae23113/go.mod h1:xUQL9SGAjoZFd4GNjrjjtEpjpkgU7RFXRyHesbKTjiY=
9797
github.com/IBM-Cloud/power-go-client v1.12.0 h1:tF9Mq5GLYHebpzQT6IYB89lIxEST1E9teuchjxSAaw0=
@@ -393,8 +393,8 @@ github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTg
393393
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
394394
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
395395
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
396-
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
397-
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
396+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
397+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
398398
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
399399
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
400400
github.com/go-logr/zapr v0.1.0/go.mod h1:tabnROwaDl0UNxkVeFRbY8bwB37GwRv0P8lg6aAiEnk=
@@ -1009,8 +1009,8 @@ github.com/onsi/gomega v1.27.1/go.mod h1:aHX5xOykVYzWOV4WqQy0sy8BQptgukenXpCXfad
10091009
github.com/onsi/gomega v1.27.3/go.mod h1:5vG284IBtfDAmDyrK+eGyZmUgUlmi+Wngqo557cZ6Gw=
10101010
github.com/onsi/gomega v1.27.4/go.mod h1:riYq/GJKh8hhoM01HN6Vmuy93AarCXCBGpvFDK3q3fQ=
10111011
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
1012-
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
1013-
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
1012+
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
1013+
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
10141014
github.com/openshift/api v0.0.0-20210105115604-44119421ec6b/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg=
10151015
github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43 h1:3lcB5nqOOfsJzY4JD12AMKyg3+yQhAdJzNDenbmbMQg=
10161016
github.com/openshift/api v0.0.0-20241216151652-de9de05a8e43/go.mod h1:Shkl4HanLwDiiBzakv+con/aMGnVE2MAGvoKp5oyYUo=
@@ -1274,8 +1274,8 @@ go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
12741274
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
12751275
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
12761276
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
1277-
go.yaml.in/yaml/v3 v3.0.3 h1:bXOww4E/J3f66rav3pX3m8w6jDE4knZjGOw8b5Y6iNE=
1278-
go.yaml.in/yaml/v3 v3.0.3/go.mod h1:tBHosrYAkRZjRAOREWbDnBXUf08JOwYq++0QNwQiWzI=
1277+
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
1278+
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
12791279
golang.org/x/crypto v0.0.0-20180820150726-614d502a4dac/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
12801280
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
12811281
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -1917,8 +1917,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
19171917
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
19181918
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
19191919
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
1920-
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
1921-
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
1920+
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
1921+
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
19221922
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
19231923
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
19241924
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

ibm/conns/config.go

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,7 +1449,7 @@ func (c *Config) ClientSession() (interface{}, error) {
14491449
return session, nil
14501450
}
14511451

1452-
if sess.BluemixSession.Config.BluemixAPIKey != "" {
1452+
if sess.BluemixSession.Config.BluemixAPIKey != "" && c.IAMTrustedProfileID == "" {
14531453
err = authenticateAPIKey(sess.BluemixSession)
14541454
if err != nil {
14551455
for count := c.RetryCount; count >= 0; count-- {
@@ -1469,7 +1469,27 @@ func (c *Config) ClientSession() (interface{}, error) {
14691469
session.functionConfigErr = fmt.Errorf("[ERROR] Error occured while fetching auth key for function: %q", err)
14701470
}
14711471

1472-
if c.IAMTrustedProfileID == "" && sess.BluemixSession.Config.IAMAccessToken != "" && sess.BluemixSession.Config.BluemixAPIKey == "" {
1472+
if sess.BluemixSession.Config.BluemixAPIKey != "" && c.IAMTrustedProfileID != "" {
1473+
err = authenticateAssume(sess.BluemixSession)
1474+
if err != nil {
1475+
for count := c.RetryCount; count >= 0; count-- {
1476+
if err == nil || !isRetryable(err) {
1477+
break
1478+
}
1479+
time.Sleep(c.RetryDelay)
1480+
log.Printf("Retrying IAM Authentication %d", count)
1481+
err = authenticateAssume(sess.BluemixSession)
1482+
}
1483+
if err != nil {
1484+
session.bmxUserFetchErr = fmt.Errorf("[ERROR] Error occured while fetching auth key for account user details: %q", err)
1485+
session.functionConfigErr = fmt.Errorf("[ERROR] Error occured while fetching auth key for function: %q", err)
1486+
}
1487+
}
1488+
1489+
session.functionConfigErr = fmt.Errorf("[ERROR] Error occured while fetching auth key for function: %q", err)
1490+
}
1491+
1492+
if c.IAMTrustedProfileID == "" && sess.BluemixSession.Config.BluemixAPIKey == "" && sess.BluemixSession.Config.IAMAccessToken != "" && sess.BluemixSession.Config.IAMRefreshToken != "" {
14731493
err := RefreshToken(sess.BluemixSession)
14741494
if err != nil {
14751495
for count := c.RetryCount; count >= 0; count-- {
@@ -1627,7 +1647,15 @@ func (c *Config) ClientSession() (interface{}, error) {
16271647

16281648
var authenticator core.Authenticator
16291649

1630-
if c.BluemixAPIKey != "" || sess.BluemixSession.Config.IAMRefreshToken != "" {
1650+
if (c.BluemixAPIKey != "") && c.IAMTrustedProfileID != "" {
1651+
authenticator, err = core.NewIamAssumeAuthenticatorBuilder().
1652+
SetApiKey(c.BluemixAPIKey).
1653+
SetIAMProfileID(c.IAMTrustedProfileID).
1654+
Build()
1655+
if err != nil {
1656+
log.Fatalf("Error in authenticating using NewIamAssumeAuthenticatorBuilder. Error: %s", err)
1657+
}
1658+
} else if c.BluemixAPIKey != "" || sess.BluemixSession.Config.IAMRefreshToken != "" {
16311659
if c.BluemixAPIKey != "" {
16321660
authenticator = &core.IamAuthenticator{
16331661
ApiKey: c.BluemixAPIKey,
@@ -3770,12 +3798,12 @@ func newSession(c *Config) (*Session, error) {
37703798
softlayerSession.AppendUserAgent(fmt.Sprintf("terraform-provider-ibm/%s", version.Version))
37713799
ibmSession.SoftLayerSession = softlayerSession
37723800

3773-
if c.IAMTrustedProfileID == "" && (c.IAMToken != "" && c.IAMRefreshToken == "") || (c.IAMToken == "" && c.IAMRefreshToken != "") {
3801+
/*if c.IAMTrustedProfileID == "" && (c.IAMToken != "" && c.IAMRefreshToken == "") || (c.IAMToken == "" && c.IAMRefreshToken != "") {
37743802
return nil, fmt.Errorf("iam_token and iam_refresh_token must be provided")
37753803
}
37763804
if c.IAMTrustedProfileID != "" && c.IAMToken == "" {
37773805
return nil, fmt.Errorf("iam_token and iam_profile_id must be provided")
3778-
}
3806+
}*/
37793807

37803808
if c.IAMToken != "" {
37813809
log.Println("Configuring IBM Cloud Session with token")
@@ -3818,6 +3846,7 @@ func newSession(c *Config) (*Session, error) {
38183846
PrivateEndpointType: c.PrivateEndpointType,
38193847
EndpointsFile: c.EndpointsFile,
38203848
UserAgent: fmt.Sprintf("terraform-provider-ibm/%s", version.Version),
3849+
IAMTrustedProfileID: c.IAMTrustedProfileID,
38213850
}
38223851
sess, err := bxsession.New(bmxConfig)
38233852
if err != nil {
@@ -3843,6 +3872,20 @@ func authenticateAPIKey(sess *bxsession.Session) error {
38433872
return tokenRefresher.AuthenticateAPIKey(config.BluemixAPIKey)
38443873
}
38453874

3875+
func authenticateAssume(sess *bxsession.Session) error {
3876+
config := sess.Config
3877+
tokenRefresher, err := authentication.NewIAMAuthRepository(config, &rest.Client{
3878+
DefaultHeader: gohttp.Header{
3879+
"User-Agent": []string{http.UserAgent()},
3880+
"X-Original-User-Agent": []string{config.UserAgent},
3881+
},
3882+
})
3883+
if err != nil {
3884+
return err
3885+
}
3886+
return tokenRefresher.AuthenticateAssume(config.BluemixAPIKey, config.IAMTrustedProfileID)
3887+
}
3888+
38463889
func fetchUserDetails(sess *bxsession.Session, retries int, retryDelay time.Duration) (*UserConfig, error) {
38473890
config := sess.Config
38483891
user := UserConfig{}
@@ -3860,11 +3903,17 @@ func fetchUserDetails(sess *bxsession.Session, retries int, retryDelay time.Dura
38603903
// TODO validate with key
38613904
if err != nil && !strings.Contains(err.Error(), "key is of invalid type") {
38623905
if retries > 0 {
3863-
if config.BluemixAPIKey != "" {
3906+
if config.BluemixAPIKey != "" && config.IAMTrustedProfileID == "" {
38643907
time.Sleep(retryDelay)
38653908
log.Printf("Retrying authentication for user details %d", retries)
38663909
_ = authenticateAPIKey(sess)
38673910
return fetchUserDetails(sess, retries-1, retryDelay)
3911+
} else if config.BluemixAPIKey != "" && config.IAMTrustedProfileID != "" {
3912+
time.Sleep(retryDelay)
3913+
log.Printf("Retrying authentication for user details %d", retries)
3914+
_ = authenticateAssume(sess)
3915+
return fetchUserDetails(sess, retries-1, retryDelay)
3916+
38683917
}
38693918
}
38703919
return &user, err

0 commit comments

Comments
 (0)