diff --git a/api/utils/grpc/interceptors/mfa.go b/api/utils/grpc/interceptors/mfa.go index 7bc3c3d6d8bb6..665147bf06d02 100644 --- a/api/utils/grpc/interceptors/mfa.go +++ b/api/utils/grpc/interceptors/mfa.go @@ -17,6 +17,7 @@ package interceptors import ( "context" "errors" + "strings" "github.com/gravitational/trace" "github.com/gravitational/trace/trail" @@ -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./", + // 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) } diff --git a/lib/client/mfa/cli.go b/lib/client/mfa/cli.go index b3ad1af8cb52a..25b87b0f38444 100644 --- a/lib/client/mfa/cli.go +++ b/lib/client/mfa/cli.go @@ -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 {