Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict APM Server user role #2777

Merged
merged 10 commits into from
Apr 2, 2020
Merged
Show file tree
Hide file tree
Changes from 7 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
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package apmserverelasticsearchassociation
import (
"context"
"reflect"
"strings"
"time"

"go.elastic.co/apm"
Expand All @@ -33,8 +34,10 @@ import (
"github.com/elastic/cloud-on-k8s/pkg/controller/common/operator"
"github.com/elastic/cloud-on-k8s/pkg/controller/common/reconciler"
"github.com/elastic/cloud-on-k8s/pkg/controller/common/tracing"
"github.com/elastic/cloud-on-k8s/pkg/controller/common/version"
"github.com/elastic/cloud-on-k8s/pkg/controller/common/watches"
"github.com/elastic/cloud-on-k8s/pkg/controller/elasticsearch/services"
"github.com/elastic/cloud-on-k8s/pkg/controller/elasticsearch/user"
"github.com/elastic/cloud-on-k8s/pkg/utils/k8s"
"github.com/elastic/cloud-on-k8s/pkg/utils/maps"
"github.com/elastic/cloud-on-k8s/pkg/utils/rbac"
Expand All @@ -51,6 +54,28 @@ var (
defaultRequeue = reconcile.Result{Requeue: true, RequeueAfter: 10 * time.Second}
)

// getRoles returns for a given version of the APM Server the set of required roles.
func getRoles(v version.Version) string {
// 7.5.x and above
if v.IsSameOrAfter(version.From(7, 5, 0)) {
return strings.Join([]string{
user.ApmUserRoleV75, // Retrieve cluster details (e.g. version) and manage apm-* indices
"ingest_admin", // Set up index templates
}, ",")
}

// 7.1.x to 7.4.x
if v.IsSameOrAfter(version.From(7, 1, 0)) {
return strings.Join([]string{
user.ApmUserRoleV7, // Retrieve cluster details (e.g. version) and manage apm-* indices
"ingest_admin", // Set up index templates
}, ",")
}

// 6.8
return user.ApmUserRoleV6
}

// Add creates a new ApmServerElasticsearchAssociation Controller and adds it to the Manager with default RBAC. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager, accessReviewer rbac.AccessReviewer, params operator.Parameters) error {
Expand Down Expand Up @@ -291,7 +316,7 @@ func (r *ReconcileApmServerElasticsearchAssociation) reconcileInternal(ctx conte
r.Client,
apmServer,
associationLabels(apmServer),
"superuser",
getRoles(version.MustParse(apmServer.Spec.Version)),
apmUserSuffix,
es,
); err != nil { // TODO distinguish conflicts and non-recoverable errors here
Expand Down
24 changes: 7 additions & 17 deletions pkg/controller/elasticsearch/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,15 @@ type BasicAuth struct {
Password string
}

type IndexRole struct {
Names []string `json:"names,omitempty"`
Privileges []string `json:",omitempty"`
}

// Role represents an Elasticsearch role.
type Role struct {
Cluster []string `json:"cluster,omitempty"`
/*Indices []struct {
Names []string `json:"names,omitempty"`
Privileges []string `json:",omitempty"`
} `json:"indices,omitempty"`
Applications []struct {
Application string `json:"application"`
Privileges []string `json:"privileges"`
Resources []string `json:"resources,omitempty"`
} `json:"applications,omitempty"`
RunAs []string `json:"run_as,omitempty"`
Metadata *struct {
Reserved bool `json:"_reserved"`
} `json:"metadata,omitempty"`
TransientMetadata *struct {
Enabled bool `json:"enabled"`
} `json:"transient_metadata,omitempty"`*/
Cluster []string `json:"cluster,omitempty"`
Indices []IndexRole `json:"indices,omitempty"`
}

// Client captures the information needed to interact with an Elasticsearch cluster via HTTP
Expand Down
2 changes: 1 addition & 1 deletion pkg/controller/elasticsearch/user/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,6 @@ func Test_aggregateRoles(t *testing.T) {
c := k8s.WrappedFakeClient(sampleUserProvidedRolesSecret...)
roles, err := aggregateRoles(c, sampleEsWithAuth, initDynamicWatches(), record.NewFakeRecorder(10))
require.NoError(t, err)
require.Len(t, roles, 3)
require.Len(t, roles, 6)
require.Contains(t, roles, ProbeUserRole, "role1", "role2")
}
34 changes: 34 additions & 0 deletions pkg/controller/elasticsearch/user/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,46 @@ const (
SuperUserBuiltinRole = "superuser"
// ProbeUserRole is the name of the role used by the internal probe user.
ProbeUserRole = "elastic_internal_probe_user"

// ApmUserRoleV6 is the name of the role used by the association user for 6.8.x APMServer instances.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we calling it the association user? Is it not just the user APM Server will use to connect to Elasticsearch?

ApmUserRoleV6 = "eck_apm_user_role_v6"
// ApmUserRoleV7 is the name of the role used by the association user for APMServer instances from version 7.1 to 7.4 included.
ApmUserRoleV7 = "eck_apm_user_role_v7"
// ApmUserRoleV75 is the name of the role used by the association user for APMServer instances from version 7.5
ApmUserRoleV75 = "eck_apm_user_role_v75"
)

var (
// PredefinedRoles to create for internal needs.
PredefinedRoles = RolesFileContent{
ProbeUserRole: esclient.Role{Cluster: []string{"monitor"}},
ApmUserRoleV6: esclient.Role{
Cluster: []string{"monitor", "manage_index_templates"},
Indices: []esclient.IndexRole{
{
Names: []string{"apm-*"},
Privileges: []string{"write", "create_index"},
},
},
},
ApmUserRoleV7: esclient.Role{
Cluster: []string{"monitor", "manage_ilm", "manage_index_templates"},
Indices: []esclient.IndexRole{
{
Names: []string{"apm-*"},
Privileges: []string{"manage", "write", "create_index"},
simitt marked this conversation as resolved.
Show resolved Hide resolved
},
},
},
ApmUserRoleV75: esclient.Role{
Cluster: []string{"monitor", "manage_ilm", "manage_api_key"}, // manage_api_key has been introduced in 7.5
Indices: []esclient.IndexRole{
{
Names: []string{"apm-*"},
Privileges: []string{"manage", "create_doc", "create_index"},
barkbay marked this conversation as resolved.
Show resolved Hide resolved
},
barkbay marked this conversation as resolved.
Show resolved Hide resolved
},
},
}
)

Expand Down