From 4f35054d29e1ccdf790f6a9a69cde15352039cf6 Mon Sep 17 00:00:00 2001 From: Aditya Manthramurthy Date: Fri, 3 Dec 2021 13:15:56 -0800 Subject: [PATCH] Ensure that role ARNs don't collide (#13817) This is to prepare for multiple providers enhancement. --- cmd/sts-handlers_test.go | 2 +- internal/arn/arn.go | 6 +++--- internal/config/identity/openid/jwt.go | 20 ++++++++++++++++---- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/cmd/sts-handlers_test.go b/cmd/sts-handlers_test.go index 203b593d3..aa9c562a6 100644 --- a/cmd/sts-handlers_test.go +++ b/cmd/sts-handlers_test.go @@ -855,7 +855,7 @@ func TestIAMWithOpenIDWithRolePolicyServerSuite(t *testing.T) { } const ( - testRoleARN = "arn:minio:iam:::role/127.0.0.1_minio-cl" + testRoleARN = "arn:minio:iam:::role/nOybJqMNzNmroqEKq5D0EUsRZw0" ) func (s *TestSuiteIAM) TestOpenIDSTSWithRolePolicy(c *check) { diff --git a/internal/arn/arn.go b/internal/arn/arn.go index f32cea0c4..daa9bb8c4 100644 --- a/internal/arn/arn.go +++ b/internal/arn/arn.go @@ -59,9 +59,9 @@ type ARN struct { } var ( - // Allows lower-case chars, numbers, '.', '-', '_' and '/'. Starts with - // a letter or digit. At least 1 character long. - validResourceIDRegex = regexp.MustCompile(`^[a-z0-9][a-z0-9_/\.-]*$`) + // Allows english letters, numbers, '.', '-', '_' and '/'. Starts with a + // letter or digit. At least 1 character long. + validResourceIDRegex = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9_/\.-]*$`) ) // NewIAMRoleARN - returns an ARN for a role in MinIO. diff --git a/internal/config/identity/openid/jwt.go b/internal/config/identity/openid/jwt.go index 324a5ec0a..42e343f2f 100644 --- a/internal/config/identity/openid/jwt.go +++ b/internal/config/identity/openid/jwt.go @@ -19,6 +19,8 @@ package openid import ( "crypto" + "crypto/sha1" + "encoding/base64" "encoding/json" "errors" "fmt" @@ -576,11 +578,21 @@ func LookupConfig(kvs config.KVS, transport *http.Transport, closeRespFn func(io return c, config.Errorf("unable to generate a domain from the OpenID config.") } } - clientIDFragment := c.ClientID[:8] - if clientIDFragment == "" { - return c, config.Errorf("unable to get a non-empty clientID fragment from the OpenID config.") + + if c.ClientID == "" { + return c, config.Errorf("client ID must not be empty") + } + + // We set the resource ID of the role arn as a hash of client + // ID, so we can get a short roleARN that stays the same on + // restart. + var resourceID string + { + h := sha1.New() + h.Write([]byte(c.ClientID)) + bs := h.Sum(nil) + resourceID = base64.RawURLEncoding.EncodeToString(bs) } - resourceID := domain + "_" + clientIDFragment c.roleArn, err = arn.NewIAMRoleARN(resourceID, serverRegion) if err != nil { return c, config.Errorf("unable to generate ARN from the OpenID config: %v", err)