mirror of https://github.com/minio/minio.git
sa: Allow empty policy to indicate parent user's policy is inherited (#9185)
This commit is contained in:
parent
9a951da881
commit
791821d590
|
@ -211,8 +211,9 @@ func getClaimsFromToken(r *http.Request) (map[string]interface{}, error) {
|
|||
// If OPA is not set, session token should
|
||||
// have a policy and its mandatory, reject
|
||||
// requests without policy claim.
|
||||
_, pok := claims.Lookup(iamPolicyClaimName())
|
||||
if !pok {
|
||||
_, pokOpenID := claims.Lookup(iamPolicyClaimNameOpenID())
|
||||
_, pokSA := claims.Lookup(iamPolicyClaimNameSA())
|
||||
if !pokOpenID && !pokSA {
|
||||
return nil, errAuthentication
|
||||
}
|
||||
|
||||
|
|
58
cmd/iam.go
58
cmd/iam.go
|
@ -798,17 +798,18 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser, sessionPol
|
|||
}
|
||||
|
||||
if len(sessionPolicy) > 16*1024 {
|
||||
return auth.Credentials{}, fmt.Errorf("Session policy should not exceed 16*1024 characters")
|
||||
return auth.Credentials{}, fmt.Errorf("Session policy should not exceed 16 KiB characters")
|
||||
}
|
||||
|
||||
policy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicy)))
|
||||
if err != nil {
|
||||
return auth.Credentials{}, err
|
||||
}
|
||||
|
||||
// Version in policy must not be empty
|
||||
if policy.Version == "" {
|
||||
return auth.Credentials{}, fmt.Errorf("Invalid session policy version")
|
||||
if len(sessionPolicy) > 0 {
|
||||
policy, err := iampolicy.ParseConfig(bytes.NewReader([]byte(sessionPolicy)))
|
||||
if err != nil {
|
||||
return auth.Credentials{}, err
|
||||
}
|
||||
// Version in policy must not be empty
|
||||
if policy.Version == "" {
|
||||
return auth.Credentials{}, fmt.Errorf("Invalid session policy version")
|
||||
}
|
||||
}
|
||||
|
||||
sys.Lock()
|
||||
|
@ -836,9 +837,14 @@ func (sys *IAMSys) NewServiceAccount(ctx context.Context, parentUser, sessionPol
|
|||
}
|
||||
|
||||
m := make(map[string]interface{})
|
||||
m[iampolicy.SessionPolicyName] = base64.StdEncoding.EncodeToString([]byte(sessionPolicy))
|
||||
m[parentClaim] = parentUser
|
||||
m[iamPolicyClaimName()] = "embedded-policy"
|
||||
|
||||
if len(sessionPolicy) > 0 {
|
||||
m[iampolicy.SessionPolicyName] = base64.StdEncoding.EncodeToString([]byte(sessionPolicy))
|
||||
m[iamPolicyClaimNameSA()] = "embedded-policy"
|
||||
} else {
|
||||
m[iamPolicyClaimNameSA()] = "inherited-policy"
|
||||
}
|
||||
|
||||
secret := globalActiveCred.SecretKey
|
||||
cred, err := auth.GetNewCredentialsWithMetadata(m, secret)
|
||||
|
@ -1473,6 +1479,11 @@ func (sys *IAMSys) IsAllowedServiceAccount(args iampolicy.Args, parent string) b
|
|||
if parentInClaim != parent {
|
||||
return false
|
||||
}
|
||||
} else {
|
||||
// This is needed so a malicious user cannot
|
||||
// use a leaked session key of another user
|
||||
// to widen its privileges.
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if the parent is allowed to perform this action, reject if not
|
||||
|
@ -1508,12 +1519,27 @@ func (sys *IAMSys) IsAllowedServiceAccount(args iampolicy.Args, parent string) b
|
|||
availablePolicies[i].Statements...)
|
||||
}
|
||||
|
||||
serviceAcc := args.AccountName
|
||||
args.AccountName = parent
|
||||
if !combinedPolicy.IsAllowed(args) {
|
||||
parentArgs := args
|
||||
parentArgs.AccountName = parent
|
||||
if !combinedPolicy.IsAllowed(parentArgs) {
|
||||
return false
|
||||
}
|
||||
args.AccountName = serviceAcc
|
||||
|
||||
saPolicyClaim, ok := args.Claims[iamPolicyClaimNameSA()]
|
||||
if ok {
|
||||
saPolicyClaimStr, ok := saPolicyClaim.(string)
|
||||
if !ok {
|
||||
// Sub policy if set, should be a string reject
|
||||
// malformed/malicious requests.
|
||||
return false
|
||||
}
|
||||
|
||||
if saPolicyClaimStr == "inherited-policy" {
|
||||
// Immediately returns true since at this stage, since
|
||||
// parent user is allowed to do this action.
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Now check if we have a sessionPolicy.
|
||||
spolicy, ok := args.Claims[iampolicy.SessionPolicyName]
|
||||
|
@ -1605,7 +1631,7 @@ func (sys *IAMSys) IsAllowedSTS(args iampolicy.Args) bool {
|
|||
return combinedPolicy.IsAllowed(args)
|
||||
}
|
||||
|
||||
pnameSlice, ok := args.GetPolicies(iamPolicyClaimName())
|
||||
pnameSlice, ok := args.GetPolicies(iamPolicyClaimNameOpenID())
|
||||
if !ok {
|
||||
// When claims are set, it should have a policy claim field.
|
||||
return false
|
||||
|
|
|
@ -215,7 +215,7 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
|
|||
// This policy is the policy associated with the user
|
||||
// requesting for temporary credentials. The temporary
|
||||
// credentials will inherit the same policy requirements.
|
||||
m[iamPolicyClaimName()] = policyName
|
||||
m[iamPolicyClaimNameOpenID()] = policyName
|
||||
|
||||
if len(sessionPolicyStr) > 0 {
|
||||
m[iampolicy.SessionPolicyName] = base64.StdEncoding.EncodeToString([]byte(sessionPolicyStr))
|
||||
|
@ -351,7 +351,7 @@ func (sts *stsAPIHandlers) AssumeRoleWithJWT(w http.ResponseWriter, r *http.Requ
|
|||
// be set and configured on your identity provider as part of
|
||||
// JWT custom claims.
|
||||
var policyName string
|
||||
if v, ok := m[iamPolicyClaimName()]; ok {
|
||||
if v, ok := m[iamPolicyClaimNameOpenID()]; ok {
|
||||
policyName, _ = v.(string)
|
||||
}
|
||||
|
||||
|
|
|
@ -620,10 +620,14 @@ func getMinioMode() string {
|
|||
return mode
|
||||
}
|
||||
|
||||
func iamPolicyClaimName() string {
|
||||
func iamPolicyClaimNameOpenID() string {
|
||||
return globalOpenIDConfig.ClaimPrefix + globalOpenIDConfig.ClaimName
|
||||
}
|
||||
|
||||
func iamPolicyClaimNameSA() string {
|
||||
return "sa-policy"
|
||||
}
|
||||
|
||||
func isWORMEnabled(bucket string) bool {
|
||||
if isMinioMetaBucketName(bucket) {
|
||||
return false
|
||||
|
|
Loading…
Reference in New Issue