Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion api/utils/grpc/interceptors/mfa.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package interceptors
import (
"context"
"errors"
"strings"

"github.com/gravitational/trace"
"github.com/gravitational/trace/trail"
Expand All @@ -35,7 +36,14 @@ func RetryWithMFAUnaryInterceptor(mfaCeremony func(ctx context.Context, opts ...
return err
}

mfaResp, ceremonyErr := mfaCeremony(ctx, mfa.WithPromptReasonAdminAction(method))
// In this context, method looks like "/proto.<grpc-service-name>/<method-name>",
// we just want the method name.
splitMethod := strings.Split(method, "/")
readableMethodName := splitMethod[len(splitMethod)-1]

// Start an MFA prompt that shares what API request caused MFA to be prompted.
// ex: MFA is required for admin-level API request: "CreateUser"
mfaResp, ceremonyErr := mfaCeremony(ctx, mfa.WithPromptReasonAdminAction(readableMethodName))
if ceremonyErr != nil {
return trace.NewAggregate(trail.FromGRPC(err), ceremonyErr)
}
Expand Down
4 changes: 4 additions & 0 deletions lib/client/mfa/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ func NewCLIPrompt(cfg *PromptConfig, writer io.Writer) *CLIPrompt {

// Run prompts the user to complete an MFA authentication challenge.
func (c *CLIPrompt) Run(ctx context.Context, chal *proto.MFAAuthenticateChallenge) (*proto.MFAAuthenticateResponse, error) {
if c.cfg.PromptReason != "" {
fmt.Fprintln(c.writer, c.cfg.PromptReason)
}

var wg sync.WaitGroup
runOpts, err := c.cfg.getRunOptions(ctx, chal)
if err != nil {
Expand Down