From b44b2a090cf62519b1e5bf61927808dbe44e87ff Mon Sep 17 00:00:00 2001 From: Ian Roberts Date: Fri, 8 Aug 2025 18:51:23 +0100 Subject: [PATCH] fix: when claim-based OIDC is configured, treat unknown roleArn as claim-based auth (#21512) RoleARN is a required parameter in AssumeRoleWithWebIdentity, according to the standard AWS implementation, and the official AWS SDKs and CLI will not allow you to assume a role from a JWT without also specifying a RoleARN. This meant that it was not possible to use the official SDKs for claim-based OIDC with Minio (minio/minio#21421), since Minio required you to _omit_ the RoleARN in this case. minio/minio#21468 attempted to fix this by disabling the validation of the RoleARN when a claim-based provider was configured, but this had the side effect of making it impossible to have a mixture of claim-based and role-based OIDC providers configured at the same time - every authentication would be treated as claim-based, ignoring the RoleARN entirely. This is an alternative fix, whereby: - _if_ the `RoleARN` is one that Minio knows about, then use the associated role policy - if the `RoleARN` is not recognised, but there is a claim-based provider configured, then ignore the role ARN and attempt authentication with the claim-based provider - if the `RoleARN` is not recognised, and there is _no_ claim-based provider, then return an error. --- cmd/sts-handlers.go | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 6ac8e677b..33873b894 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -414,19 +414,28 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ // // Currently, we do not support multiple claim based IDPs, as there is no // defined parameter to disambiguate the intended IDP in this STS request. - // - // Skip RoleArn existence check when policy mapping is based on a JWT claim. - // This is required to support clients (like the AWS CLI or SDKs) that enforce providing a RoleArn, - // even though it's not used in claim-based identity mode. roleArn := openid.DummyRoleARN roleArnStr := r.Form.Get(stsRoleArn) - if roleArnStr != "" && strings.TrimSpace(iamPolicyClaimNameOpenID()) == "" { + isRolePolicyProvider := roleArnStr != "" + if isRolePolicyProvider { var err error roleArn, _, err = globalIAMSys.GetRolePolicy(roleArnStr) if err != nil { - writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, - fmt.Errorf("Error processing %s parameter: %v", stsRoleArn, err)) - return + // If there is no claim-based provider configured, then an + // unrecognized roleArn is an error + if strings.TrimSpace(iamPolicyClaimNameOpenID()) == "" { + writeSTSErrorResponse(ctx, w, ErrSTSInvalidParameterValue, + fmt.Errorf("Error processing %s parameter: %v", stsRoleArn, err)) + return + } + // If there *is* a claim-based provider configured, then + // treat an unrecognized roleArn the same as no roleArn + // at all. This is to support clients like the AWS SDKs + // or CLI that will not allow an AssumeRoleWithWebIdentity + // call without a RoleARN parameter - for these cases the + // user can supply a dummy ARN, which Minio will ignore. + roleArn = openid.DummyRoleARN + isRolePolicyProvider = false } } @@ -455,7 +464,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ } var policyName string - if roleArnStr != "" && globalIAMSys.HasRolePolicy() && strings.TrimSpace(iamPolicyClaimNameOpenID()) == "" { + if isRolePolicyProvider { // If roleArn is used, we set it as a claim, and use the // associated policy when credentials are used. claims[roleArnClaim] = roleArn.String()