diff --git a/pkg/api/api.go b/pkg/api/api.go index c4b5213bfe5..ebd4a2e5f33 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/models" ac "github.com/grafana/grafana/pkg/services/accesscontrol" acmiddleware "github.com/grafana/grafana/pkg/services/accesscontrol/middleware" + sa "github.com/grafana/grafana/pkg/services/serviceaccounts/manager" ) var plog = log.New("api") @@ -252,10 +253,10 @@ func (hs *HTTPServer) registerRoutes() { // auth api keys apiRoute.Group("/auth/keys", func(keysRoute routing.RouteRegister) { - keysRoute.Get("/", routing.Wrap(GetAPIKeys)) - keysRoute.Post("/", quota("api_key"), routing.Wrap(hs.AddAPIKey)) - keysRoute.Post("/additional", quota("api_key"), routing.Wrap(hs.AdditionalAPIKey)) - keysRoute.Delete("/:id", routing.Wrap(DeleteAPIKey)) + keysRoute.Get("/", authorize(reqOrgAdmin, sa.ActionApikeyListEv), routing.Wrap(GetAPIKeys)) + keysRoute.Post("/", authorize(reqOrgAdmin, sa.ActionApikeyAddEv), quota("api_key"), routing.Wrap(hs.AddAPIKey)) + keysRoute.Post("/additional", authorize(reqOrgAdmin, sa.ActionApikeyAddAdditionalEv), quota("api_key"), routing.Wrap(hs.AdditionalAPIKey)) + keysRoute.Delete("/:id", authorize(reqOrgAdmin, sa.ActionApikeyRemoveEv), routing.Wrap(DeleteAPIKey)) }, reqOrgAdmin) // Preferences diff --git a/pkg/services/serviceaccounts/manager/roles.go b/pkg/services/serviceaccounts/manager/roles.go index 11f8b23d1cd..e8038241322 100644 --- a/pkg/services/serviceaccounts/manager/roles.go +++ b/pkg/services/serviceaccounts/manager/roles.go @@ -6,7 +6,23 @@ import ( ) var ( - role = accesscontrol.RoleRegistration{ + ActionApikeyList = "apikey:list" + ActionApikeyAdd = "apikey:add" + ActionApikeyRemove = "apikey:remove" + ActionApikeyAddAdditional = "apikey:addadditional" + + apikeyWriter = "fixed:apikey:writer" + apikeyReader = "fixed:apikey:reader" + + //API key actions + ActionApikeyListEv = accesscontrol.EvalPermission(ActionApikeyList) + ActionApikeyAddEv = accesscontrol.EvalPermission(ActionApikeyAdd) + ActionApikeyRemoveEv = accesscontrol.EvalPermission(ActionApikeyRemove) //Improvement:Check here or in database layer that user has permissiono modify the service account attached to this api key + ActionApikeyAddAdditionalEv = accesscontrol.EvalPermission(ActionApikeyAddAdditional) +) + +func RegisterRoles(ac accesscontrol.AccessControl) error { + role := accesscontrol.RoleRegistration{ Role: accesscontrol.RoleDTO{ Version: 3, Name: "fixed:serviceaccounts:writer", @@ -29,4 +45,54 @@ var ( }, Grants: []string{"Admin"}, } -) + + if err := ac.DeclareFixedRoles(role); err != nil { + return err + } + + apikeyAdminReadRole := accesscontrol.RoleRegistration{ + Role: accesscontrol.RoleDTO{ + Version: 1, + Name: apikeyReader, + DisplayName: "Apikeys reader", + Description: "Gives access to list apikeys.", + Group: "Service accounts", + Permissions: []accesscontrol.Permission{ + { + Action: ActionApikeyList, + Scope: accesscontrol.ScopeUsersAll, + }, + }, + }, + Grants: []string{"Admin"}, + } + if err := ac.DeclareFixedRoles(apikeyAdminReadRole); err != nil { + return err + } + + apikeyAdminEditRole := accesscontrol.RoleRegistration{ + Role: accesscontrol.RoleDTO{ + Version: 1, + Name: apikeyWriter, + DisplayName: "Apikeys writer", + Description: "Gives access to add and delete api keys.", + Group: "Service accounts", + Permissions: accesscontrol.ConcatPermissions(apikeyAdminReadRole.Role.Permissions, []accesscontrol.Permission{ + { + Action: ActionApikeyAdd, + Scope: accesscontrol.ScopeUsersAll, + }, + { + Action: ActionApikeyRemove, + Scope: accesscontrol.ScopeUsersAll, + }, + }), + }, + Grants: []string{"Admin"}, + } + if err := ac.DeclareFixedRoles(apikeyAdminEditRole); err != nil { + return err + } + + return nil +} diff --git a/pkg/services/serviceaccounts/manager/service.go b/pkg/services/serviceaccounts/manager/service.go index 4de30ba79b3..010a92da099 100644 --- a/pkg/services/serviceaccounts/manager/service.go +++ b/pkg/services/serviceaccounts/manager/service.go @@ -35,9 +35,11 @@ func ProvideServiceAccountsService( store: database.NewServiceAccountsStore(store), log: log.New("serviceaccounts"), } - if err := ac.DeclareFixedRoles(role); err != nil { - return nil, err + + if err := RegisterRoles(ac); err != nil { + s.log.Error("Failed to register roles", "error", err) } + serviceaccountsAPI := api.NewServiceAccountsAPI(s, ac, routeRegister, s.store) serviceaccountsAPI.RegisterAPIEndpoints(cfg)