From e656beb915d951fe2a4c4ebc2ddd7acaf50168c7 Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Wed, 5 Aug 2020 13:08:40 -0700 Subject: [PATCH] feat: allow service accounts to be generated with OpenID STS (#10184) Bonus also fix a bug where we did not purge relevant service accounts generated by rotating credentials appropriately, service accounts should become invalid as soon as its corresponding parent user becomes invalid. Since service account themselves carry parent claim always we would never reach this problem, as the access get rejected at IAM policy layer. --- cmd/iam-etcd-store.go | 22 ++++++++++++++++++++++ cmd/iam-object-store.go | 14 ++++++++++++++ cmd/iam.go | 11 ++--------- cmd/sts-handlers.go | 2 -- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/cmd/iam-etcd-store.go b/cmd/iam-etcd-store.go index 3a22a3e1d..4ba91ea68 100644 --- a/cmd/iam-etcd-store.go +++ b/cmd/iam-etcd-store.go @@ -516,6 +516,28 @@ func (ies *IAMEtcdStore) loadAll(ctx context.Context, sys *IAMSys) error { sys.iamUserPolicyMap[k] = v } + // purge any expired entries which became expired now. + var expiredEntries []string + for k, v := range sys.iamUsersMap { + if v.IsExpired() { + delete(sys.iamUsersMap, k) + delete(sys.iamUserPolicyMap, k) + expiredEntries = append(expiredEntries, k) + // Deleting on the disk is taken care of in the next cycle + } + } + + for _, v := range sys.iamUsersMap { + if v.IsServiceAccount() { + for _, accessKey := range expiredEntries { + if v.ParentUser == accessKey { + _ = ies.deleteUserIdentity(v.AccessKey, srvAccUser) + delete(sys.iamUsersMap, v.AccessKey) + } + } + } + } + // purge any expired entries which became expired now. for k, v := range sys.iamUsersMap { if v.IsExpired() { diff --git a/cmd/iam-object-store.go b/cmd/iam-object-store.go index fe0dc7c10..03cb09ef3 100644 --- a/cmd/iam-object-store.go +++ b/cmd/iam-object-store.go @@ -304,6 +304,7 @@ func (iamOS *IAMObjectStore) loadUser(user string, userType IAMUserType, m map[s if u.Credentials.AccessKey == "" { u.Credentials.AccessKey = user } + m[user] = u.Credentials return nil } @@ -474,14 +475,27 @@ func (iamOS *IAMObjectStore) loadAll(ctx context.Context, sys *IAMSys) error { } // purge any expired entries which became expired now. + var expiredEntries []string for k, v := range sys.iamUsersMap { if v.IsExpired() { delete(sys.iamUsersMap, k) delete(sys.iamUserPolicyMap, k) + expiredEntries = append(expiredEntries, k) // Deleting on the disk is taken care of in the next cycle } } + for _, v := range sys.iamUsersMap { + if v.IsServiceAccount() { + for _, accessKey := range expiredEntries { + if v.ParentUser == accessKey { + _ = iamOS.deleteUserIdentity(v.AccessKey, srvAccUser) + delete(sys.iamUsersMap, v.AccessKey) + } + } + } + } + for k, v := range iamGroupPolicyMap { sys.iamGroupPolicyMap[k] = v } diff --git a/cmd/iam.go b/cmd/iam.go index 5ce1b975a..63cd609f9 100644 --- a/cmd/iam.go +++ b/cmd/iam.go @@ -26,6 +26,7 @@ import ( "strings" "time" + humanize "github.com/dustin/go-humanize" "github.com/minio/minio-go/v7/pkg/set" "github.com/minio/minio/cmd/config" "github.com/minio/minio/cmd/logger" @@ -929,7 +930,7 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, ses if err != nil { return auth.Credentials{}, err } - if len(policyBuf) > 16*1024 { + if len(policyBuf) > 16*humanize.KiByte { return auth.Credentials{}, fmt.Errorf("Session policy should not exceed 16 KiB characters") } } @@ -951,14 +952,6 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, ses return auth.Credentials{}, errIAMActionNotAllowed } - // FIXME: Disallow temporary users with no parent, this is most - // probably with OpenID which we don't support to provide - // any parent user, LDAPUsersType and MinIOUsersType are - // currently supported. - if cr.ParentUser == "" && cr.IsTemp() { - return auth.Credentials{}, errIAMActionNotAllowed - } - m := make(map[string]interface{}) m[parentClaim] = parentUser diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 06a5350d4..152536e29 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -355,9 +355,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid session policy version")) return } - } - if len(sessionPolicyStr) > 0 { m[iampolicy.SessionPolicyName] = base64.StdEncoding.EncodeToString([]byte(sessionPolicyStr)) }