import Boom from '@hapi/boom' ; import { ApmPluginRequestHandlerContext } from '../typings' ; import { CreateApiKeyResponse } from '../../../common/agent_key_types' ; import { PrivilegeType } from '../../../common/privilege_type' ; const resource = '*' ; interface SecurityHasPrivilegesResponse { application : { apm : { [ resource ] : { [ PrivilegeType . SOURCEMAP ] : boolean ; [ PrivilegeType . EVENT ] : boolean ; [ PrivilegeType . AGENT_CONFIG ] : boolean ; } ; } ; } ; has_all_requested : boolean ; username : string ; } export async function createAgentKey ( { context , requestBody , } ) { const { name , privileges } = requestBody ; const application = { application : 'apm' , privileges , resources : [ resource ] , } ; const { body : { application : userApplicationPrivileges , username , has_all_requested : hasRequiredPrivileges , } , } = await context . core . elasticsearch . client . asCurrentUser . security . hasPrivileges < SecurityHasPrivilegesResponse > ( { body : { application : [ application ] , } , } ) ; if ( ! hasRequiredPrivileges ) { const missingPrivileges = Object . entries ( userApplicationPrivileges . apm [ resource ] ) . filter ( ( x ) => ! x [ 1 ] ) . map ( ( x ) => x [ 0 ] ) ; const error = `${ username } is missing the following requested privilege(s): ${ missingPrivileges . join ( ', ' ) }.\
    You might try with the superuser, or add the missing APM application privileges to the role of the authenticated user, eg.:
    PUT /_security/role/my_role
    {
      ...
      "applications": [{
        "application": "apm",
        "privileges": ${ JSON . stringify ( missingPrivileges ) },
        "resources": [${ resource }]
      }],
      ...
    }` ; throw Boom . internal ( error ) ; } const body = { name , metadata : { application : 'apm' , } , role_descriptors : { apm : { cluster : [ ] , index : [ ] , applications : [ application ] , } , } , } ; const { body : agentKey } = await context . core . elasticsearch . client . asCurrentUser . security . createApiKey < CreateApiKeyResponse > ( { body , } ) ; return { agentKey , } ; }