diff --git a/cmd/bucket-policy.go b/cmd/bucket-policy.go index 1c0402648..f00ec90c8 100644 --- a/cmd/bucket-policy.go +++ b/cmd/bucket-policy.go @@ -68,6 +68,12 @@ func getConditionValues(r *http.Request, lc string, username string, claims map[ principalType := "Anonymous" if username != "" { principalType = "User" + if len(claims) > 0 { + principalType = "AssumedRole" + } + if username == globalActiveCred.AccessKey { + principalType = "Account" + } } vid := r.URL.Query().Get("versionId") @@ -143,6 +149,10 @@ func getConditionValues(r *http.Request, lc string, username string, claims map[ for k, v := range claims { vStr, ok := v.(string) if ok { + // Special case for AD/LDAP STS users + if k == ldapUser { + args[ldapUserPolicyVariable] = []string{vStr} + } args[k] = []string{vStr} } } diff --git a/cmd/server-startup-msg.go b/cmd/server-startup-msg.go index d004dad45..a9849518e 100644 --- a/cmd/server-startup-msg.go +++ b/cmd/server-startup-msg.go @@ -94,13 +94,13 @@ func printStartupSafeModeMessage(apiEndpoints []string, err error) { if color.IsTerminal() && !globalCLIContext.Anonymous { logStartupMessage(color.RedBold("\nCommand-line Access: ") + mcAdminQuickStartGuide) if runtime.GOOS == globalWindowsOSName { - mcMessage := fmt.Sprintf("> mc.exe config host add %s %s %s %s --api s3v4", alias, + mcMessage := fmt.Sprintf("> mc.exe alias set %s %s %s %s --api s3v4", alias, endPoint, cred.AccessKey, cred.SecretKey) logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) mcMessage = "> mc.exe admin config --help" logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) } else { - mcMessage := fmt.Sprintf("$ mc config host add %s %s %s %s --api s3v4", alias, + mcMessage := fmt.Sprintf("$ mc alias set %s %s %s %s --api s3v4", alias, endPoint, cred.AccessKey, cred.SecretKey) logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) mcMessage = "$ mc admin config --help" @@ -233,11 +233,11 @@ func printCLIAccessMsg(endPoint string, alias string) { if color.IsTerminal() && !globalCLIContext.Anonymous { logStartupMessage(color.Blue("\nCommand-line Access: ") + mcQuickStartGuide) if runtime.GOOS == globalWindowsOSName { - mcMessage := fmt.Sprintf("$ mc.exe config host add %s %s %s %s", alias, + mcMessage := fmt.Sprintf("$ mc.exe alias set %s %s %s %s", alias, endPoint, cred.AccessKey, cred.SecretKey) logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) } else { - mcMessage := fmt.Sprintf("$ mc config host add %s %s %s %s", alias, + mcMessage := fmt.Sprintf("$ mc alias set %s %s %s %s", alias, endPoint, cred.AccessKey, cred.SecretKey) logStartupMessage(fmt.Sprintf(getFormatStr(len(mcMessage), 3), mcMessage)) } diff --git a/cmd/sts-handlers.go b/cmd/sts-handlers.go index 152536e29..fcdabaccb 100644 --- a/cmd/sts-handlers.go +++ b/cmd/sts-handlers.go @@ -61,7 +61,8 @@ const ( parentClaim = "parent" // LDAP claim keys - ldapUser = "ldapUser" + ldapUser = "ldapUser" + ldapUserPolicyVariable = "ldap:user" ) // stsAPIHandlers implements and provides http handlers for AWS STS API. diff --git a/docs/gateway/azure.md b/docs/gateway/azure.md index 648ff3455..5a166f1cc 100644 --- a/docs/gateway/azure.md +++ b/docs/gateway/azure.md @@ -27,7 +27,7 @@ MinIO Gateway comes with an embedded web based object browser. Point your web br ### Configure `mc` ``` -mc config host add myazure http://gateway-ip:9000 azureaccountname azureaccountkey +mc alias set myazure http://gateway-ip:9000 azureaccountname azureaccountkey ``` ### List containers on Microsoft Azure diff --git a/docs/gateway/gcs.md b/docs/gateway/gcs.md index 717009d3b..d1ee727ce 100644 --- a/docs/gateway/gcs.md +++ b/docs/gateway/gcs.md @@ -53,7 +53,7 @@ MinIO Client is a command-line tool called `mc` that provides UNIX-like commands Use the following command to configure the gateway: ```sh -mc config host add mygcs http://gateway-ip:9000 minioaccesskey miniosecretkey +mc alias set mygcs http://gateway-ip:9000 minioaccesskey miniosecretkey ``` ### 3.2 List Containers on GCS diff --git a/docs/gateway/hdfs.md b/docs/gateway/hdfs.md index ab1361046..da6e66f45 100644 --- a/docs/gateway/hdfs.md +++ b/docs/gateway/hdfs.md @@ -42,7 +42,7 @@ docker run -p 9000:9000 \ ### Configure `mc` ``` -mc config host add myhdfs http://gateway-ip:9000 access_key secret_key +mc alias set myhdfs http://gateway-ip:9000 access_key secret_key ``` ### List buckets on hdfs diff --git a/docs/gateway/nas.md b/docs/gateway/nas.md index cfb5d5b86..c8a20cb85 100644 --- a/docs/gateway/nas.md +++ b/docs/gateway/nas.md @@ -37,7 +37,7 @@ MinIO Gateway comes with an embedded web based object browser. Point your web br ### Configure `mc` ``` -mc config host add mynas http://gateway-ip:9000 access_key secret_key +mc alias set mynas http://gateway-ip:9000 access_key secret_key ``` ### List buckets on nas diff --git a/docs/multi-user/README.md b/docs/multi-user/README.md index ede20b06d..e46e8db95 100644 --- a/docs/multi-user/README.md +++ b/docs/multi-user/README.md @@ -109,10 +109,135 @@ mc admin group list myminio ### 8. Configure `mc` ``` -mc config host add myminio-newuser http://localhost:9000 newuser newuser123 --api s3v4 +mc alias set myminio-newuser http://localhost:9000 newuser newuser123 --api s3v4 mc cat myminio-newuser/my-bucketname/my-objectname ``` +### Policy Variables +You can use policy variables in the *Resource* element and in string comparisons in the *Condition* element. + +You can use a policy variable in the Resource element, but only in the resource portion of the ARN. This portion of the ARN appears after the 5th colon (:). You can't use a variable to replace parts of the ARN before the 5th colon, such as the service or account. The following policy might be attached to a group. It gives each of the users in the group full programmatic access to a user-specific object (their own "home directory") in MinIO. + +``` +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": ["s3:ListBucket"], + "Effect": "Allow", + "Resource": ["arn:aws:s3:::mybucket"], + "Condition": {"StringLike": {"s3:prefix": ["${aws:username}/*"]}} + }, + { + "Action": [ + "s3:GetObject", + "s3:PutObject" + ], + "Effect": "Allow", + "Resource": ["arn:aws:s3:::mybucket/${aws:username}/*"] + } + ] +} +``` + +If the user is authenticating using an STS credential which was authorized from OpenID connect we allow all `jwt:*` variables specified in the JWT specification, custom `jwt:*` or extensions are not supported. + +List of policy variables for OpenID based STS. +``` +"jwt:sub" +"jwt:iss" +"jwt:aud" +"jwt:jti" +"jwt:upn" +"jwt:name" +"jwt:groups" +"jwt:given_name" +"jwt:family_name" +"jwt:middle_name" +"jwt:nickname" +"jwt:preferred_username" +"jwt:profile" +"jwt:picture" +"jwt:website" +"jwt:email" +"jwt:gender" +"jwt:birthdate" +"jwt:phone_number" +"jwt:address" +"jwt:scope" +"jwt:client_id" +``` + +Following example shows OpenID users with full programmatic access to a OpenID user-specific directory (their own "home directory") in MinIO. +``` +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": ["s3:ListBucket"], + "Effect": "Allow", + "Resource": ["arn:aws:s3:::mybucket"], + "Condition": {"StringLike": {"s3:prefix": ["${jwt:preferred_username}/*"]}} + }, + { + "Action": [ + "s3:GetObject", + "s3:PutObject" + ], + "Effect": "Allow", + "Resource": ["arn:aws:s3:::mybucket/${jwt:preferred_username}/*"] + } + ] +} +``` + +If the user is authenticating using an STS credential which was authorized from AD/LDAP we allow `ldap:*` variables, currently only supports `ldap:user`. Following example shows LDAP users full programmatic access to a LDAP user-specific directory (their own "home directory") in MinIO. +``` +{ + "Version": "2012-10-17", + "Statement": [ + { + "Action": ["s3:ListBucket"], + "Effect": "Allow", + "Resource": ["arn:aws:s3:::mybucket"], + "Condition": {"StringLike": {"s3:prefix": ["${ldap:user}/*"]}} + }, + { + "Action": [ + "s3:GetObject", + "s3:PutObject" + ], + "Effect": "Allow", + "Resource": ["arn:aws:s3:::mybucket/${ldap:user}/*"] + } + ] +} +``` + +#### Common information available in all requests + +- *aws:CurrentTime* - This can be used for conditions that check the date and time. +- *aws:EpochTime* - This is the date in epoch or Unix time, for use with date/time conditions. +- *aws:PrincipalType* - This value indicates whether the principal is an account (Root credential), user (MinIO user), or assumed role (STS) +- *aws:SecureTransport* - This is a Boolean value that represents whether the request was sent over TLS. +- *aws:SourceIp* - This is the requester's IP address, for use with IP address conditions. If running behind Nginx like proxies, MinIO preserve's the source IP. + +``` +{ + "Version": "2012-10-17", + "Statement": { + "Effect": "Allow", + "Action": "s3:ListBucket*", + "Resource": "arn:aws:s3:::mybucket", + "Condition": {"IpAddress": {"aws:SourceIp": "203.0.113.0/24"}} + } +} +``` + +- *aws:UserAgent* - This value is a string that contains information about the requester's client application. This string is generated by the client and can be unreliable. You can only use this context key from `mc` or other MinIO SDKs which standardize the User-Agent string. +- *aws:username* - This is a string containing the friendly name of the current user, this value would point to STS temporary credential in `AssumeRole`ed requests, instead use `jwt:preferred_username` in case of OpenID connect and `ldap:user` in case of AD/LDAP connect. *aws:userid* is an alias to *aws:username* in MinIO. + + ## Explore Further - [MinIO Client Complete Guide](https://docs.min.io/docs/minio-client-complete-guide) - [MinIO STS Quickstart Guide](https://docs.min.io/docs/minio-sts-quickstart-guide) diff --git a/docs/multi-user/admin/README.md b/docs/multi-user/admin/README.md index 6b89aebc0..73fb3331e 100644 --- a/docs/multi-user/admin/README.md +++ b/docs/multi-user/admin/README.md @@ -62,7 +62,7 @@ This admin user will then be allowed to perform create/delete user operations vi ### 3. Configure `mc` and create another user user1 with attached policy user1policy ``` -mc config host add myminio-admin1 http://localhost:9000 admin1 admin123 --api s3v4 +mc alias set myminio-admin1 http://localhost:9000 admin1 admin123 --api s3v4 mc admin user add myminio-admin1 user1 user123 mc admin policy add myminio-admin1 user1policy ~/user1policy.json diff --git a/docs/zh_CN/gateway/azure.md b/docs/zh_CN/gateway/azure.md index 8a53a7422..c31bc8338 100644 --- a/docs/zh_CN/gateway/azure.md +++ b/docs/zh_CN/gateway/azure.md @@ -26,7 +26,7 @@ MinIO Gateway配有嵌入式网络对象浏览器。 将您的Web浏览器指向 ### 配置 `mc` ``` -mc config host add myazure http://gateway-ip:9000 azureaccountname azureaccountkey +mc alias set myazure http://gateway-ip:9000 azureaccountname azureaccountkey ``` ### 列出微软Azure上的容器 diff --git a/docs/zh_CN/gateway/gcs.md b/docs/zh_CN/gateway/gcs.md index a5a81bf3a..cb5782c64 100644 --- a/docs/zh_CN/gateway/gcs.md +++ b/docs/zh_CN/gateway/gcs.md @@ -41,7 +41,7 @@ MinIO Gateway配有嵌入式网络对象浏览器。 将您的Web浏览器指向 ### 配置 `mc` ``` -mc config host add mygcs http://gateway-ip:9000 minioaccesskey miniosecretkey +mc alias set mygcs http://gateway-ip:9000 minioaccesskey miniosecretkey ``` ### 列出GCS上的容器 diff --git a/docs/zh_CN/gateway/nas.md b/docs/zh_CN/gateway/nas.md index 105096d56..879d4af1e 100644 --- a/docs/zh_CN/gateway/nas.md +++ b/docs/zh_CN/gateway/nas.md @@ -26,7 +26,7 @@ minio gateway nas /shared/nasvol ### 设置`mc` ``` -mc config host add mynas http://gateway-ip:9000 access_key secret_key +mc alias set mynas http://gateway-ip:9000 access_key secret_key ``` ### 列举nas上的存储桶 diff --git a/pkg/bucket/policy/condition/key.go b/pkg/bucket/policy/condition/key.go index b6fc6f531..39f8b554c 100644 --- a/pkg/bucket/policy/condition/key.go +++ b/pkg/bucket/policy/condition/key.go @@ -137,6 +137,7 @@ var AllSupportedKeys = append([]Key{ AWSPrincipalType, AWSUserID, AWSUsername, + LDAPUser, // Add new supported condition keys. }, JWTKeys...) @@ -152,6 +153,7 @@ var CommonKeys = append([]Key{ AWSUserID, AWSUsername, S3XAmzContentSha256, + LDAPUser, }, JWTKeys...) func substFuncFromValues(values map[string][]string) func(string) string { @@ -199,6 +201,8 @@ func (key Key) Name() string { return strings.TrimPrefix(keyString, "aws:") } else if strings.HasPrefix(keyString, "jwt:") { return strings.TrimPrefix(keyString, "jwt:") + } else if strings.HasPrefix(keyString, "ldap:") { + return strings.TrimPrefix(keyString, "ldap:") } return strings.TrimPrefix(keyString, "s3:") } diff --git a/pkg/bucket/policy/condition/ldap.go b/pkg/bucket/policy/condition/ldap.go new file mode 100644 index 000000000..d4390e9e2 --- /dev/null +++ b/pkg/bucket/policy/condition/ldap.go @@ -0,0 +1,22 @@ +/* + * MinIO Cloud Storage, (C) 2020 MinIO, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package condition + +const ( + // LDAPUser - LDAP username, in MinIO this value is equal to your authenticating LDAP user. + LDAPUser Key = "ldap:user" +)