Skip to content

Commit 5349af0

Browse files
authored
Add admin accesskey sts-revoke and idp ldap accesskey sts-revoke (#5160)
1 parent ceb07be commit 5349af0

File tree

7 files changed

+257
-12
lines changed

7 files changed

+257
-12
lines changed

cmd/admin-accesskey-sts-revoke.go

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
// Copyright (c) 2015-2025 MinIO, Inc.
2+
//
3+
// This file is part of MinIO Object Storage stack
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
package cmd
19+
20+
import (
21+
"github.com/minio/cli"
22+
json "github.com/minio/colorjson"
23+
"github.com/minio/madmin-go/v3"
24+
"github.com/minio/mc/pkg/probe"
25+
)
26+
27+
var adminAccesskeySTSRevokeFlags = []cli.Flag{
28+
cli.BoolFlag{
29+
Name: "all",
30+
Usage: "revoke all STS accounts for the specified user",
31+
},
32+
cli.BoolFlag{
33+
Name: "self",
34+
Usage: "revoke all STS accounts for the authenticated user",
35+
},
36+
cli.StringFlag{
37+
Name: "token-type",
38+
Usage: "specify the token type to revoke",
39+
},
40+
}
41+
42+
var adminAccesskeySTSRevokeCmd = cli.Command{
43+
Name: "sts-revoke",
44+
Usage: "revokes all STS accounts or specified types for the specified user",
45+
Action: mainAdminAccesskeySTSRevoke,
46+
OnUsageError: onUsageError,
47+
Before: setGlobalsFromContext,
48+
Flags: append(adminAccesskeySTSRevokeFlags, globalFlags...),
49+
CustomHelpTemplate: `NAME:
50+
{{.HelpName}} - {{.Usage}}
51+
52+
USAGE:
53+
{{.HelpName}} ALIAS USER [--all | --token-type TOKEN_TYPE]
54+
55+
Exactly one of --all or --token-type must be specified.
56+
57+
FLAGS:
58+
{{range .VisibleFlags}}{{.}}
59+
{{end}}
60+
EXAMPLES:
61+
1. Revoke all STS accounts for user "user1"
62+
{{.Prompt}} {{.HelpName}} myminio user1 --all
63+
64+
2. Revoke STS accounts of a token type "app-1" for user "user1"
65+
{{.Prompt}} {{.HelpName}} myminio user1 --token-type app-1
66+
67+
3. Revoke all STS accounts for the authenticated user
68+
{{.Prompt}} {{.HelpName}} myminio --self
69+
70+
4. Revoke STS accounts of a token type "app-1" for the authenticated user
71+
{{.Prompt}} {{.HelpName}} myminio --self --token-type app-1
72+
`,
73+
}
74+
75+
type stsRevokeMessage struct {
76+
Status string `json:"status"`
77+
User string `json:"user"`
78+
TokenRevokeType string `json:"tokenRevokeType,omitempty"`
79+
}
80+
81+
func (m stsRevokeMessage) String() string {
82+
userString := "user " + m.User
83+
if m.User == "" {
84+
userString = "authenticated user"
85+
}
86+
if m.TokenRevokeType == "" {
87+
return "Successfully revoked all STS accounts for " + userString
88+
}
89+
return "Successfully revoked all STS accounts of type " + m.TokenRevokeType + " for " + userString
90+
}
91+
92+
func (m stsRevokeMessage) JSON() string {
93+
if m.Status == "" {
94+
m.Status = "success"
95+
}
96+
jsonMessageBytes, e := json.MarshalIndent(m, "", " ")
97+
fatalIf(probe.NewError(e), "Unable to marshal into JSON.")
98+
99+
return string(jsonMessageBytes)
100+
}
101+
102+
// checkSTSRevokeSyntax - validate all the passed arguments
103+
func checkSTSRevokeSyntax(ctx *cli.Context) {
104+
if len(ctx.Args()) > 2 || len(ctx.Args()) == 0 {
105+
showCommandHelpAndExit(ctx, 1)
106+
}
107+
108+
if !ctx.Bool("self") && ctx.Args().Get(1) == "" {
109+
fatalIf(errInvalidArgument().Trace(), "Must specify user or use --self flag.")
110+
}
111+
112+
if ctx.Bool("self") && ctx.Args().Get(1) != "" {
113+
fatalIf(errInvalidArgument().Trace(), "Cannot specify user with --self flag.")
114+
}
115+
116+
if (!ctx.Bool("all") && ctx.String("token-type") == "") || (ctx.Bool("all") && ctx.String("token-type") != "") {
117+
fatalIf(errDummy().Trace(), "Exactly one of --all or --token-type must be specified.")
118+
}
119+
}
120+
121+
// mainAdminAccesskeySTSRevoke is the handle for "mc admin accesskey sts-revoke" command.
122+
func mainAdminAccesskeySTSRevoke(ctx *cli.Context) error {
123+
checkSTSRevokeSyntax(ctx)
124+
125+
// Get the alias parameter from cli
126+
args := ctx.Args()
127+
aliasedURL := args.Get(0)
128+
user := args.Get(1) // will be empty if --self flag is set
129+
tokenRevokeType := ctx.String("token-type")
130+
fullRevoke := ctx.Bool("all")
131+
132+
// Create a new MinIO Admin Client
133+
client, err := newAdminClient(aliasedURL)
134+
fatalIf(err, "Unable to initialize admin connection.")
135+
136+
e := client.RevokeTokens(globalContext, madmin.RevokeTokensReq{
137+
User: user,
138+
TokenRevokeType: tokenRevokeType,
139+
FullRevoke: fullRevoke,
140+
})
141+
fatalIf(probe.NewError(e).Trace(args...), "Unable to revoke tokens for %s", user)
142+
143+
printMsg(stsRevokeMessage{
144+
User: user,
145+
TokenRevokeType: tokenRevokeType,
146+
})
147+
148+
return nil
149+
}

cmd/admin-accesskey.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ var adminAccesskeySubcommands = []cli.Command{
2727
adminAccesskeyEditCmd,
2828
adminAccesskeyEnableCmd,
2929
adminAccesskeyDisableCmd,
30+
adminAccesskeySTSRevokeCmd,
3031
}
3132

3233
var adminAccesskeyCmd = cli.Command{

cmd/auto-complete.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -391,16 +391,18 @@ var completeCmds = map[string]complete.Predictor{
391391
"/idp/ldap/accesskey/edit": aliasCompleter,
392392
"/idp/ldap/accesskey/enable": aliasCompleter,
393393
"/idp/ldap/accesskey/disable": aliasCompleter,
394-
395-
"/admin/accesskey/create": aliasCompleter,
396-
"/admin/accesskey/list": aliasCompleter,
397-
"/admin/accesskey/ls": aliasCompleter,
398-
"/admin/accesskey/remove": aliasCompleter,
399-
"/admin/accesskey/rm": aliasCompleter,
400-
"/admin/accesskey/info": aliasCompleter,
401-
"/admin/accesskey/edit": aliasCompleter,
402-
"/admin/accesskey/enable": aliasCompleter,
403-
"/admin/accesskey/disable": aliasCompleter,
394+
"/idp/ldap/accesskey/sts-revoke": aliasCompleter,
395+
396+
"/admin/accesskey/create": aliasCompleter,
397+
"/admin/accesskey/list": aliasCompleter,
398+
"/admin/accesskey/ls": aliasCompleter,
399+
"/admin/accesskey/remove": aliasCompleter,
400+
"/admin/accesskey/rm": aliasCompleter,
401+
"/admin/accesskey/info": aliasCompleter,
402+
"/admin/accesskey/edit": aliasCompleter,
403+
"/admin/accesskey/enable": aliasCompleter,
404+
"/admin/accesskey/disable": aliasCompleter,
405+
"/admin/accesskey/sts-revoke": aliasCompleter,
404406

405407
"/admin/policy/info": aliasCompleter,
406408
"/admin/policy/update": aliasCompleter,
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// Copyright (c) 2015-2025 MinIO, Inc.
2+
//
3+
// This file is part of MinIO Object Storage stack
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as published by
7+
// the Free Software Foundation, either version 3 of the License, or
8+
// (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
package cmd
19+
20+
import (
21+
"github.com/minio/cli"
22+
"github.com/minio/madmin-go/v3"
23+
"github.com/minio/mc/pkg/probe"
24+
)
25+
26+
var idpLdapAccesskeySTSRevokeCmd = cli.Command{
27+
Name: "sts-revoke",
28+
Usage: "revokes all STS accounts or specified types for the specified user",
29+
Action: mainIdpLdapAccesskeySTSRevoke,
30+
OnUsageError: onUsageError,
31+
Before: setGlobalsFromContext,
32+
Flags: append(adminAccesskeySTSRevokeFlags, globalFlags...),
33+
CustomHelpTemplate: `NAME:
34+
{{.HelpName}} - {{.Usage}}
35+
36+
USAGE:
37+
{{.HelpName}} ALIAS USER [--all | --token-type TOKEN_TYPE]
38+
39+
Exactly one of --all or --token-type must be specified.
40+
41+
FLAGS:
42+
{{range .VisibleFlags}}{{.}}
43+
{{end}}
44+
EXAMPLES:
45+
1. Revoke all STS accounts for LDAP user 'bobfisher'
46+
{{.Prompt}} {{.HelpName}} myminio uid=bobfisher,ou=people,ou=hwengg,dc=min,dc=io --all
47+
48+
2. Revoke all STS accounts for LDAP user 'bobfisher' (alt)
49+
{{.Prompt}} {{.HelpName}} myminio bobfisher --all
50+
51+
3. Revoke STS accounts of a token type 'app-1' for user 'user1'
52+
{{.Prompt}} {{.HelpName}} myminio user1 --token-type app-1
53+
54+
4. Revoke all STS accounts for the authenticated user (must be LDAP service account)
55+
{{.Prompt}} {{.HelpName}} myminio --self
56+
57+
5. Revoke STS accounts of a token type 'app-1' for the authenticated user (must be LDAP service account)
58+
{{.Prompt}} {{.HelpName}} myminio --self --token-type app-1
59+
`,
60+
}
61+
62+
// mainIdpLdapAccesskeySTSRevoke is the handle for "mc idp ldap accesskey sts-revoke" command.
63+
func mainIdpLdapAccesskeySTSRevoke(ctx *cli.Context) error {
64+
checkSTSRevokeSyntax(ctx)
65+
66+
// Get the alias parameter from cli
67+
args := ctx.Args()
68+
aliasedURL := args.Get(0)
69+
user := args.Get(1) // will be empty if --self flag is set
70+
tokenRevokeType := ctx.String("token-type")
71+
fullRevoke := ctx.Bool("all")
72+
73+
// Create a new MinIO Admin Client
74+
client, err := newAdminClient(aliasedURL)
75+
fatalIf(err, "Unable to initialize admin connection.")
76+
77+
e := client.RevokeTokens(globalContext, madmin.RevokeTokensReq{
78+
User: user,
79+
TokenRevokeType: tokenRevokeType,
80+
FullRevoke: fullRevoke,
81+
})
82+
fatalIf(probe.NewError(e).Trace(args...), "Unable to revoke tokens for %s", user)
83+
84+
printMsg(stsRevokeMessage{
85+
User: user,
86+
TokenRevokeType: tokenRevokeType,
87+
})
88+
89+
return nil
90+
}

cmd/idp-ldap-accesskey.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var idpLdapAccesskeySubcommands = []cli.Command{
2828
idpLdapAccesskeyEditCmd,
2929
idpLdapAccesskeyEnableCmd,
3030
idpLdapAccesskeyDisableCmd,
31+
idpLdapAccesskeySTSRevokeCmd,
3132
}
3233

3334
var idpLdapAccesskeyCmd = cli.Command{

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ go 1.23.0
44

55
toolchain go1.23.6
66

7+
replace github.com/minio/madmin-go/v3 => github.com/minio/madmin-go/v3 v3.0.100-0.20250319234114-3c39f28946cb
8+
79
require (
810
github.com/charmbracelet/bubbles v0.20.0
911
github.com/charmbracelet/bubbletea v1.3.4

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ github.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY
142142
github.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
143143
github.com/minio/filepath v1.0.0 h1:fvkJu1+6X+ECRA6G3+JJETj4QeAYO9sV43I79H8ubDY=
144144
github.com/minio/filepath v1.0.0/go.mod h1:/nRZA2ldl5z6jT9/KQuvZcQlxZIMQoFFQPvEXx9T/Bw=
145-
github.com/minio/madmin-go/v3 v3.0.97 h1:P7XO+ofPexkXy9akxG9Xoif1zIkbmWKeKtG3AquVzEY=
146-
github.com/minio/madmin-go/v3 v3.0.97/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE=
145+
github.com/minio/madmin-go/v3 v3.0.100-0.20250319234114-3c39f28946cb h1:J+db7F8JuJDR/lqco4XHLtM5gErYkSYXwR+X4hfjl3Q=
146+
github.com/minio/madmin-go/v3 v3.0.100-0.20250319234114-3c39f28946cb/go.mod h1:pMLdj9OtN0CANNs5tdm6opvOlDFfj0WhbztboZAjRWE=
147147
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
148148
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
149149
github.com/minio/minio-go/v7 v7.0.88 h1:v8MoIJjwYxOkehp+eiLIuvXk87P2raUtoU5klrAAshs=

0 commit comments

Comments
 (0)