diff --git a/cmd/admin-handlers-idp-openid.go b/cmd/admin-handlers-idp-openid.go
new file mode 100644
index 000000000..78e537d48
--- /dev/null
+++ b/cmd/admin-handlers-idp-openid.go
@@ -0,0 +1,246 @@
+// Copyright (c) 2015-2025 MinIO, Inc.
+//
+// This file is part of MinIO Object Storage stack
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package cmd
+
+import (
+ "encoding/json"
+ "errors"
+ "net/http"
+ "sort"
+
+ "github.com/minio/madmin-go/v3"
+ "github.com/minio/minio-go/v7/pkg/set"
+ "github.com/minio/pkg/v3/policy"
+)
+
+const dummyRoleARN = "dummy-internal"
+
+// ListAccessKeysOpenIDBulk - GET /minio/admin/v3/idp/openid/list-access-keys-bulk
+func (a adminAPIHandlers) ListAccessKeysOpenIDBulk(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+
+ // Get current object layer instance.
+ objectAPI := newObjectLayerFn()
+ if objectAPI == nil || globalNotificationSys == nil {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
+ return
+ }
+
+ cred, owner, s3Err := validateAdminSignature(ctx, r, "")
+ if s3Err != ErrNone {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
+ return
+ }
+
+ if !globalIAMSys.OpenIDConfig.Enabled {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminOpenIDNotEnabled), r.URL)
+ return
+ }
+
+ userList := r.Form["users"]
+ isAll := r.Form.Get("all") == "true"
+ selfOnly := !isAll && len(userList) == 0
+ cfgName := r.Form.Get("configName")
+ allConfigs := r.Form.Get("allConfigs") == "true"
+ if cfgName == "" && !allConfigs {
+ cfgName = madmin.Default
+ }
+
+ if isAll && len(userList) > 0 {
+ // This should be checked on client side, so return generic error
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrInvalidRequest), r.URL)
+ return
+ }
+
+ // Empty DN list and not self, list access keys for all users
+ if isAll {
+ if !globalIAMSys.IsAllowed(policy.Args{
+ AccountName: cred.AccessKey,
+ Groups: cred.Groups,
+ Action: policy.ListUsersAdminAction,
+ ConditionValues: getConditionValues(r, "", cred),
+ IsOwner: owner,
+ Claims: cred.Claims,
+ }) {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
+ return
+ }
+ } else if len(userList) == 1 && userList[0] == cred.ParentUser {
+ selfOnly = true
+ }
+
+ if !globalIAMSys.IsAllowed(policy.Args{
+ AccountName: cred.AccessKey,
+ Groups: cred.Groups,
+ Action: policy.ListServiceAccountsAdminAction,
+ ConditionValues: getConditionValues(r, "", cred),
+ IsOwner: owner,
+ Claims: cred.Claims,
+ DenyOnly: selfOnly,
+ }) {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
+ return
+ }
+
+ if selfOnly && len(userList) == 0 {
+ selfDN := cred.AccessKey
+ if cred.ParentUser != "" {
+ selfDN = cred.ParentUser
+ }
+ userList = append(userList, selfDN)
+ }
+
+ listType := r.Form.Get("listType")
+ var listSTSKeys, listServiceAccounts bool
+ switch listType {
+ case madmin.AccessKeyListUsersOnly:
+ listSTSKeys = false
+ listServiceAccounts = false
+ case madmin.AccessKeyListSTSOnly:
+ listSTSKeys = true
+ listServiceAccounts = false
+ case madmin.AccessKeyListSvcaccOnly:
+ listSTSKeys = false
+ listServiceAccounts = true
+ case madmin.AccessKeyListAll:
+ listSTSKeys = true
+ listServiceAccounts = true
+ default:
+ err := errors.New("invalid list type")
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErrWithErr(ErrInvalidRequest, err), r.URL)
+ return
+ }
+
+ s := globalServerConfig.Clone()
+ roleArnMap := make(map[string]string)
+ // Map of configs to a map of users to their access keys
+ cfgToUsersMap := make(map[string]map[string]madmin.OpenIDUserAccessKeys)
+ configs, err := globalIAMSys.OpenIDConfig.GetConfigList(s)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+ for _, config := range configs {
+ if !allConfigs && cfgName != config.Name {
+ continue
+ }
+ arn := dummyRoleARN
+ if config.RoleARN != "" {
+ arn = config.RoleARN
+ }
+ roleArnMap[arn] = config.Name
+ newResp := make(map[string]madmin.OpenIDUserAccessKeys)
+ cfgToUsersMap[config.Name] = newResp
+ }
+ if len(roleArnMap) == 0 {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminNoSuchConfigTarget), r.URL)
+ return
+ }
+
+ userSet := set.CreateStringSet(userList...)
+ accessKeys, err := globalIAMSys.ListAllAccessKeys(ctx)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ for _, accessKey := range accessKeys {
+ // Filter out any disqualifying access keys
+ _, ok := accessKey.Claims[subClaim]
+ if !ok {
+ continue // OpenID access keys must have a sub claim
+ }
+ if (!listSTSKeys && !accessKey.IsServiceAccount()) || (!listServiceAccounts && accessKey.IsServiceAccount()) {
+ continue // skip if not the type we want
+ }
+ arn, ok := accessKey.Claims[roleArnClaim].(string)
+ if !ok {
+ if _, ok := accessKey.Claims[iamPolicyClaimNameOpenID()]; !ok {
+ continue // skip if no roleArn and no policy claim
+ }
+ }
+ matchingCfgName, ok := roleArnMap[arn]
+ if !ok {
+ continue // skip if not part of the target config
+ }
+ var id string
+ if idClaim := globalIAMSys.OpenIDConfig.GetUserIDClaim(matchingCfgName); idClaim != "" {
+ id, _ = accessKey.Claims[idClaim].(string)
+ }
+ if !userSet.IsEmpty() && !userSet.Contains(accessKey.ParentUser) && !userSet.Contains(id) {
+ continue // skip if not in the user list
+ }
+ openIDUserAccessKeys, ok := cfgToUsersMap[matchingCfgName][accessKey.ParentUser]
+
+ // Add new user to map if not already present
+ if !ok {
+ var readableClaim string
+ if rc := globalIAMSys.OpenIDConfig.GetUserReadableClaim(matchingCfgName); rc != "" {
+ readableClaim, _ = accessKey.Claims[rc].(string)
+ }
+ openIDUserAccessKeys = madmin.OpenIDUserAccessKeys{
+ MinioAccessKey: accessKey.ParentUser,
+ ID: id,
+ ReadableName: readableClaim,
+ }
+ }
+ svcAccInfo := madmin.ServiceAccountInfo{
+ AccessKey: accessKey.AccessKey,
+ Expiration: &accessKey.Expiration,
+ }
+ if accessKey.IsServiceAccount() {
+ openIDUserAccessKeys.ServiceAccounts = append(openIDUserAccessKeys.ServiceAccounts, svcAccInfo)
+ } else {
+ openIDUserAccessKeys.STSKeys = append(openIDUserAccessKeys.STSKeys, svcAccInfo)
+ }
+ cfgToUsersMap[matchingCfgName][accessKey.ParentUser] = openIDUserAccessKeys
+ }
+
+ // Convert map to slice and sort
+ resp := make([]madmin.ListAccessKeysOpenIDResp, 0, len(cfgToUsersMap))
+ for cfgName, usersMap := range cfgToUsersMap {
+ users := make([]madmin.OpenIDUserAccessKeys, 0, len(usersMap))
+ for _, user := range usersMap {
+ users = append(users, user)
+ }
+ sort.Slice(users, func(i, j int) bool {
+ return users[i].MinioAccessKey < users[j].MinioAccessKey
+ })
+ resp = append(resp, madmin.ListAccessKeysOpenIDResp{
+ ConfigName: cfgName,
+ Users: users,
+ })
+ }
+ sort.Slice(resp, func(i, j int) bool {
+ return resp[i].ConfigName < resp[j].ConfigName
+ })
+
+ data, err := json.Marshal(resp)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ encryptedData, err := madmin.EncryptData(cred.SecretKey, data)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ writeSuccessResponseJSON(w, encryptedData)
+}
diff --git a/cmd/admin-handlers-users.go b/cmd/admin-handlers-users.go
index 8c0c74422..43f3d36c1 100644
--- a/cmd/admin-handlers-users.go
+++ b/cmd/admin-handlers-users.go
@@ -2068,6 +2068,149 @@ func (a adminAPIHandlers) RevokeTokens(w http.ResponseWriter, r *http.Request) {
writeSuccessNoContent(w)
}
+// InfoAccessKey - GET /minio/admin/v3/info-access-key?access-key=
+func (a adminAPIHandlers) InfoAccessKey(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+
+ // Get current object layer instance.
+ objectAPI := newObjectLayerFn()
+ if objectAPI == nil || globalNotificationSys == nil {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL)
+ return
+ }
+
+ cred, owner, s3Err := validateAdminSignature(ctx, r, "")
+ if s3Err != ErrNone {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL)
+ return
+ }
+
+ accessKey := mux.Vars(r)["accessKey"]
+ if accessKey == "" {
+ accessKey = cred.AccessKey
+ }
+
+ u, ok := globalIAMSys.GetUser(ctx, accessKey)
+ targetCred := u.Credentials
+
+ if !globalIAMSys.IsAllowed(policy.Args{
+ AccountName: cred.AccessKey,
+ Groups: cred.Groups,
+ Action: policy.ListServiceAccountsAdminAction,
+ ConditionValues: getConditionValues(r, "", cred),
+ IsOwner: owner,
+ Claims: cred.Claims,
+ }) {
+ // If requested user does not exist and requestor is not allowed to list service accounts, return access denied.
+ if !ok {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
+ return
+ }
+
+ requestUser := cred.AccessKey
+ if cred.ParentUser != "" {
+ requestUser = cred.ParentUser
+ }
+
+ if requestUser != targetCred.ParentUser {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL)
+ return
+ }
+ }
+
+ if !ok {
+ writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminNoSuchAccessKey), r.URL)
+ return
+ }
+
+ var (
+ sessionPolicy *policy.Policy
+ err error
+ userType string
+ )
+ switch {
+ case targetCred.IsTemp():
+ userType = "STS"
+ _, sessionPolicy, err = globalIAMSys.GetTemporaryAccount(ctx, accessKey)
+ if err == errNoSuchTempAccount {
+ err = errNoSuchAccessKey
+ }
+ case targetCred.IsServiceAccount():
+ userType = "Service Account"
+ _, sessionPolicy, err = globalIAMSys.GetServiceAccount(ctx, accessKey)
+ if err == errNoSuchServiceAccount {
+ err = errNoSuchAccessKey
+ }
+ default:
+ err = errNoSuchAccessKey
+ }
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ // if session policy is nil or empty, then it is implied policy
+ impliedPolicy := sessionPolicy == nil || (sessionPolicy.Version == "" && len(sessionPolicy.Statements) == 0)
+
+ var svcAccountPolicy policy.Policy
+
+ if !impliedPolicy {
+ svcAccountPolicy = *sessionPolicy
+ } else {
+ policiesNames, err := globalIAMSys.PolicyDBGet(targetCred.ParentUser, targetCred.Groups...)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+ svcAccountPolicy = globalIAMSys.GetCombinedPolicy(policiesNames...)
+ }
+
+ policyJSON, err := json.MarshalIndent(svcAccountPolicy, "", " ")
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ var expiration *time.Time
+ if !targetCred.Expiration.IsZero() && !targetCred.Expiration.Equal(timeSentinel) {
+ expiration = &targetCred.Expiration
+ }
+
+ userProvider := guessUserProvider(targetCred)
+
+ infoResp := madmin.InfoAccessKeyResp{
+ AccessKey: accessKey,
+ InfoServiceAccountResp: madmin.InfoServiceAccountResp{
+ ParentUser: targetCred.ParentUser,
+ Name: targetCred.Name,
+ Description: targetCred.Description,
+ AccountStatus: targetCred.Status,
+ ImpliedPolicy: impliedPolicy,
+ Policy: string(policyJSON),
+ Expiration: expiration,
+ },
+
+ UserType: userType,
+ UserProvider: userProvider,
+ }
+
+ populateProviderInfoFromClaims(targetCred.Claims, userProvider, &infoResp)
+
+ data, err := json.Marshal(infoResp)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ encryptedData, err := madmin.EncryptData(cred.SecretKey, data)
+ if err != nil {
+ writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
+ return
+ }
+
+ writeSuccessResponseJSON(w, encryptedData)
+}
+
const (
allPoliciesFile = "policies.json"
allUsersFile = "users.json"
diff --git a/cmd/admin-router.go b/cmd/admin-router.go
index 4e5ac8dba..2527b0615 100644
--- a/cmd/admin-router.go
+++ b/cmd/admin-router.go
@@ -246,6 +246,7 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
// Access key (service account/STS) operations
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/list-access-keys-bulk").HandlerFunc(adminMiddleware(adminAPI.ListAccessKeysBulk)).Queries("listType", "{listType:.*}")
+ adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-access-key").HandlerFunc(adminMiddleware(adminAPI.InfoAccessKey)).Queries("accessKey", "{accessKey:.*}")
// Info policy IAM latest
adminRouter.Methods(http.MethodGet).Path(adminVersion+"/info-canned-policy").HandlerFunc(adminMiddleware(adminAPI.InfoCannedPolicy)).Queries("name", "{name:.*}")
@@ -312,6 +313,11 @@ func registerAdminRouter(router *mux.Router, enableConfigOps bool) {
// LDAP IAM operations
adminRouter.Methods(http.MethodGet).Path(adminVersion + "/idp/ldap/policy-entities").HandlerFunc(adminMiddleware(adminAPI.ListLDAPPolicyMappingEntities))
adminRouter.Methods(http.MethodPost).Path(adminVersion + "/idp/ldap/policy/{operation}").HandlerFunc(adminMiddleware(adminAPI.AttachDetachPolicyLDAP))
+
+ // OpenID specific service accounts ops
+ adminRouter.Methods(http.MethodGet).Path(adminVersion+"/idp/openid/list-access-keys-bulk").
+ HandlerFunc(adminMiddleware(adminAPI.ListAccessKeysOpenIDBulk)).Queries("listType", "{listType:.*}")
+
// -- END IAM APIs --
// GetBucketQuotaConfig
diff --git a/cmd/api-errors.go b/cmd/api-errors.go
index bc108814a..6ccd5fab2 100644
--- a/cmd/api-errors.go
+++ b/cmd/api-errors.go
@@ -215,6 +215,8 @@ const (
ErrExcessData
ErrPolicyInvalidName
ErrNoTokenRevokeType
+ ErrAdminOpenIDNotEnabled
+ ErrAdminNoSuchAccessKey
// Add new error codes here.
// SSE-S3/SSE-KMS related API errors
@@ -568,6 +570,11 @@ var errorCodes = errorCodeMap{
Description: "Policy name may not contain comma",
HTTPStatusCode: http.StatusBadRequest,
},
+ ErrAdminOpenIDNotEnabled: {
+ Code: "OpenIDNotEnabled",
+ Description: "No enabled OpenID Connect identity providers",
+ HTTPStatusCode: http.StatusBadRequest,
+ },
ErrPolicyTooLarge: {
Code: "PolicyTooLarge",
Description: "Policy exceeds the maximum allowed document size.",
@@ -1270,6 +1277,11 @@ var errorCodes = errorCodeMap{
Description: "No token revoke type specified and one could not be inferred from the request",
HTTPStatusCode: http.StatusBadRequest,
},
+ ErrAdminNoSuchAccessKey: {
+ Code: "XMinioAdminNoSuchAccessKey",
+ Description: "The specified access key does not exist.",
+ HTTPStatusCode: http.StatusNotFound,
+ },
// S3 extensions.
ErrContentSHA256Mismatch: {
@@ -2167,6 +2179,8 @@ func toAPIErrorCode(ctx context.Context, err error) (apiErr APIErrorCode) {
apiErr = ErrAdminNoSuchUserLDAPWarn
case errNoSuchServiceAccount:
apiErr = ErrAdminServiceAccountNotFound
+ case errNoSuchAccessKey:
+ apiErr = ErrAdminNoSuchAccessKey
case errNoSuchGroup:
apiErr = ErrAdminNoSuchGroup
case errGroupNotEmpty:
diff --git a/cmd/apierrorcode_string.go b/cmd/apierrorcode_string.go
index 2953a8616..d9973d887 100644
--- a/cmd/apierrorcode_string.go
+++ b/cmd/apierrorcode_string.go
@@ -141,208 +141,210 @@ func _() {
_ = x[ErrExcessData-130]
_ = x[ErrPolicyInvalidName-131]
_ = x[ErrNoTokenRevokeType-132]
- _ = x[ErrInvalidEncryptionMethod-133]
- _ = x[ErrInvalidEncryptionKeyID-134]
- _ = x[ErrInsecureSSECustomerRequest-135]
- _ = x[ErrSSEMultipartEncrypted-136]
- _ = x[ErrSSEEncryptedObject-137]
- _ = x[ErrInvalidEncryptionParameters-138]
- _ = x[ErrInvalidEncryptionParametersSSEC-139]
- _ = x[ErrInvalidSSECustomerAlgorithm-140]
- _ = x[ErrInvalidSSECustomerKey-141]
- _ = x[ErrMissingSSECustomerKey-142]
- _ = x[ErrMissingSSECustomerKeyMD5-143]
- _ = x[ErrSSECustomerKeyMD5Mismatch-144]
- _ = x[ErrInvalidSSECustomerParameters-145]
- _ = x[ErrIncompatibleEncryptionMethod-146]
- _ = x[ErrKMSNotConfigured-147]
- _ = x[ErrKMSKeyNotFoundException-148]
- _ = x[ErrKMSDefaultKeyAlreadyConfigured-149]
- _ = x[ErrNoAccessKey-150]
- _ = x[ErrInvalidToken-151]
- _ = x[ErrEventNotification-152]
- _ = x[ErrARNNotification-153]
- _ = x[ErrRegionNotification-154]
- _ = x[ErrOverlappingFilterNotification-155]
- _ = x[ErrFilterNameInvalid-156]
- _ = x[ErrFilterNamePrefix-157]
- _ = x[ErrFilterNameSuffix-158]
- _ = x[ErrFilterValueInvalid-159]
- _ = x[ErrOverlappingConfigs-160]
- _ = x[ErrUnsupportedNotification-161]
- _ = x[ErrContentSHA256Mismatch-162]
- _ = x[ErrContentChecksumMismatch-163]
- _ = x[ErrStorageFull-164]
- _ = x[ErrRequestBodyParse-165]
- _ = x[ErrObjectExistsAsDirectory-166]
- _ = x[ErrInvalidObjectName-167]
- _ = x[ErrInvalidObjectNamePrefixSlash-168]
- _ = x[ErrInvalidResourceName-169]
- _ = x[ErrInvalidLifecycleQueryParameter-170]
- _ = x[ErrServerNotInitialized-171]
- _ = x[ErrBucketMetadataNotInitialized-172]
- _ = x[ErrRequestTimedout-173]
- _ = x[ErrClientDisconnected-174]
- _ = x[ErrTooManyRequests-175]
- _ = x[ErrInvalidRequest-176]
- _ = x[ErrTransitionStorageClassNotFoundError-177]
- _ = x[ErrInvalidStorageClass-178]
- _ = x[ErrBackendDown-179]
- _ = x[ErrMalformedJSON-180]
- _ = x[ErrAdminNoSuchUser-181]
- _ = x[ErrAdminNoSuchUserLDAPWarn-182]
- _ = x[ErrAdminLDAPExpectedLoginName-183]
- _ = x[ErrAdminNoSuchGroup-184]
- _ = x[ErrAdminGroupNotEmpty-185]
- _ = x[ErrAdminGroupDisabled-186]
- _ = x[ErrAdminInvalidGroupName-187]
- _ = x[ErrAdminNoSuchJob-188]
- _ = x[ErrAdminNoSuchPolicy-189]
- _ = x[ErrAdminPolicyChangeAlreadyApplied-190]
- _ = x[ErrAdminInvalidArgument-191]
- _ = x[ErrAdminInvalidAccessKey-192]
- _ = x[ErrAdminInvalidSecretKey-193]
- _ = x[ErrAdminConfigNoQuorum-194]
- _ = x[ErrAdminConfigTooLarge-195]
- _ = x[ErrAdminConfigBadJSON-196]
- _ = x[ErrAdminNoSuchConfigTarget-197]
- _ = x[ErrAdminConfigEnvOverridden-198]
- _ = x[ErrAdminConfigDuplicateKeys-199]
- _ = x[ErrAdminConfigInvalidIDPType-200]
- _ = x[ErrAdminConfigLDAPNonDefaultConfigName-201]
- _ = x[ErrAdminConfigLDAPValidation-202]
- _ = x[ErrAdminConfigIDPCfgNameAlreadyExists-203]
- _ = x[ErrAdminConfigIDPCfgNameDoesNotExist-204]
- _ = x[ErrInsecureClientRequest-205]
- _ = x[ErrObjectTampered-206]
- _ = x[ErrAdminLDAPNotEnabled-207]
- _ = x[ErrSiteReplicationInvalidRequest-208]
- _ = x[ErrSiteReplicationPeerResp-209]
- _ = x[ErrSiteReplicationBackendIssue-210]
- _ = x[ErrSiteReplicationServiceAccountError-211]
- _ = x[ErrSiteReplicationBucketConfigError-212]
- _ = x[ErrSiteReplicationBucketMetaError-213]
- _ = x[ErrSiteReplicationIAMError-214]
- _ = x[ErrSiteReplicationConfigMissing-215]
- _ = x[ErrSiteReplicationIAMConfigMismatch-216]
- _ = x[ErrAdminRebalanceAlreadyStarted-217]
- _ = x[ErrAdminRebalanceNotStarted-218]
- _ = x[ErrAdminBucketQuotaExceeded-219]
- _ = x[ErrAdminNoSuchQuotaConfiguration-220]
- _ = x[ErrHealNotImplemented-221]
- _ = x[ErrHealNoSuchProcess-222]
- _ = x[ErrHealInvalidClientToken-223]
- _ = x[ErrHealMissingBucket-224]
- _ = x[ErrHealAlreadyRunning-225]
- _ = x[ErrHealOverlappingPaths-226]
- _ = x[ErrIncorrectContinuationToken-227]
- _ = x[ErrEmptyRequestBody-228]
- _ = x[ErrUnsupportedFunction-229]
- _ = x[ErrInvalidExpressionType-230]
- _ = x[ErrBusy-231]
- _ = x[ErrUnauthorizedAccess-232]
- _ = x[ErrExpressionTooLong-233]
- _ = x[ErrIllegalSQLFunctionArgument-234]
- _ = x[ErrInvalidKeyPath-235]
- _ = x[ErrInvalidCompressionFormat-236]
- _ = x[ErrInvalidFileHeaderInfo-237]
- _ = x[ErrInvalidJSONType-238]
- _ = x[ErrInvalidQuoteFields-239]
- _ = x[ErrInvalidRequestParameter-240]
- _ = x[ErrInvalidDataType-241]
- _ = x[ErrInvalidTextEncoding-242]
- _ = x[ErrInvalidDataSource-243]
- _ = x[ErrInvalidTableAlias-244]
- _ = x[ErrMissingRequiredParameter-245]
- _ = x[ErrObjectSerializationConflict-246]
- _ = x[ErrUnsupportedSQLOperation-247]
- _ = x[ErrUnsupportedSQLStructure-248]
- _ = x[ErrUnsupportedSyntax-249]
- _ = x[ErrUnsupportedRangeHeader-250]
- _ = x[ErrLexerInvalidChar-251]
- _ = x[ErrLexerInvalidOperator-252]
- _ = x[ErrLexerInvalidLiteral-253]
- _ = x[ErrLexerInvalidIONLiteral-254]
- _ = x[ErrParseExpectedDatePart-255]
- _ = x[ErrParseExpectedKeyword-256]
- _ = x[ErrParseExpectedTokenType-257]
- _ = x[ErrParseExpected2TokenTypes-258]
- _ = x[ErrParseExpectedNumber-259]
- _ = x[ErrParseExpectedRightParenBuiltinFunctionCall-260]
- _ = x[ErrParseExpectedTypeName-261]
- _ = x[ErrParseExpectedWhenClause-262]
- _ = x[ErrParseUnsupportedToken-263]
- _ = x[ErrParseUnsupportedLiteralsGroupBy-264]
- _ = x[ErrParseExpectedMember-265]
- _ = x[ErrParseUnsupportedSelect-266]
- _ = x[ErrParseUnsupportedCase-267]
- _ = x[ErrParseUnsupportedCaseClause-268]
- _ = x[ErrParseUnsupportedAlias-269]
- _ = x[ErrParseUnsupportedSyntax-270]
- _ = x[ErrParseUnknownOperator-271]
- _ = x[ErrParseMissingIdentAfterAt-272]
- _ = x[ErrParseUnexpectedOperator-273]
- _ = x[ErrParseUnexpectedTerm-274]
- _ = x[ErrParseUnexpectedToken-275]
- _ = x[ErrParseUnexpectedKeyword-276]
- _ = x[ErrParseExpectedExpression-277]
- _ = x[ErrParseExpectedLeftParenAfterCast-278]
- _ = x[ErrParseExpectedLeftParenValueConstructor-279]
- _ = x[ErrParseExpectedLeftParenBuiltinFunctionCall-280]
- _ = x[ErrParseExpectedArgumentDelimiter-281]
- _ = x[ErrParseCastArity-282]
- _ = x[ErrParseInvalidTypeParam-283]
- _ = x[ErrParseEmptySelect-284]
- _ = x[ErrParseSelectMissingFrom-285]
- _ = x[ErrParseExpectedIdentForGroupName-286]
- _ = x[ErrParseExpectedIdentForAlias-287]
- _ = x[ErrParseUnsupportedCallWithStar-288]
- _ = x[ErrParseNonUnaryAggregateFunctionCall-289]
- _ = x[ErrParseMalformedJoin-290]
- _ = x[ErrParseExpectedIdentForAt-291]
- _ = x[ErrParseAsteriskIsNotAloneInSelectList-292]
- _ = x[ErrParseCannotMixSqbAndWildcardInSelectList-293]
- _ = x[ErrParseInvalidContextForWildcardInSelectList-294]
- _ = x[ErrIncorrectSQLFunctionArgumentType-295]
- _ = x[ErrValueParseFailure-296]
- _ = x[ErrEvaluatorInvalidArguments-297]
- _ = x[ErrIntegerOverflow-298]
- _ = x[ErrLikeInvalidInputs-299]
- _ = x[ErrCastFailed-300]
- _ = x[ErrInvalidCast-301]
- _ = x[ErrEvaluatorInvalidTimestampFormatPattern-302]
- _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbolForParsing-303]
- _ = x[ErrEvaluatorTimestampFormatPatternDuplicateFields-304]
- _ = x[ErrEvaluatorTimestampFormatPatternHourClockAmPmMismatch-305]
- _ = x[ErrEvaluatorUnterminatedTimestampFormatPatternToken-306]
- _ = x[ErrEvaluatorInvalidTimestampFormatPatternToken-307]
- _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbol-308]
- _ = x[ErrEvaluatorBindingDoesNotExist-309]
- _ = x[ErrMissingHeaders-310]
- _ = x[ErrInvalidColumnIndex-311]
- _ = x[ErrAdminConfigNotificationTargetsFailed-312]
- _ = x[ErrAdminProfilerNotEnabled-313]
- _ = x[ErrInvalidDecompressedSize-314]
- _ = x[ErrAddUserInvalidArgument-315]
- _ = x[ErrAddUserValidUTF-316]
- _ = x[ErrAdminResourceInvalidArgument-317]
- _ = x[ErrAdminAccountNotEligible-318]
- _ = x[ErrAccountNotEligible-319]
- _ = x[ErrAdminServiceAccountNotFound-320]
- _ = x[ErrPostPolicyConditionInvalidFormat-321]
- _ = x[ErrInvalidChecksum-322]
- _ = x[ErrLambdaARNInvalid-323]
- _ = x[ErrLambdaARNNotFound-324]
- _ = x[ErrInvalidAttributeName-325]
- _ = x[ErrAdminNoAccessKey-326]
- _ = x[ErrAdminNoSecretKey-327]
- _ = x[ErrIAMNotInitialized-328]
- _ = x[apiErrCodeEnd-329]
+ _ = x[ErrAdminOpenIDNotEnabled-133]
+ _ = x[ErrAdminNoSuchAccessKey-134]
+ _ = x[ErrInvalidEncryptionMethod-135]
+ _ = x[ErrInvalidEncryptionKeyID-136]
+ _ = x[ErrInsecureSSECustomerRequest-137]
+ _ = x[ErrSSEMultipartEncrypted-138]
+ _ = x[ErrSSEEncryptedObject-139]
+ _ = x[ErrInvalidEncryptionParameters-140]
+ _ = x[ErrInvalidEncryptionParametersSSEC-141]
+ _ = x[ErrInvalidSSECustomerAlgorithm-142]
+ _ = x[ErrInvalidSSECustomerKey-143]
+ _ = x[ErrMissingSSECustomerKey-144]
+ _ = x[ErrMissingSSECustomerKeyMD5-145]
+ _ = x[ErrSSECustomerKeyMD5Mismatch-146]
+ _ = x[ErrInvalidSSECustomerParameters-147]
+ _ = x[ErrIncompatibleEncryptionMethod-148]
+ _ = x[ErrKMSNotConfigured-149]
+ _ = x[ErrKMSKeyNotFoundException-150]
+ _ = x[ErrKMSDefaultKeyAlreadyConfigured-151]
+ _ = x[ErrNoAccessKey-152]
+ _ = x[ErrInvalidToken-153]
+ _ = x[ErrEventNotification-154]
+ _ = x[ErrARNNotification-155]
+ _ = x[ErrRegionNotification-156]
+ _ = x[ErrOverlappingFilterNotification-157]
+ _ = x[ErrFilterNameInvalid-158]
+ _ = x[ErrFilterNamePrefix-159]
+ _ = x[ErrFilterNameSuffix-160]
+ _ = x[ErrFilterValueInvalid-161]
+ _ = x[ErrOverlappingConfigs-162]
+ _ = x[ErrUnsupportedNotification-163]
+ _ = x[ErrContentSHA256Mismatch-164]
+ _ = x[ErrContentChecksumMismatch-165]
+ _ = x[ErrStorageFull-166]
+ _ = x[ErrRequestBodyParse-167]
+ _ = x[ErrObjectExistsAsDirectory-168]
+ _ = x[ErrInvalidObjectName-169]
+ _ = x[ErrInvalidObjectNamePrefixSlash-170]
+ _ = x[ErrInvalidResourceName-171]
+ _ = x[ErrInvalidLifecycleQueryParameter-172]
+ _ = x[ErrServerNotInitialized-173]
+ _ = x[ErrBucketMetadataNotInitialized-174]
+ _ = x[ErrRequestTimedout-175]
+ _ = x[ErrClientDisconnected-176]
+ _ = x[ErrTooManyRequests-177]
+ _ = x[ErrInvalidRequest-178]
+ _ = x[ErrTransitionStorageClassNotFoundError-179]
+ _ = x[ErrInvalidStorageClass-180]
+ _ = x[ErrBackendDown-181]
+ _ = x[ErrMalformedJSON-182]
+ _ = x[ErrAdminNoSuchUser-183]
+ _ = x[ErrAdminNoSuchUserLDAPWarn-184]
+ _ = x[ErrAdminLDAPExpectedLoginName-185]
+ _ = x[ErrAdminNoSuchGroup-186]
+ _ = x[ErrAdminGroupNotEmpty-187]
+ _ = x[ErrAdminGroupDisabled-188]
+ _ = x[ErrAdminInvalidGroupName-189]
+ _ = x[ErrAdminNoSuchJob-190]
+ _ = x[ErrAdminNoSuchPolicy-191]
+ _ = x[ErrAdminPolicyChangeAlreadyApplied-192]
+ _ = x[ErrAdminInvalidArgument-193]
+ _ = x[ErrAdminInvalidAccessKey-194]
+ _ = x[ErrAdminInvalidSecretKey-195]
+ _ = x[ErrAdminConfigNoQuorum-196]
+ _ = x[ErrAdminConfigTooLarge-197]
+ _ = x[ErrAdminConfigBadJSON-198]
+ _ = x[ErrAdminNoSuchConfigTarget-199]
+ _ = x[ErrAdminConfigEnvOverridden-200]
+ _ = x[ErrAdminConfigDuplicateKeys-201]
+ _ = x[ErrAdminConfigInvalidIDPType-202]
+ _ = x[ErrAdminConfigLDAPNonDefaultConfigName-203]
+ _ = x[ErrAdminConfigLDAPValidation-204]
+ _ = x[ErrAdminConfigIDPCfgNameAlreadyExists-205]
+ _ = x[ErrAdminConfigIDPCfgNameDoesNotExist-206]
+ _ = x[ErrInsecureClientRequest-207]
+ _ = x[ErrObjectTampered-208]
+ _ = x[ErrAdminLDAPNotEnabled-209]
+ _ = x[ErrSiteReplicationInvalidRequest-210]
+ _ = x[ErrSiteReplicationPeerResp-211]
+ _ = x[ErrSiteReplicationBackendIssue-212]
+ _ = x[ErrSiteReplicationServiceAccountError-213]
+ _ = x[ErrSiteReplicationBucketConfigError-214]
+ _ = x[ErrSiteReplicationBucketMetaError-215]
+ _ = x[ErrSiteReplicationIAMError-216]
+ _ = x[ErrSiteReplicationConfigMissing-217]
+ _ = x[ErrSiteReplicationIAMConfigMismatch-218]
+ _ = x[ErrAdminRebalanceAlreadyStarted-219]
+ _ = x[ErrAdminRebalanceNotStarted-220]
+ _ = x[ErrAdminBucketQuotaExceeded-221]
+ _ = x[ErrAdminNoSuchQuotaConfiguration-222]
+ _ = x[ErrHealNotImplemented-223]
+ _ = x[ErrHealNoSuchProcess-224]
+ _ = x[ErrHealInvalidClientToken-225]
+ _ = x[ErrHealMissingBucket-226]
+ _ = x[ErrHealAlreadyRunning-227]
+ _ = x[ErrHealOverlappingPaths-228]
+ _ = x[ErrIncorrectContinuationToken-229]
+ _ = x[ErrEmptyRequestBody-230]
+ _ = x[ErrUnsupportedFunction-231]
+ _ = x[ErrInvalidExpressionType-232]
+ _ = x[ErrBusy-233]
+ _ = x[ErrUnauthorizedAccess-234]
+ _ = x[ErrExpressionTooLong-235]
+ _ = x[ErrIllegalSQLFunctionArgument-236]
+ _ = x[ErrInvalidKeyPath-237]
+ _ = x[ErrInvalidCompressionFormat-238]
+ _ = x[ErrInvalidFileHeaderInfo-239]
+ _ = x[ErrInvalidJSONType-240]
+ _ = x[ErrInvalidQuoteFields-241]
+ _ = x[ErrInvalidRequestParameter-242]
+ _ = x[ErrInvalidDataType-243]
+ _ = x[ErrInvalidTextEncoding-244]
+ _ = x[ErrInvalidDataSource-245]
+ _ = x[ErrInvalidTableAlias-246]
+ _ = x[ErrMissingRequiredParameter-247]
+ _ = x[ErrObjectSerializationConflict-248]
+ _ = x[ErrUnsupportedSQLOperation-249]
+ _ = x[ErrUnsupportedSQLStructure-250]
+ _ = x[ErrUnsupportedSyntax-251]
+ _ = x[ErrUnsupportedRangeHeader-252]
+ _ = x[ErrLexerInvalidChar-253]
+ _ = x[ErrLexerInvalidOperator-254]
+ _ = x[ErrLexerInvalidLiteral-255]
+ _ = x[ErrLexerInvalidIONLiteral-256]
+ _ = x[ErrParseExpectedDatePart-257]
+ _ = x[ErrParseExpectedKeyword-258]
+ _ = x[ErrParseExpectedTokenType-259]
+ _ = x[ErrParseExpected2TokenTypes-260]
+ _ = x[ErrParseExpectedNumber-261]
+ _ = x[ErrParseExpectedRightParenBuiltinFunctionCall-262]
+ _ = x[ErrParseExpectedTypeName-263]
+ _ = x[ErrParseExpectedWhenClause-264]
+ _ = x[ErrParseUnsupportedToken-265]
+ _ = x[ErrParseUnsupportedLiteralsGroupBy-266]
+ _ = x[ErrParseExpectedMember-267]
+ _ = x[ErrParseUnsupportedSelect-268]
+ _ = x[ErrParseUnsupportedCase-269]
+ _ = x[ErrParseUnsupportedCaseClause-270]
+ _ = x[ErrParseUnsupportedAlias-271]
+ _ = x[ErrParseUnsupportedSyntax-272]
+ _ = x[ErrParseUnknownOperator-273]
+ _ = x[ErrParseMissingIdentAfterAt-274]
+ _ = x[ErrParseUnexpectedOperator-275]
+ _ = x[ErrParseUnexpectedTerm-276]
+ _ = x[ErrParseUnexpectedToken-277]
+ _ = x[ErrParseUnexpectedKeyword-278]
+ _ = x[ErrParseExpectedExpression-279]
+ _ = x[ErrParseExpectedLeftParenAfterCast-280]
+ _ = x[ErrParseExpectedLeftParenValueConstructor-281]
+ _ = x[ErrParseExpectedLeftParenBuiltinFunctionCall-282]
+ _ = x[ErrParseExpectedArgumentDelimiter-283]
+ _ = x[ErrParseCastArity-284]
+ _ = x[ErrParseInvalidTypeParam-285]
+ _ = x[ErrParseEmptySelect-286]
+ _ = x[ErrParseSelectMissingFrom-287]
+ _ = x[ErrParseExpectedIdentForGroupName-288]
+ _ = x[ErrParseExpectedIdentForAlias-289]
+ _ = x[ErrParseUnsupportedCallWithStar-290]
+ _ = x[ErrParseNonUnaryAggregateFunctionCall-291]
+ _ = x[ErrParseMalformedJoin-292]
+ _ = x[ErrParseExpectedIdentForAt-293]
+ _ = x[ErrParseAsteriskIsNotAloneInSelectList-294]
+ _ = x[ErrParseCannotMixSqbAndWildcardInSelectList-295]
+ _ = x[ErrParseInvalidContextForWildcardInSelectList-296]
+ _ = x[ErrIncorrectSQLFunctionArgumentType-297]
+ _ = x[ErrValueParseFailure-298]
+ _ = x[ErrEvaluatorInvalidArguments-299]
+ _ = x[ErrIntegerOverflow-300]
+ _ = x[ErrLikeInvalidInputs-301]
+ _ = x[ErrCastFailed-302]
+ _ = x[ErrInvalidCast-303]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPattern-304]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbolForParsing-305]
+ _ = x[ErrEvaluatorTimestampFormatPatternDuplicateFields-306]
+ _ = x[ErrEvaluatorTimestampFormatPatternHourClockAmPmMismatch-307]
+ _ = x[ErrEvaluatorUnterminatedTimestampFormatPatternToken-308]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPatternToken-309]
+ _ = x[ErrEvaluatorInvalidTimestampFormatPatternSymbol-310]
+ _ = x[ErrEvaluatorBindingDoesNotExist-311]
+ _ = x[ErrMissingHeaders-312]
+ _ = x[ErrInvalidColumnIndex-313]
+ _ = x[ErrAdminConfigNotificationTargetsFailed-314]
+ _ = x[ErrAdminProfilerNotEnabled-315]
+ _ = x[ErrInvalidDecompressedSize-316]
+ _ = x[ErrAddUserInvalidArgument-317]
+ _ = x[ErrAddUserValidUTF-318]
+ _ = x[ErrAdminResourceInvalidArgument-319]
+ _ = x[ErrAdminAccountNotEligible-320]
+ _ = x[ErrAccountNotEligible-321]
+ _ = x[ErrAdminServiceAccountNotFound-322]
+ _ = x[ErrPostPolicyConditionInvalidFormat-323]
+ _ = x[ErrInvalidChecksum-324]
+ _ = x[ErrLambdaARNInvalid-325]
+ _ = x[ErrLambdaARNNotFound-326]
+ _ = x[ErrInvalidAttributeName-327]
+ _ = x[ErrAdminNoAccessKey-328]
+ _ = x[ErrAdminNoSecretKey-329]
+ _ = x[ErrIAMNotInitialized-330]
+ _ = x[apiErrCodeEnd-331]
}
-const _APIErrorCode_name = "NoneAccessDeniedBadDigestEntityTooSmallEntityTooLargePolicyTooLargeIncompleteBodyInternalErrorInvalidAccessKeyIDAccessKeyDisabledInvalidArgumentInvalidBucketNameInvalidDigestInvalidRangeInvalidRangePartNumberInvalidCopyPartRangeInvalidCopyPartRangeSourceInvalidMaxKeysInvalidEncodingMethodInvalidMaxUploadsInvalidMaxPartsInvalidPartNumberMarkerInvalidPartNumberInvalidRequestBodyInvalidCopySourceInvalidMetadataDirectiveInvalidCopyDestInvalidPolicyDocumentInvalidObjectStateMalformedXMLMissingContentLengthMissingContentMD5MissingRequestBodyErrorMissingSecurityHeaderNoSuchBucketNoSuchBucketPolicyNoSuchBucketLifecycleNoSuchLifecycleConfigurationInvalidLifecycleWithObjectLockNoSuchBucketSSEConfigNoSuchCORSConfigurationNoSuchWebsiteConfigurationReplicationConfigurationNotFoundErrorRemoteDestinationNotFoundErrorReplicationDestinationMissingLockRemoteTargetNotFoundErrorReplicationRemoteConnectionErrorReplicationBandwidthLimitErrorBucketRemoteIdenticalToSourceBucketRemoteAlreadyExistsBucketRemoteLabelInUseBucketRemoteArnTypeInvalidBucketRemoteArnInvalidBucketRemoteRemoveDisallowedRemoteTargetNotVersionedErrorReplicationSourceNotVersionedErrorReplicationNeedsVersioningErrorReplicationBucketNeedsVersioningErrorReplicationDenyEditErrorRemoteTargetDenyAddErrorReplicationNoExistingObjectsReplicationValidationErrorReplicationPermissionCheckErrorObjectRestoreAlreadyInProgressNoSuchKeyNoSuchUploadInvalidVersionIDNoSuchVersionNotImplementedPreconditionFailedRequestTimeTooSkewedSignatureDoesNotMatchMethodNotAllowedInvalidPartInvalidPartOrderMissingPartAuthorizationHeaderMalformedMalformedPOSTRequestPOSTFileRequiredSignatureVersionNotSupportedBucketNotEmptyAllAccessDisabledPolicyInvalidVersionMissingFieldsMissingCredTagCredMalformedInvalidRegionInvalidServiceS3InvalidServiceSTSInvalidRequestVersionMissingSignTagMissingSignHeadersTagMalformedDateMalformedPresignedDateMalformedCredentialDateMalformedExpiresNegativeExpiresAuthHeaderEmptyExpiredPresignRequestRequestNotReadyYetUnsignedHeadersMissingDateHeaderInvalidQuerySignatureAlgoInvalidQueryParamsBucketAlreadyOwnedByYouInvalidDurationBucketAlreadyExistsMetadataTooLargeUnsupportedMetadataUnsupportedHostHeaderMaximumExpiresSlowDownReadSlowDownWriteMaxVersionsExceededInvalidPrefixMarkerBadRequestKeyTooLongErrorInvalidBucketObjectLockConfigurationObjectLockConfigurationNotFoundObjectLockConfigurationNotAllowedNoSuchObjectLockConfigurationObjectLockedInvalidRetentionDatePastObjectLockRetainDateUnknownWORMModeDirectiveBucketTaggingNotFoundObjectLockInvalidHeadersInvalidTagDirectivePolicyAlreadyAttachedPolicyNotAttachedExcessDataPolicyInvalidNameNoTokenRevokeTypeInvalidEncryptionMethodInvalidEncryptionKeyIDInsecureSSECustomerRequestSSEMultipartEncryptedSSEEncryptedObjectInvalidEncryptionParametersInvalidEncryptionParametersSSECInvalidSSECustomerAlgorithmInvalidSSECustomerKeyMissingSSECustomerKeyMissingSSECustomerKeyMD5SSECustomerKeyMD5MismatchInvalidSSECustomerParametersIncompatibleEncryptionMethodKMSNotConfiguredKMSKeyNotFoundExceptionKMSDefaultKeyAlreadyConfiguredNoAccessKeyInvalidTokenEventNotificationARNNotificationRegionNotificationOverlappingFilterNotificationFilterNameInvalidFilterNamePrefixFilterNameSuffixFilterValueInvalidOverlappingConfigsUnsupportedNotificationContentSHA256MismatchContentChecksumMismatchStorageFullRequestBodyParseObjectExistsAsDirectoryInvalidObjectNameInvalidObjectNamePrefixSlashInvalidResourceNameInvalidLifecycleQueryParameterServerNotInitializedBucketMetadataNotInitializedRequestTimedoutClientDisconnectedTooManyRequestsInvalidRequestTransitionStorageClassNotFoundErrorInvalidStorageClassBackendDownMalformedJSONAdminNoSuchUserAdminNoSuchUserLDAPWarnAdminLDAPExpectedLoginNameAdminNoSuchGroupAdminGroupNotEmptyAdminGroupDisabledAdminInvalidGroupNameAdminNoSuchJobAdminNoSuchPolicyAdminPolicyChangeAlreadyAppliedAdminInvalidArgumentAdminInvalidAccessKeyAdminInvalidSecretKeyAdminConfigNoQuorumAdminConfigTooLargeAdminConfigBadJSONAdminNoSuchConfigTargetAdminConfigEnvOverriddenAdminConfigDuplicateKeysAdminConfigInvalidIDPTypeAdminConfigLDAPNonDefaultConfigNameAdminConfigLDAPValidationAdminConfigIDPCfgNameAlreadyExistsAdminConfigIDPCfgNameDoesNotExistInsecureClientRequestObjectTamperedAdminLDAPNotEnabledSiteReplicationInvalidRequestSiteReplicationPeerRespSiteReplicationBackendIssueSiteReplicationServiceAccountErrorSiteReplicationBucketConfigErrorSiteReplicationBucketMetaErrorSiteReplicationIAMErrorSiteReplicationConfigMissingSiteReplicationIAMConfigMismatchAdminRebalanceAlreadyStartedAdminRebalanceNotStartedAdminBucketQuotaExceededAdminNoSuchQuotaConfigurationHealNotImplementedHealNoSuchProcessHealInvalidClientTokenHealMissingBucketHealAlreadyRunningHealOverlappingPathsIncorrectContinuationTokenEmptyRequestBodyUnsupportedFunctionInvalidExpressionTypeBusyUnauthorizedAccessExpressionTooLongIllegalSQLFunctionArgumentInvalidKeyPathInvalidCompressionFormatInvalidFileHeaderInfoInvalidJSONTypeInvalidQuoteFieldsInvalidRequestParameterInvalidDataTypeInvalidTextEncodingInvalidDataSourceInvalidTableAliasMissingRequiredParameterObjectSerializationConflictUnsupportedSQLOperationUnsupportedSQLStructureUnsupportedSyntaxUnsupportedRangeHeaderLexerInvalidCharLexerInvalidOperatorLexerInvalidLiteralLexerInvalidIONLiteralParseExpectedDatePartParseExpectedKeywordParseExpectedTokenTypeParseExpected2TokenTypesParseExpectedNumberParseExpectedRightParenBuiltinFunctionCallParseExpectedTypeNameParseExpectedWhenClauseParseUnsupportedTokenParseUnsupportedLiteralsGroupByParseExpectedMemberParseUnsupportedSelectParseUnsupportedCaseParseUnsupportedCaseClauseParseUnsupportedAliasParseUnsupportedSyntaxParseUnknownOperatorParseMissingIdentAfterAtParseUnexpectedOperatorParseUnexpectedTermParseUnexpectedTokenParseUnexpectedKeywordParseExpectedExpressionParseExpectedLeftParenAfterCastParseExpectedLeftParenValueConstructorParseExpectedLeftParenBuiltinFunctionCallParseExpectedArgumentDelimiterParseCastArityParseInvalidTypeParamParseEmptySelectParseSelectMissingFromParseExpectedIdentForGroupNameParseExpectedIdentForAliasParseUnsupportedCallWithStarParseNonUnaryAggregateFunctionCallParseMalformedJoinParseExpectedIdentForAtParseAsteriskIsNotAloneInSelectListParseCannotMixSqbAndWildcardInSelectListParseInvalidContextForWildcardInSelectListIncorrectSQLFunctionArgumentTypeValueParseFailureEvaluatorInvalidArgumentsIntegerOverflowLikeInvalidInputsCastFailedInvalidCastEvaluatorInvalidTimestampFormatPatternEvaluatorInvalidTimestampFormatPatternSymbolForParsingEvaluatorTimestampFormatPatternDuplicateFieldsEvaluatorTimestampFormatPatternHourClockAmPmMismatchEvaluatorUnterminatedTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternSymbolEvaluatorBindingDoesNotExistMissingHeadersInvalidColumnIndexAdminConfigNotificationTargetsFailedAdminProfilerNotEnabledInvalidDecompressedSizeAddUserInvalidArgumentAddUserValidUTFAdminResourceInvalidArgumentAdminAccountNotEligibleAccountNotEligibleAdminServiceAccountNotFoundPostPolicyConditionInvalidFormatInvalidChecksumLambdaARNInvalidLambdaARNNotFoundInvalidAttributeNameAdminNoAccessKeyAdminNoSecretKeyIAMNotInitializedapiErrCodeEnd"
+const _APIErrorCode_name = "NoneAccessDeniedBadDigestEntityTooSmallEntityTooLargePolicyTooLargeIncompleteBodyInternalErrorInvalidAccessKeyIDAccessKeyDisabledInvalidArgumentInvalidBucketNameInvalidDigestInvalidRangeInvalidRangePartNumberInvalidCopyPartRangeInvalidCopyPartRangeSourceInvalidMaxKeysInvalidEncodingMethodInvalidMaxUploadsInvalidMaxPartsInvalidPartNumberMarkerInvalidPartNumberInvalidRequestBodyInvalidCopySourceInvalidMetadataDirectiveInvalidCopyDestInvalidPolicyDocumentInvalidObjectStateMalformedXMLMissingContentLengthMissingContentMD5MissingRequestBodyErrorMissingSecurityHeaderNoSuchBucketNoSuchBucketPolicyNoSuchBucketLifecycleNoSuchLifecycleConfigurationInvalidLifecycleWithObjectLockNoSuchBucketSSEConfigNoSuchCORSConfigurationNoSuchWebsiteConfigurationReplicationConfigurationNotFoundErrorRemoteDestinationNotFoundErrorReplicationDestinationMissingLockRemoteTargetNotFoundErrorReplicationRemoteConnectionErrorReplicationBandwidthLimitErrorBucketRemoteIdenticalToSourceBucketRemoteAlreadyExistsBucketRemoteLabelInUseBucketRemoteArnTypeInvalidBucketRemoteArnInvalidBucketRemoteRemoveDisallowedRemoteTargetNotVersionedErrorReplicationSourceNotVersionedErrorReplicationNeedsVersioningErrorReplicationBucketNeedsVersioningErrorReplicationDenyEditErrorRemoteTargetDenyAddErrorReplicationNoExistingObjectsReplicationValidationErrorReplicationPermissionCheckErrorObjectRestoreAlreadyInProgressNoSuchKeyNoSuchUploadInvalidVersionIDNoSuchVersionNotImplementedPreconditionFailedRequestTimeTooSkewedSignatureDoesNotMatchMethodNotAllowedInvalidPartInvalidPartOrderMissingPartAuthorizationHeaderMalformedMalformedPOSTRequestPOSTFileRequiredSignatureVersionNotSupportedBucketNotEmptyAllAccessDisabledPolicyInvalidVersionMissingFieldsMissingCredTagCredMalformedInvalidRegionInvalidServiceS3InvalidServiceSTSInvalidRequestVersionMissingSignTagMissingSignHeadersTagMalformedDateMalformedPresignedDateMalformedCredentialDateMalformedExpiresNegativeExpiresAuthHeaderEmptyExpiredPresignRequestRequestNotReadyYetUnsignedHeadersMissingDateHeaderInvalidQuerySignatureAlgoInvalidQueryParamsBucketAlreadyOwnedByYouInvalidDurationBucketAlreadyExistsMetadataTooLargeUnsupportedMetadataUnsupportedHostHeaderMaximumExpiresSlowDownReadSlowDownWriteMaxVersionsExceededInvalidPrefixMarkerBadRequestKeyTooLongErrorInvalidBucketObjectLockConfigurationObjectLockConfigurationNotFoundObjectLockConfigurationNotAllowedNoSuchObjectLockConfigurationObjectLockedInvalidRetentionDatePastObjectLockRetainDateUnknownWORMModeDirectiveBucketTaggingNotFoundObjectLockInvalidHeadersInvalidTagDirectivePolicyAlreadyAttachedPolicyNotAttachedExcessDataPolicyInvalidNameNoTokenRevokeTypeAdminOpenIDNotEnabledAdminNoSuchAccessKeyInvalidEncryptionMethodInvalidEncryptionKeyIDInsecureSSECustomerRequestSSEMultipartEncryptedSSEEncryptedObjectInvalidEncryptionParametersInvalidEncryptionParametersSSECInvalidSSECustomerAlgorithmInvalidSSECustomerKeyMissingSSECustomerKeyMissingSSECustomerKeyMD5SSECustomerKeyMD5MismatchInvalidSSECustomerParametersIncompatibleEncryptionMethodKMSNotConfiguredKMSKeyNotFoundExceptionKMSDefaultKeyAlreadyConfiguredNoAccessKeyInvalidTokenEventNotificationARNNotificationRegionNotificationOverlappingFilterNotificationFilterNameInvalidFilterNamePrefixFilterNameSuffixFilterValueInvalidOverlappingConfigsUnsupportedNotificationContentSHA256MismatchContentChecksumMismatchStorageFullRequestBodyParseObjectExistsAsDirectoryInvalidObjectNameInvalidObjectNamePrefixSlashInvalidResourceNameInvalidLifecycleQueryParameterServerNotInitializedBucketMetadataNotInitializedRequestTimedoutClientDisconnectedTooManyRequestsInvalidRequestTransitionStorageClassNotFoundErrorInvalidStorageClassBackendDownMalformedJSONAdminNoSuchUserAdminNoSuchUserLDAPWarnAdminLDAPExpectedLoginNameAdminNoSuchGroupAdminGroupNotEmptyAdminGroupDisabledAdminInvalidGroupNameAdminNoSuchJobAdminNoSuchPolicyAdminPolicyChangeAlreadyAppliedAdminInvalidArgumentAdminInvalidAccessKeyAdminInvalidSecretKeyAdminConfigNoQuorumAdminConfigTooLargeAdminConfigBadJSONAdminNoSuchConfigTargetAdminConfigEnvOverriddenAdminConfigDuplicateKeysAdminConfigInvalidIDPTypeAdminConfigLDAPNonDefaultConfigNameAdminConfigLDAPValidationAdminConfigIDPCfgNameAlreadyExistsAdminConfigIDPCfgNameDoesNotExistInsecureClientRequestObjectTamperedAdminLDAPNotEnabledSiteReplicationInvalidRequestSiteReplicationPeerRespSiteReplicationBackendIssueSiteReplicationServiceAccountErrorSiteReplicationBucketConfigErrorSiteReplicationBucketMetaErrorSiteReplicationIAMErrorSiteReplicationConfigMissingSiteReplicationIAMConfigMismatchAdminRebalanceAlreadyStartedAdminRebalanceNotStartedAdminBucketQuotaExceededAdminNoSuchQuotaConfigurationHealNotImplementedHealNoSuchProcessHealInvalidClientTokenHealMissingBucketHealAlreadyRunningHealOverlappingPathsIncorrectContinuationTokenEmptyRequestBodyUnsupportedFunctionInvalidExpressionTypeBusyUnauthorizedAccessExpressionTooLongIllegalSQLFunctionArgumentInvalidKeyPathInvalidCompressionFormatInvalidFileHeaderInfoInvalidJSONTypeInvalidQuoteFieldsInvalidRequestParameterInvalidDataTypeInvalidTextEncodingInvalidDataSourceInvalidTableAliasMissingRequiredParameterObjectSerializationConflictUnsupportedSQLOperationUnsupportedSQLStructureUnsupportedSyntaxUnsupportedRangeHeaderLexerInvalidCharLexerInvalidOperatorLexerInvalidLiteralLexerInvalidIONLiteralParseExpectedDatePartParseExpectedKeywordParseExpectedTokenTypeParseExpected2TokenTypesParseExpectedNumberParseExpectedRightParenBuiltinFunctionCallParseExpectedTypeNameParseExpectedWhenClauseParseUnsupportedTokenParseUnsupportedLiteralsGroupByParseExpectedMemberParseUnsupportedSelectParseUnsupportedCaseParseUnsupportedCaseClauseParseUnsupportedAliasParseUnsupportedSyntaxParseUnknownOperatorParseMissingIdentAfterAtParseUnexpectedOperatorParseUnexpectedTermParseUnexpectedTokenParseUnexpectedKeywordParseExpectedExpressionParseExpectedLeftParenAfterCastParseExpectedLeftParenValueConstructorParseExpectedLeftParenBuiltinFunctionCallParseExpectedArgumentDelimiterParseCastArityParseInvalidTypeParamParseEmptySelectParseSelectMissingFromParseExpectedIdentForGroupNameParseExpectedIdentForAliasParseUnsupportedCallWithStarParseNonUnaryAggregateFunctionCallParseMalformedJoinParseExpectedIdentForAtParseAsteriskIsNotAloneInSelectListParseCannotMixSqbAndWildcardInSelectListParseInvalidContextForWildcardInSelectListIncorrectSQLFunctionArgumentTypeValueParseFailureEvaluatorInvalidArgumentsIntegerOverflowLikeInvalidInputsCastFailedInvalidCastEvaluatorInvalidTimestampFormatPatternEvaluatorInvalidTimestampFormatPatternSymbolForParsingEvaluatorTimestampFormatPatternDuplicateFieldsEvaluatorTimestampFormatPatternHourClockAmPmMismatchEvaluatorUnterminatedTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternTokenEvaluatorInvalidTimestampFormatPatternSymbolEvaluatorBindingDoesNotExistMissingHeadersInvalidColumnIndexAdminConfigNotificationTargetsFailedAdminProfilerNotEnabledInvalidDecompressedSizeAddUserInvalidArgumentAddUserValidUTFAdminResourceInvalidArgumentAdminAccountNotEligibleAccountNotEligibleAdminServiceAccountNotFoundPostPolicyConditionInvalidFormatInvalidChecksumLambdaARNInvalidLambdaARNNotFoundInvalidAttributeNameAdminNoAccessKeyAdminNoSecretKeyIAMNotInitializedapiErrCodeEnd"
-var _APIErrorCode_index = [...]uint16{0, 4, 16, 25, 39, 53, 67, 81, 94, 112, 129, 144, 161, 174, 186, 208, 228, 254, 268, 289, 306, 321, 344, 361, 379, 396, 420, 435, 456, 474, 486, 506, 523, 546, 567, 579, 597, 618, 646, 676, 697, 720, 746, 783, 813, 846, 871, 903, 933, 962, 987, 1009, 1035, 1057, 1085, 1114, 1148, 1179, 1216, 1240, 1264, 1292, 1318, 1349, 1379, 1388, 1400, 1416, 1429, 1443, 1461, 1481, 1502, 1518, 1529, 1545, 1556, 1584, 1604, 1620, 1648, 1662, 1679, 1699, 1712, 1726, 1739, 1752, 1768, 1785, 1806, 1820, 1841, 1854, 1876, 1899, 1915, 1930, 1945, 1966, 1984, 1999, 2016, 2041, 2059, 2082, 2097, 2116, 2132, 2151, 2172, 2186, 2198, 2211, 2230, 2249, 2259, 2274, 2310, 2341, 2374, 2403, 2415, 2435, 2459, 2483, 2504, 2528, 2547, 2568, 2585, 2595, 2612, 2629, 2652, 2674, 2700, 2721, 2739, 2766, 2797, 2824, 2845, 2866, 2890, 2915, 2943, 2971, 2987, 3010, 3040, 3051, 3063, 3080, 3095, 3113, 3142, 3159, 3175, 3191, 3209, 3227, 3250, 3271, 3294, 3305, 3321, 3344, 3361, 3389, 3408, 3438, 3458, 3486, 3501, 3519, 3534, 3548, 3583, 3602, 3613, 3626, 3641, 3664, 3690, 3706, 3724, 3742, 3763, 3777, 3794, 3825, 3845, 3866, 3887, 3906, 3925, 3943, 3966, 3990, 4014, 4039, 4074, 4099, 4133, 4166, 4187, 4201, 4220, 4249, 4272, 4299, 4333, 4365, 4395, 4418, 4446, 4478, 4506, 4530, 4554, 4583, 4601, 4618, 4640, 4657, 4675, 4695, 4721, 4737, 4756, 4777, 4781, 4799, 4816, 4842, 4856, 4880, 4901, 4916, 4934, 4957, 4972, 4991, 5008, 5025, 5049, 5076, 5099, 5122, 5139, 5161, 5177, 5197, 5216, 5238, 5259, 5279, 5301, 5325, 5344, 5386, 5407, 5430, 5451, 5482, 5501, 5523, 5543, 5569, 5590, 5612, 5632, 5656, 5679, 5698, 5718, 5740, 5763, 5794, 5832, 5873, 5903, 5917, 5938, 5954, 5976, 6006, 6032, 6060, 6094, 6112, 6135, 6170, 6210, 6252, 6284, 6301, 6326, 6341, 6358, 6368, 6379, 6417, 6471, 6517, 6569, 6617, 6660, 6704, 6732, 6746, 6764, 6800, 6823, 6846, 6868, 6883, 6911, 6934, 6952, 6979, 7011, 7026, 7042, 7059, 7079, 7095, 7111, 7128, 7141}
+var _APIErrorCode_index = [...]uint16{0, 4, 16, 25, 39, 53, 67, 81, 94, 112, 129, 144, 161, 174, 186, 208, 228, 254, 268, 289, 306, 321, 344, 361, 379, 396, 420, 435, 456, 474, 486, 506, 523, 546, 567, 579, 597, 618, 646, 676, 697, 720, 746, 783, 813, 846, 871, 903, 933, 962, 987, 1009, 1035, 1057, 1085, 1114, 1148, 1179, 1216, 1240, 1264, 1292, 1318, 1349, 1379, 1388, 1400, 1416, 1429, 1443, 1461, 1481, 1502, 1518, 1529, 1545, 1556, 1584, 1604, 1620, 1648, 1662, 1679, 1699, 1712, 1726, 1739, 1752, 1768, 1785, 1806, 1820, 1841, 1854, 1876, 1899, 1915, 1930, 1945, 1966, 1984, 1999, 2016, 2041, 2059, 2082, 2097, 2116, 2132, 2151, 2172, 2186, 2198, 2211, 2230, 2249, 2259, 2274, 2310, 2341, 2374, 2403, 2415, 2435, 2459, 2483, 2504, 2528, 2547, 2568, 2585, 2595, 2612, 2629, 2650, 2670, 2693, 2715, 2741, 2762, 2780, 2807, 2838, 2865, 2886, 2907, 2931, 2956, 2984, 3012, 3028, 3051, 3081, 3092, 3104, 3121, 3136, 3154, 3183, 3200, 3216, 3232, 3250, 3268, 3291, 3312, 3335, 3346, 3362, 3385, 3402, 3430, 3449, 3479, 3499, 3527, 3542, 3560, 3575, 3589, 3624, 3643, 3654, 3667, 3682, 3705, 3731, 3747, 3765, 3783, 3804, 3818, 3835, 3866, 3886, 3907, 3928, 3947, 3966, 3984, 4007, 4031, 4055, 4080, 4115, 4140, 4174, 4207, 4228, 4242, 4261, 4290, 4313, 4340, 4374, 4406, 4436, 4459, 4487, 4519, 4547, 4571, 4595, 4624, 4642, 4659, 4681, 4698, 4716, 4736, 4762, 4778, 4797, 4818, 4822, 4840, 4857, 4883, 4897, 4921, 4942, 4957, 4975, 4998, 5013, 5032, 5049, 5066, 5090, 5117, 5140, 5163, 5180, 5202, 5218, 5238, 5257, 5279, 5300, 5320, 5342, 5366, 5385, 5427, 5448, 5471, 5492, 5523, 5542, 5564, 5584, 5610, 5631, 5653, 5673, 5697, 5720, 5739, 5759, 5781, 5804, 5835, 5873, 5914, 5944, 5958, 5979, 5995, 6017, 6047, 6073, 6101, 6135, 6153, 6176, 6211, 6251, 6293, 6325, 6342, 6367, 6382, 6399, 6409, 6420, 6458, 6512, 6558, 6610, 6658, 6701, 6745, 6773, 6787, 6805, 6841, 6864, 6887, 6909, 6924, 6952, 6975, 6993, 7020, 7052, 7067, 7083, 7100, 7120, 7136, 7152, 7169, 7182}
func (i APIErrorCode) String() string {
if i < 0 || i >= APIErrorCode(len(_APIErrorCode_index)-1) {
diff --git a/cmd/iam-store.go b/cmd/iam-store.go
index 5640a8b8f..90e615519 100644
--- a/cmd/iam-store.go
+++ b/cmd/iam-store.go
@@ -2777,6 +2777,31 @@ func (store *IAMStoreSys) ListSTSAccounts(ctx context.Context, accessKey string)
return stsAccounts, nil
}
+// ListAccessKeys - lists all access keys (sts/service accounts)
+func (store *IAMStoreSys) ListAccessKeys(ctx context.Context) ([]auth.Credentials, error) {
+ cache := store.rlock()
+ defer store.runlock()
+
+ accessKeys := store.getSTSAndServiceAccounts(cache)
+ for i, accessKey := range accessKeys {
+ accessKeys[i].SecretKey = ""
+ if accessKey.IsTemp() {
+ secret, err := getTokenSigningKey()
+ if err != nil {
+ return nil, err
+ }
+ claims, err := getClaimsFromTokenWithSecret(accessKey.SessionToken, secret)
+ if err != nil {
+ continue // ignore invalid session tokens
+ }
+ accessKeys[i].Claims = claims.MapClaims
+ }
+ accessKeys[i].SessionToken = ""
+ }
+
+ return accessKeys, nil
+}
+
// AddUser - adds/updates long term user account to storage.
func (store *IAMStoreSys) AddUser(ctx context.Context, accessKey string, ureq madmin.AddOrUpdateUserReq) (updatedAt time.Time, err error) {
cache := store.lock()
@@ -2839,6 +2864,10 @@ func (store *IAMStoreSys) GetSTSAndServiceAccounts() []auth.Credentials {
cache := store.rlock()
defer store.runlock()
+ return store.getSTSAndServiceAccounts(cache)
+}
+
+func (store *IAMStoreSys) getSTSAndServiceAccounts(cache *iamCache) []auth.Credentials {
var res []auth.Credentials
for _, u := range cache.iamUsersMap {
cred := u.Credentials
diff --git a/cmd/iam.go b/cmd/iam.go
index ba9715abf..39416a64f 100644
--- a/cmd/iam.go
+++ b/cmd/iam.go
@@ -1246,6 +1246,20 @@ func (sys *IAMSys) ListSTSAccounts(ctx context.Context, accessKey string) ([]aut
}
}
+// ListAllAccessKeys - lists all access keys (sts/service accounts)
+func (sys *IAMSys) ListAllAccessKeys(ctx context.Context) ([]auth.Credentials, error) {
+ if !sys.Initialized() {
+ return nil, errServerNotInitialized
+ }
+
+ select {
+ case <-sys.configLoaded:
+ return sys.store.ListAccessKeys(ctx)
+ case <-ctx.Done():
+ return nil, ctx.Err()
+ }
+}
+
// GetServiceAccount - wrapper method to get information about a service account
func (sys *IAMSys) GetServiceAccount(ctx context.Context, accessKey string) (auth.Credentials, *policy.Policy, error) {
sa, embeddedPolicy, err := sys.getServiceAccount(ctx, accessKey)
diff --git a/cmd/typed-errors.go b/cmd/typed-errors.go
index da25c674a..58f2590e4 100644
--- a/cmd/typed-errors.go
+++ b/cmd/typed-errors.go
@@ -75,6 +75,9 @@ var errNoSuchServiceAccount = errors.New("Specified service account does not exi
// error returned when temporary account is not found
var errNoSuchTempAccount = errors.New("Specified temporary account does not exist")
+// error returned when access key is not found
+var errNoSuchAccessKey = errors.New("Specified access key does not exist")
+
// error returned in IAM subsystem when an account doesn't exist.
var errNoSuchAccount = errors.New("Specified account does not exist")
diff --git a/cmd/user-provider-utils.go b/cmd/user-provider-utils.go
index 5f5501350..8f2ad5358 100644
--- a/cmd/user-provider-utils.go
+++ b/cmd/user-provider-utils.go
@@ -19,8 +19,10 @@ package cmd
import (
"context"
+ "strings"
"github.com/minio/madmin-go/v3"
+ "github.com/minio/minio/internal/auth"
)
// getUserWithProvider - returns the appropriate internal username based on the user provider.
@@ -55,3 +57,85 @@ func getUserWithProvider(ctx context.Context, userProvider, user string, validat
return "", errIAMActionNotAllowed
}
}
+
+// guessUserProvider - guesses the user provider based on the access key and claims.
+func guessUserProvider(credentials auth.Credentials) string {
+ if !credentials.IsServiceAccount() && !credentials.IsTemp() {
+ return madmin.BuiltinProvider // regular users are always internal
+ }
+
+ claims := credentials.Claims
+ if _, ok := claims[ldapUser]; ok {
+ return madmin.LDAPProvider // ldap users
+ }
+
+ if _, ok := claims[subClaim]; ok {
+ providerPrefix, _, found := strings.Cut(credentials.ParentUser, getKeySeparator())
+ if found {
+ return providerPrefix // this is true for certificate and custom providers
+ }
+ return madmin.OpenIDProvider // openid users are already hashed, so no separator
+ }
+
+ return madmin.BuiltinProvider // default to internal
+}
+
+// getProviderInfoFromClaims - returns the provider info from the claims.
+func populateProviderInfoFromClaims(claims map[string]interface{}, provider string, resp *madmin.InfoAccessKeyResp) {
+ resp.UserProvider = provider
+ switch provider {
+ case madmin.LDAPProvider:
+ resp.LDAPSpecificInfo = getLDAPInfoFromClaims(claims)
+ case madmin.OpenIDProvider:
+ resp.OpenIDSpecificInfo = getOpenIDInfoFromClaims(claims)
+ }
+}
+
+func getOpenIDCfgNameFromClaims(claims map[string]interface{}) (string, bool) {
+ roleArn := claims[roleArnClaim]
+
+ s := globalServerConfig.Clone()
+ configs, err := globalIAMSys.OpenIDConfig.GetConfigList(s)
+ if err != nil {
+ return "", false
+ }
+ for _, cfg := range configs {
+ if cfg.RoleARN == roleArn {
+ return cfg.Name, true
+ }
+ }
+ return "", false
+}
+
+func getOpenIDInfoFromClaims(claims map[string]interface{}) madmin.OpenIDSpecificAccessKeyInfo {
+ info := madmin.OpenIDSpecificAccessKeyInfo{}
+
+ cfgName, ok := getOpenIDCfgNameFromClaims(claims)
+ if !ok {
+ return info
+ }
+
+ info.ConfigName = cfgName
+ if displayNameClaim := globalIAMSys.OpenIDConfig.GetUserReadableClaim(cfgName); displayNameClaim != "" {
+ name, _ := claims[displayNameClaim].(string)
+ info.DisplayName = name
+ info.DisplayNameClaim = displayNameClaim
+ }
+ if idClaim := globalIAMSys.OpenIDConfig.GetUserIDClaim(cfgName); idClaim != "" {
+ id, _ := claims[idClaim].(string)
+ info.UserID = id
+ info.UserIDClaim = idClaim
+ }
+
+ return info
+}
+
+func getLDAPInfoFromClaims(claims map[string]interface{}) madmin.LDAPSpecificAccessKeyInfo {
+ info := madmin.LDAPSpecificAccessKeyInfo{}
+
+ if name, ok := claims[ldapUser].(string); ok {
+ info.Username = name
+ }
+
+ return info
+}
diff --git a/go.mod b/go.mod
index 02d1e7bb1..5def36df8 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,8 @@ go 1.24.0
toolchain go1.24.2
+replace github.com/minio/madmin-go/v3 => github.com/taran-p/madmin-go/v3 v3.0.55-0.20250325221636-f5498832320f
+
require (
cloud.google.com/go/storage v1.46.0
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0
diff --git a/go.sum b/go.sum
index 36d2bb401..96b86ae7a 100644
--- a/go.sum
+++ b/go.sum
@@ -436,8 +436,6 @@ github.com/minio/kms-go/kes v0.3.1 h1:K3sPFAvFbJx33XlCTUBnQo8JRmSZyDvT6T2/MQ2iC3
github.com/minio/kms-go/kes v0.3.1/go.mod h1:Q9Ct0KUAuN9dH0hSVa0eva45Jg99cahbZpPxeqR9rOQ=
github.com/minio/kms-go/kms v0.4.0 h1:cLPZceEp+05xHotVBaeFJrgL7JcXM4lBy6PU0idkE7I=
github.com/minio/kms-go/kms v0.4.0/go.mod h1:q12CehiIy2qgBnDKq6Q7wmPi2PHSyRVug5DKp0HAVeE=
-github.com/minio/madmin-go/v3 v3.0.102 h1:bqy15D6d9uQOh/3B/sLfzRtWSJgZeuKnAI5VRDhvRQw=
-github.com/minio/madmin-go/v3 v3.0.102/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE=
github.com/minio/mc v0.0.0-20250312172924-c1d5d4cbb4ca h1:Zeu+Gbsw/yoqJofAFaU3zbIVr51j9LULUrQqKFLQnGA=
github.com/minio/mc v0.0.0-20250312172924-c1d5d4cbb4ca/go.mod h1:h5UQZ+5Qfq6XV81E4iZSgStPZ6Hy+gMuHMkLkjq4Gys=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
@@ -612,6 +610,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
+github.com/taran-p/madmin-go/v3 v3.0.55-0.20250325221636-f5498832320f h1:U8MMUkE2W8zVMMxpI6AwIf0PacwEYdBP1LR30FWNlhk=
+github.com/taran-p/madmin-go/v3 v3.0.55-0.20250325221636-f5498832320f/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE=
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
diff --git a/internal/config/identity/openid/openid.go b/internal/config/identity/openid/openid.go
index c2f502a68..c90c60d3e 100644
--- a/internal/config/identity/openid/openid.go
+++ b/internal/config/identity/openid/openid.go
@@ -43,13 +43,15 @@ import (
// OpenID keys and envs.
const (
- ClientID = "client_id"
- ClientSecret = "client_secret"
- ConfigURL = "config_url"
- ClaimName = "claim_name"
- ClaimUserinfo = "claim_userinfo"
- RolePolicy = "role_policy"
- DisplayName = "display_name"
+ ClientID = "client_id"
+ ClientSecret = "client_secret"
+ ConfigURL = "config_url"
+ ClaimName = "claim_name"
+ ClaimUserinfo = "claim_userinfo"
+ RolePolicy = "role_policy"
+ DisplayName = "display_name"
+ UserReadableClaim = "user_readable_claim"
+ UserIDClaim = "user_id_claim"
Scopes = "scopes"
RedirectURI = "redirect_uri"
@@ -130,6 +132,14 @@ var (
Key: KeyCloakAdminURL,
Value: "",
},
+ config.KV{
+ Key: UserReadableClaim,
+ Value: "",
+ },
+ config.KV{
+ Key: UserIDClaim,
+ Value: "",
+ },
}
)
@@ -628,3 +638,25 @@ func GetDefaultExpiration(dsecs string) (time.Duration, error) {
return defaultExpiryDuration, nil
}
+
+// GetUserReadableClaim returns the human readable claim name for the given
+// configuration name.
+func (r Config) GetUserReadableClaim(cfgName string) string {
+ pCfg, ok := r.ProviderCfgs[cfgName]
+ if ok {
+ return pCfg.UserReadableClaim
+ }
+ return ""
+}
+
+// GetUserIDClaim returns the user ID claim for the given configuration name, or "sub" if not set.
+func (r Config) GetUserIDClaim(cfgName string) string {
+ pCfg, ok := r.ProviderCfgs[cfgName]
+ if ok {
+ if pCfg.UserIDClaim != "" {
+ return pCfg.UserIDClaim
+ }
+ return "sub"
+ }
+ return "" // an incorrect config should be handled outside this function
+}
diff --git a/internal/config/identity/openid/providercfg.go b/internal/config/identity/openid/providercfg.go
index 5621b83df..0c0a91534 100644
--- a/internal/config/identity/openid/providercfg.go
+++ b/internal/config/identity/openid/providercfg.go
@@ -48,6 +48,8 @@ type providerCfg struct {
ClientID string
ClientSecret string
RolePolicy string
+ UserReadableClaim string
+ UserIDClaim string
roleArn arn.ARN
provider provider.Provider
@@ -64,6 +66,8 @@ func newProviderCfgFromConfig(getCfgVal func(cfgName string) string) providerCfg
ClientID: getCfgVal(ClientID),
ClientSecret: getCfgVal(ClientSecret),
RolePolicy: getCfgVal(RolePolicy),
+ UserReadableClaim: getCfgVal(UserReadableClaim),
+ UserIDClaim: getCfgVal(UserIDClaim),
}
}