Skip to content

Commit

Permalink
Restrict APM Server user role (#2777)
Browse files Browse the repository at this point in the history
* Restrict APM Server user role
  • Loading branch information
barkbay authored Apr 2, 2020
1 parent 341bd66 commit c2a768d
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 19 deletions.
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,33 @@ 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
"apm_system", // To collect metrics about APM Server
}, ",")
}

// 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
"apm_system", // To collect metrics about APM Server
}, ",")
}

// 6.8
return strings.Join([]string{
user.ApmUserRoleV6, // Retrieve cluster details (e.g. version) and manage apm-* indices
"apm_system", // To collect metrics about APM Server
}, ",")
}

// 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 +321,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 @@ -30,25 +30,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 6.8.x APMServer instances to connect to Elasticsearch.
ApmUserRoleV6 = "eck_apm_user_role_v6"
// ApmUserRoleV7 is the name of the role used by APMServer instances to connect to Elasticsearch from version 7.1 to 7.4 included.
ApmUserRoleV7 = "eck_apm_user_role_v7"
// ApmUserRoleV75 is the name of the role used by APMServer instances to connect to Elasticsearch 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"},
},
},
},
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"},
},
},
},
}
)

Expand Down

0 comments on commit c2a768d

Please sign in to comment.