mirror of
https://github.com/minio/minio.git
synced 2024-12-25 06:35:56 -05:00
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.
This commit is contained in:
parent
cd04600862
commit
e656beb915
@ -516,6 +516,28 @@ func (ies *IAMEtcdStore) loadAll(ctx context.Context, sys *IAMSys) error {
|
|||||||
sys.iamUserPolicyMap[k] = v
|
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.
|
// purge any expired entries which became expired now.
|
||||||
for k, v := range sys.iamUsersMap {
|
for k, v := range sys.iamUsersMap {
|
||||||
if v.IsExpired() {
|
if v.IsExpired() {
|
||||||
|
@ -304,6 +304,7 @@ func (iamOS *IAMObjectStore) loadUser(user string, userType IAMUserType, m map[s
|
|||||||
if u.Credentials.AccessKey == "" {
|
if u.Credentials.AccessKey == "" {
|
||||||
u.Credentials.AccessKey = user
|
u.Credentials.AccessKey = user
|
||||||
}
|
}
|
||||||
|
|
||||||
m[user] = u.Credentials
|
m[user] = u.Credentials
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -474,14 +475,27 @@ func (iamOS *IAMObjectStore) loadAll(ctx context.Context, sys *IAMSys) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// purge any expired entries which became expired now.
|
// purge any expired entries which became expired now.
|
||||||
|
var expiredEntries []string
|
||||||
for k, v := range sys.iamUsersMap {
|
for k, v := range sys.iamUsersMap {
|
||||||
if v.IsExpired() {
|
if v.IsExpired() {
|
||||||
delete(sys.iamUsersMap, k)
|
delete(sys.iamUsersMap, k)
|
||||||
delete(sys.iamUserPolicyMap, k)
|
delete(sys.iamUserPolicyMap, k)
|
||||||
|
expiredEntries = append(expiredEntries, k)
|
||||||
// Deleting on the disk is taken care of in the next cycle
|
// 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 {
|
for k, v := range iamGroupPolicyMap {
|
||||||
sys.iamGroupPolicyMap[k] = v
|
sys.iamGroupPolicyMap[k] = v
|
||||||
}
|
}
|
||||||
|
11
cmd/iam.go
11
cmd/iam.go
@ -26,6 +26,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
humanize "github.com/dustin/go-humanize"
|
||||||
"github.com/minio/minio-go/v7/pkg/set"
|
"github.com/minio/minio-go/v7/pkg/set"
|
||||||
"github.com/minio/minio/cmd/config"
|
"github.com/minio/minio/cmd/config"
|
||||||
"github.com/minio/minio/cmd/logger"
|
"github.com/minio/minio/cmd/logger"
|
||||||
@ -929,7 +930,7 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser string, ses
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return auth.Credentials{}, err
|
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")
|
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
|
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 := make(map[string]interface{})
|
||||||
m[parentClaim] = parentUser
|
m[parentClaim] = parentUser
|
||||||
|
|
||||||
|
@ -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"))
|
writeSTSErrorResponse(ctx, w, true, ErrSTSInvalidParameterValue, fmt.Errorf("Invalid session policy version"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if len(sessionPolicyStr) > 0 {
|
|
||||||
m[iampolicy.SessionPolicyName] = base64.StdEncoding.EncodeToString([]byte(sessionPolicyStr))
|
m[iampolicy.SessionPolicyName] = base64.StdEncoding.EncodeToString([]byte(sessionPolicyStr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user