From ba6719a3c43d9472f7b9a930962cbaf47e36c501 Mon Sep 17 00:00:00 2001 From: joerger Date: Mon, 26 Feb 2024 16:54:52 -0800 Subject: [PATCH] Require admin MFA for UpsertTrustedCluster. --- lib/auth/auth_with_roles.go | 8 ++++++++ lib/web/resources.go | 9 ++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index f812458f8b5fb..72045af29c489 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -4567,6 +4567,10 @@ func (a *ServerWithRoles) UpsertTrustedCluster(ctx context.Context, tc types.Tru return nil, trace.Wrap(err) } + if err := a.context.AuthorizeAdminAction(); err != nil { + return nil, trace.Wrap(err) + } + return a.authServer.UpsertTrustedCluster(ctx, tc) } @@ -4586,6 +4590,10 @@ func (a *ServerWithRoles) DeleteTrustedCluster(ctx context.Context, name string) return trace.Wrap(err) } + if err := a.context.AuthorizeAdminAction(); err != nil { + return trace.Wrap(err) + } + return a.authServer.DeleteTrustedCluster(ctx, name) } diff --git a/lib/web/resources.go b/lib/web/resources.go index f696635a6cfa7..347360eb2e73d 100644 --- a/lib/web/resources.go +++ b/lib/web/resources.go @@ -30,6 +30,7 @@ import ( "github.com/gravitational/teleport/api/client/proto" kubeproto "github.com/gravitational/teleport/api/gen/proto/go/teleport/kube/v1" + "github.com/gravitational/teleport/api/mfa" "github.com/gravitational/teleport/api/types" "github.com/gravitational/teleport/lib/auth" "github.com/gravitational/teleport/lib/client" @@ -238,7 +239,13 @@ func (h *Handler) upsertTrustedClusterHandle(w http.ResponseWriter, r *http.Requ func upsertTrustedCluster(ctx context.Context, clt resourcesAPIGetter, content, httpMethod string, params httprouter.Params) (*ui.ResourceItem, error) { get := func(ctx context.Context, name string) (types.Resource, error) { - return clt.GetTrustedCluster(ctx, name) + // Remove the MFA resp from the context before getting the trusted cluster. + // Otherwise, it will be consumed before the Upsert which actually + // requires the MFA. + // TODO(Joerger): Explicitly provide MFA response only where it is + // needed instead of removing it like this. + getCtx := mfa.ContextWithMFAResponse(ctx, nil) + return clt.GetTrustedCluster(getCtx, name) } extractedRes, err := ExtractResourceAndValidate(content)