SentinelOne Management SDK - Node.js This SDK has been developed based on SentinelOne's 2 API documentation. The purpose of this SDK should help IT administrators and security teams help automate management of their Sentinelone fleet. Node SDK In GitHub
to install dependency simply run :
npm install
To run unit tests (jest) :
npm run test
!!! If you are running into issue with tests , you may need to delete compiled files (ts to js)
To build documentation locally ,run :
npm run docs
To run in dev mode (node-deamon) :
npm run start:dev
To compile typescript in watch mode :
npm run build:watch
This is only suggested configuration structure:
export const configure = {
auth: {
by: {
login: { username: '', password: '' },
apiToken: '',
app: { code: '' }
}
},
hostName: ``,
apiPath: `web/api/v2.0`
};
npm login
npm publish
commandconst mgmt = Management.getInstance(configure.hostName, configure.apiPath);
const activityEntity: Activities = mgmt.activities;
const filterEntity: Filters = mgmt.filters;
const settingsEntity: Settings = mgmt.settings;
const notifications: Notifications = settingsEntity.notifications;
const sitesEntity: Sites = mgmt.sites;
const reportsEntity: Report = mgmt.reports;
const ExlusionEntity: Exclusions = mgmt.exclusions;
const HashEntity: Hash = mgmt.hash;
const updates: Update = mgmt.updates;
Management is the main Entity (Hold all others in the SDK) each one represent the related mangment api for this Entity
const mgmt = Management.getInstance(configure.hostName, configure.apiPath);
const authRes = await mgmt.authenticator.authenticate({
method: AuthMethodsTypes.Login,
data: configure.auth.by.login
});
Before we will be able to send api calls through the sdk we have to authenticate in one of the following ways :
Note : The NodeJs SDK is running in an async-await manners. This means thar api calls are wrapped in async function and await must appear before the method call.
As Following:
async function main() {
const systemStettings = await mgmt.system.get();
}
This structure is used to investigate failed api requests . and get information about calls history made in the sdk .
{
url: 'api end point url',
respondData:{},
request:{} // requst as sent to server
status: 200 | ErrorDetails
}
async function main() {
const systemReq = await mgmt.system.get();
// logging http request and respond
console.log(systemReq);
const stettingData = systemReq.respondData;
// logging data retrived from the api
console.log(stettingData);
}
! By defualt most entities should have four basic fucntion ( create,delete,get,update ).
This way you can verify that the expected data is sent correcttly , before acully make the api call
const request = new RequestData<CreateSiteRequest>({
name: 'name',
inherits: false,
siteType: SiteTypes.DEV,
suite: SuiteTypes.Complete,
totalLicenses: 10
});
console.log(await mgmt.sites.create(request.data));
console.log(
await mgmt.sites.create({
name: 'siteName',
siteType: SiteTypes.Paid,
suite: SuiteTypes.Core,
unlimitedExpiration: true,
totalLicenses: 3,
unlimitedLicenses: true
})
);
The SDK had endpoints for each http request in the following structure:
export const <EntityName> = {
<method_name> : { url: `<Appended endpoint url>`, method: HttpMethod.<GET | POST | PUT | DELETE> }
}
/**
* enum for end point name-endpoint mapping
**/
export enum <EntityName>EndPointsTypes {
<method_name> = '<method_name>'
}
export const ActivitiesEndPointsNames = ActivitiesEndPointsTypes;
Make sure you keep structure consistency, for any change made in that section farther more dont forget:
This small Gist was created for faster development using vscode and the node-sdk. (Later On he will be move to seperate gist url) in order to use it :
{
"Print to console": {
"prefix": "log",
"body": ["console.log('$1');", "$2"],
"description": "Log output to console"
},
"SDKasync": {
"prefix": "SDKasync",
"body": [
"async ${1:methodName} (${2:data}:${3:dataType}): Promise<SDKRespond>{",
" try{",
" return this.makeApiCall(this.endPoints.${4:endPointName} , ${5:data })",
" } catch( err ){",
" throw err",
" }",
"}"
],
"description": "SDK async method function"
},
"SDKreq": {
"prefix": "SDKreq",
"body": [
"const data:${1|CreateSiteRequest,UpdateSiteRequest,ReactiveSiteRequest,ChangePasswordRequest,CreateUserRequest,Enable2faAppRequest,PolicyIocAttributes,UpdateUserRequest,VerifyCodeRequest,CountByFilterPayload,GetThreatsGrouped,MarkAsBengin,MarkAsResolve,ThreatFilterPayload,SetSystemConfigurionRequest,SettingGetRespond,CreateNotifictionType,NotificationRequest,NotificationGetRequest,NotificationRecipientsRequest,NotificationsType,ActiveDirectoryRequest,AdRolesStringsDataRequest,SmtpDataRequest,SsoDataRequest,PolicyEngiens,PolicyRequestFilter,PolicyDataRequest,GroupRequestData,MoveAgentGroup,Rank,SiteDefualtGroupRequest,FilterAdditionalDataRequest,BaseFilterFileld,CreateDvFilterRequest,CreateFilterRequest,GetFilterRequest,UpdateDvFilterRequest,UpdateFilterRequest,CreateListItemRequest,ExclusionsUpdateItem,GetListItemsRequest,DeepVisibilityV2CreateQuery,BaseDeepVisibilityV2Request,DeepVisibilityV2GetEventsRequest,DVAgent,DVRequestData,DVProccess,GetCommandRequest,GetActivitiesFilters,GroupedAppInventory|} = {} ;"
],
"description": "SDK DATA"
},
"SDKconfig": {
"prefix": "SDKconfig",
"body": [
"export const configure = {",
"auth: {",
" by: {",
"login: { username: '${1}' , password: '${2}' },",
" apiToken: '${3}',",
" app: { code: '${4}' }",
" }",
"},",
"hostName: '${5}',",
"apiPath: 'web/api/v2.0' ",
"} "
],
"description": "SDK async method function"
},
"SDKauth": {
"prefix": "SDKauth",
"body": [
"await mgmt.authenticator.authenticate({ method: AuthMethodsTypes.Login, data: configure.auth.by.login })"
],
"description": "SDK Auth method"
},
"SDKmgmt": {
"prefix": "SDKmgmt",
"body": [
"const mgmt = Management.getInstance(configure.hostName, configure.apiPath)"
],
"description": "SDK Managment Object"
},
"ManagmentEntity": {
"prefix": "mgmte",
"body": [
"const ${1:Entity} = Management.getInstance(configure.hostName, configure.apiPath).${2|authenticator,threats,users,sites,system,policy,groups,commands,activities,settings,configOverride,filters,reports,hash,exclusions,deepVisibilityV2,agents,agentActions,deepVisibility,updates|}"
],
"description": "SDK Managment Entity"
}
}
the main file of the app is: src/entities/mangment/mangment.class.ts
let's take for example the entity (group of api requests) custom-detection
every entity has:
this.customDetectionRules = new CustomDetectionRules(this.apiCall);
export const customDetectionRules = {
createRule: { url: 'cloud-detection/rules', method: HttpMethod.POST },
deleteRule: { url: 'cloud-detection/rules', method: HttpMethod.DELETE },
getRules: { url: 'cloud-detection/rules?limit=100', method: HttpMethod.GET }
};
async delete(filter: DeleteRulesRequest, data: object = {}): Promise<SDKRespond> {
try {
return await this.makeApiCall(this.endPoints.deleteRule, { filter, data });
} catch (e) {
throw e;
}
}
export interface CustomDetectionRulesRequest {
name: string;
description: string;
severity: DetectionRuleSeverityTypes;
expirationMode: DetectionRulesExpirationModes;
s1ql: string;
queryType: DetectionRulesQueryTypes;
status: DetectionRuleStatuses;
expiration?: Date | string;
networkQuarantine: boolean;
treatAsThreat?: TreatAsThreatTypes;
}
Generated using TypeDoc