From 69ccbacf306c677b7253e8d7c1b6478996fe7dfd Mon Sep 17 00:00:00 2001 From: Bhagyashreek8 <57988406+Bhagyashreek8@users.noreply.github.com> Date: Thu, 12 Mar 2026 15:34:16 +0530 Subject: [PATCH] s3: IBM COS: provide ibm_iam_endpoint as a configurable param for IBM IAM-based auth --- backend/s3/ibm_signer.go | 11 ++++++----- backend/s3/ibm_signer_test.go | 8 +++++--- backend/s3/provider/IBMCOS.yaml | 1 + backend/s3/providers.go | 3 +++ backend/s3/s3.go | 7 ++++++- 5 files changed, 21 insertions(+), 9 deletions(-) diff --git a/backend/s3/ibm_signer.go b/backend/s3/ibm_signer.go index e1f9d1831..a99a0d802 100644 --- a/backend/s3/ibm_signer.go +++ b/backend/s3/ibm_signer.go @@ -16,11 +16,12 @@ type Authenticator interface { } // IbmIamSigner is a structure for signing requests using IBM IAM. -// Requeres APIKey and Resource InstanceID +// Requires APIKey and Resource InstanceID type IbmIamSigner struct { - APIKey string - InstanceID string - Auth Authenticator + APIKey string + InstanceID string + IAMEndpoint string + Auth Authenticator } // SignHTTP signs requests using IBM IAM token. @@ -29,7 +30,7 @@ func (signer *IbmIamSigner) SignHTTP(ctx context.Context, credentials aws.Creden if signer.Auth != nil { authenticator = signer.Auth } else { - authenticator = &core.IamAuthenticator{ApiKey: signer.APIKey} + authenticator = &core.IamAuthenticator{ApiKey: signer.APIKey, URL: signer.IAMEndpoint} } token, err := authenticator.GetToken() if err != nil { diff --git a/backend/s3/ibm_signer_test.go b/backend/s3/ibm_signer_test.go index bf1f52ff5..bafafc26f 100644 --- a/backend/s3/ibm_signer_test.go +++ b/backend/s3/ibm_signer_test.go @@ -23,14 +23,16 @@ func TestSignHTTP(t *testing.T) { apiKey := "mock-api-key" instanceID := "mock-instance-id" token := "mock-iam-token" + iamEndpoint := "https://iamendpoint.com" mockAuth := &MockAuthenticator{ Token: token, Error: nil, } signer := &IbmIamSigner{ - APIKey: apiKey, - InstanceID: instanceID, - Auth: mockAuth, + APIKey: apiKey, + InstanceID: instanceID, + IAMEndpoint: iamEndpoint, + Auth: mockAuth, } req, err := http.NewRequest("GET", "https://example.com", nil) if err != nil { diff --git a/backend/s3/provider/IBMCOS.yaml b/backend/s3/provider/IBMCOS.yaml index 8b6290fc3..91e0f7d1f 100644 --- a/backend/s3/provider/IBMCOS.yaml +++ b/backend/s3/provider/IBMCOS.yaml @@ -117,6 +117,7 @@ acl: This acl is available on IBM Cloud (Infra) and On-Premise IBM COS. ibm_api_key: true ibm_resource_instance_id: true +ibm_iam_endpoint: true bucket_acl: true quirks: list_version: 1 diff --git a/backend/s3/providers.go b/backend/s3/providers.go index 1a7500ea3..4ff6f7696 100644 --- a/backend/s3/providers.go +++ b/backend/s3/providers.go @@ -52,6 +52,7 @@ type Provider struct { // other IBMApiKey bool `yaml:"ibm_api_key,omitempty"` IBMResourceInstanceID bool `yaml:"ibm_resource_instance_id,omitempty"` + IBMIAMEndpoint bool `yaml:"ibm_iam_endpoint,omitempty"` // advanced BucketACL bool `yaml:"bucket_acl,omitempty"` @@ -224,6 +225,8 @@ func constructProviders(options fs.Options, providerMap map[string]*Provider) st addBool(opt, p, p.IBMApiKey) case "ibm_resource_instance_id": addBool(opt, p, p.IBMResourceInstanceID) + case "ibm_iam_endpoint": + addBool(opt, p, p.IBMIAMEndpoint) case "leave_parts_on_error": addBool(opt, p, p.LeavePartsOnError) case "sts_endpoint": diff --git a/backend/s3/s3.go b/backend/s3/s3.go index 440890f8c..80866f63d 100644 --- a/backend/s3/s3.go +++ b/backend/s3/s3.go @@ -829,6 +829,10 @@ use |-vv| to see the debug level logs. }, { Name: "ibm_resource_instance_id", Help: "IBM service instance id", + }, { + Name: "ibm_iam_endpoint", + Help: "IBM IAM Endpoint to use for authentication.\n\nLeave blank to use the default public endpoint.", + Advanced: true, }, { Name: "object_lock_mode", Help: `Object Lock mode to apply when uploading or copying objects. @@ -1107,6 +1111,7 @@ type Options struct { DirectoryBucket bool `config:"directory_bucket"` IBMAPIKey string `config:"ibm_api_key"` IBMInstanceID string `config:"ibm_resource_instance_id"` + IBMIAMEndpoint string `config:"ibm_iam_endpoint"` UseXID fs.Tristate `config:"use_x_id"` SignAcceptEncoding fs.Tristate `config:"sign_accept_encoding"` ObjectLockMode string `config:"object_lock_mode"` @@ -1541,7 +1546,7 @@ func s3Connection(ctx context.Context, opt *Options, client *http.Client) (s3Cli fs.Debugf(nil, "Using v2 auth") if opt.Provider == "IBMCOS" && opt.IBMAPIKey != "" && opt.IBMInstanceID != "" { options = append(options, func(s3Opt *s3.Options) { - s3Opt.HTTPSignerV4 = &IbmIamSigner{APIKey: opt.IBMAPIKey, InstanceID: opt.IBMInstanceID} + s3Opt.HTTPSignerV4 = &IbmIamSigner{APIKey: opt.IBMAPIKey, InstanceID: opt.IBMInstanceID, IAMEndpoint: opt.IBMIAMEndpoint} }) } else { options = append(options, func(s3Opt *s3.Options) {