K8s: Prevent user impersonation (#78555)

This commit is contained in:
Todd Treece 2023-11-22 15:55:37 -05:00 committed by GitHub
parent d269a123e7
commit 4203a83538
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 1 deletions

View File

@ -0,0 +1,19 @@
package impersonation
import (
"context"
"k8s.io/apiserver/pkg/authorization/authorizer"
)
var _ authorizer.Authorizer = (*ImpersonationAuthorizer)(nil)
// ImpersonationAuthorizer denies all impersonation requests.
type ImpersonationAuthorizer struct{}
func (auth ImpersonationAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
if a.GetVerb() == "impersonate" {
return authorizer.DecisionDeny, "user impersonation is not supported", nil
}
return authorizer.DecisionNoOpinion, "", nil
}

View File

@ -0,0 +1,48 @@
package impersonation_test
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"k8s.io/apiserver/pkg/authorization/authorizer"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/auth/authorizer/impersonation"
)
func TestImpersonationAuthorizer_Authorize(t *testing.T) {
auth := impersonation.ImpersonationAuthorizer{}
t.Run("impersonate verb", func(t *testing.T) {
attrs := &fakeAttributes{
verb: "impersonate",
}
authorized, reason, err := auth.Authorize(context.Background(), attrs)
require.Equal(t, authorizer.DecisionDeny, authorized)
require.Equal(t, "user impersonation is not supported", reason)
require.NoError(t, err)
})
t.Run("other verb", func(t *testing.T) {
attrs := &fakeAttributes{
verb: "get",
}
authorized, reason, err := auth.Authorize(context.Background(), attrs)
require.Equal(t, authorizer.DecisionNoOpinion, authorized)
require.Equal(t, "", reason)
require.NoError(t, err)
})
}
type fakeAttributes struct {
authorizer.Attributes
verb string
}
func (a fakeAttributes) GetVerb() string {
return a.verb
}

View File

@ -4,6 +4,7 @@ import (
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/authorization/union"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/auth/authorizer/impersonation"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/auth/authorizer/org"
"github.com/grafana/grafana/pkg/services/grafana-apiserver/auth/authorizer/stack"
"github.com/grafana/grafana/pkg/setting"
@ -15,7 +16,9 @@ func ProvideAuthorizer(
stackIDAuthorizer *stack.StackIDAuthorizer,
cfg *setting.Cfg,
) authorizer.Authorizer {
authorizers := []authorizer.Authorizer{}
authorizers := []authorizer.Authorizer{
&impersonation.ImpersonationAuthorizer{},
}
// In Hosted grafana, the StackID replaces the orgID as a valid namespace
if cfg.StackID != "" {