This is an isomorphic javascript client library for accessing the Hardenize Org API
Although it is isomorphic, you will almost always only want to use it from inside NodeJS. That is because if you use it from a web browser, you will expose your Hardenize API credentials, which you MUST keep secret.
$ npm i @hardenize/api
Or:
$ git clone https://github.com/hardenize/hardenize-api
If you are targetting the browser and do not have a build pipeline using something like webpack or browserify,
you can grab a copy of static.js
from the root of the git repository, place it on your website somewhere
and then include it using a script tag. This will expose window.HardenizeApi
If you are targetting old web browsers, ensure that fetch
and Promise
are polyfilled as this lib expects
them to exist.
import HardenizeApi from '@hardenize/api';
const api = new HardenizeApi({
user: 'your_api_username',
pass: 'your_api_password',
org: 'your_org_label',
});
Once you have an api object, you can call a number of methods on it. Each one of them will return a Promise
.
Failed API calls are rejected with an Error
object containing the error message. It MAY also include a res
HTTP Response object also if the call got as far as making a HTTP request and receiving a HTTP response.
Successful API calls are resolved with an object containing both a fetchResults
function and a pages
number. pages
is the number of pages of results that can be retrieved, and exists due to pagination. When you call fetchResults
it returns a Promise which resolves to an object containing data
and res
, where data is the API response body, and res
is the HTTP Response object. res
exists, so that you can do things like checking the HTTP response status code. You can call fetchResults
with no arguments, to retrieve all results, or with a startPage and endPage number to only fetch a subset of the results. E.g:
(async () => {
try {
const response = await api.someApiCall(...someArgs);
const { data, res } = await response.fetchResults(1, response.pages);
const { data, res } = await response.fetchResults(); // Same as the above call
} catch(err) {
if (err.res) console.warn(`API Response Status: ${err.res.status} ${err.res.statusText}`);
console.warn(err.message)
}
})();
The above example uses async
, await
and appropriate error handling. The remainder of the examples
in this documentation will drop suitable error handling and ignore the async
wrapper, for brevity.
Not all of the Hardenize API end-points are async, or paginated, but this simple interface applies to all of the methods in this javascript library, so you don't have to differentiate.
For tracing/debugging, it can sometimes be useful to track all API requests sent and responses received. You can add listeners for these events on a HardenizeAPI object. Your callback will be passed a Request or Response object as an argument. Examples:
const api = new HardenizeApi({ ...options });
const onRequest = req => console.log("Sending API request", req);
const onResponse = res => console.log("Received API response", res);
const onResponseBody = body => console.log("Received API response body", body);
api.addEventListener('request', onRequest);
api.addEventListener('response', onResponse);
api.addEventListener('body', onResponseBody);
// Or:
api.on('request', onRequest);
api.on('response', onResponse);
api.on('body', onResponseBody);
To remove the event listeners:
api.removeEventListener('request', onRequest);
api.removeEventListener('response', onResponse);
api.removeEventListener('body', onResponseBody);
// Or:
api.off('request', onRequest);
api.off('response', onResponse);
api.off('body', onResponseBody);
If you want to remove all of the event listeners of a particular type, just don't pass the callback function argument:
api.removeEventListener('request');
api.removeEventListener('response');
api.removeEventListener('body');
// Or:
api.off('request');
api.off('response');
api.off('body');
Returns the api version string. Can also be called as a class function. E.g:
import HardenizeApi from '@hardenize/api';
const api = new HardenizeApi({ config });
HardenizeApi.version() === api.version();
Allows you to view or change configuration on an existing API object. Examples:
api.config(); // View all config
api.config('user'); // View just config.user
api.config('user', 'foo'); // Change user to foo
api.config('user', null); // Delete user from config
api.config({ pass: 'foo', org: null }); // Change pass to foo and delete org
See https://www.hardenize.com/docs/api/v1/#list-certificates
Example. Fetch all active certificates that have not yet expired, but will expire within the next 30 days.
const { data: { certs } } = await api.getCerts({ active: true, expired: false, expireInDays: 30 })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#retrieve-certificate
Example. Fetch a certificate with a particular SHA256.
const { data: { cert } } = await api.getCert('3c8031d6af1dc0a557381318692f0d4ecb74508e2116d489fec9dcc16a0f1552')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-certificate
Example. Create a certificate with a particular PEM
const { res, data: { sha256 } } = await api.createCert('some pem content')
.then(response => response.fetchResults());
switch (res.status) {
case 201: console.log('Certificate created', sha256); break;
case 202: console.log('Certificate already existed', sha256); break;
default: // Should not get as far as this
}
See https://www.hardenize.com/docs/api/v1/#update-certificate
Example. Mute a certificate
const { res, data: { cert } } = await api.updateCert(sha256, { muted: true })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#get-access-control-configuration
Example. Fetch access control config.
const { data: config } = await api.getAccessControlConfig()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-access-control-configuration
Example. Change the appNetworks config, leaving the apiNetworks config as it is.
const { data: newConfig } = await api.updateAccessControlConfig({
appNetworks: ["127.0.0.0/8"],
appNetworksCascade: "enabled",
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#get-network-scanning-configuration
Example. Fetch network scanning configuration
const { data: config } = await api.getNetworkScanningConfig()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-network-scanning-configuration
Example. Disable dynamic network scanning
const { data: newConfig } = await api.updateNetworkScanningConfig({
netscanDynamic: false,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#get-mfa-configuration
Example. Fetch multi-factor-authentication config.
const { data: config } = await api.getMfaConfig()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-mfa-configuration
Example. Force the use of multi-factor-authentication
const { data: newConfig } = await api.updateMfaConfig({
mfaRequired: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#get-saml-configuration
Example. Fetch saml config.
const { data: config } = await api.getSamlConfig()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-saml-configuration
Example. Enable SAML
const { data: newConfig } = await api.updateSamlConfig({
enabled: true,
idpMetadata,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#upload-dns-zone
Example. Create a dns zone for "example.com"
const zoneBody = `$ORIGIN example.com.
$TTL 1h
@ IN SOA ns.example.com. admin.example.com. ( 2018081601 1d 2h 4w 1h )
@ IN NS ns
@ IN MX 10 mx.example.com.
@ IN A 192.0.2.1
IN AAAA 2001:db8:10::1
ns IN A 192.0.2.2
IN AAAA 2001:db8:10::2
www IN CNAME example.com.
mx IN A 192.0.2.3`;
await api.createDnsZone('example.com', zoneBody)
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-groups
Fetch a list of groups.
const { data: { groups } } = await api.getGroups()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-group
Create a new group
await api.createGroup('Group Name', { auto: true, tags: ['tag1', 'tag2'] })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#delete-group
Delete a group
await api.deleteGroup('groupid')
.then(response => response.fetchResults());
This will fail if the group is in use. If you want to force removal even if the group is in use,
pass an additional object with force
set to true:
await api.deleteGroup('groupid', { force: true })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-hosts
Fetch a list of hosts
const { data: { hosts } } = await api.getHosts()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#retrieve-host
Fetch details about a host
const { data: { host } } = await api.getHost('example.com')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-hosts
Create new hosts
await api.createHosts([ 'example.com', 'example.org' ], {
status: 'monitored',
groups: ['Production'],
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-hosts
Update hosts.
Example: Update example.com, example.org and all hosts that are subdomains of those two hostnames. Set their statuses to 'idle', and add a group named "New" to each of them.
await api.updateHosts([ 'example.com', 'example.org' ], {
status: 'idle',
groups: ['New'],
groupOp: 'add',
}, {
subdomains: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#delete-hosts
Delete hosts
await api.deleteHosts([ 'example.com', 'example.org' ], { subdomains: true })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-host-discoveries
Gets a list of host discoveries.
Example: Fetch keyword related pending discoveries.
const { data: { hostDiscoveries } } = await api.getHostDiscoveries({
resolution: 'pending',
matchReason: 'keyword',
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#retrieve-host-discovery
Retrieves a host discovery, by ID. Id's can be seen in the results of calling getHostDiscoveries().
const { data: { hostDiscovery } } = await api.getHostDiscovery(id)
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-host-discovery
Updates an existing host discovery. Allows setting the triage resolution.
await api.updateHostDiscovery(id, {
resolution: 'own'
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-host-discoveries
Updates existing host discoveries. Allows setting the triage resolution. Supply the optional argument {"preview": true}, if you only want to see what would be changed.
await api.updateHostDiscoveries(ids, {
resolution: 'own',
}, {
preview: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#delete-host-discoveries
Deletes existing host discoveries. Supply the optional argument {"preview": true}, if you only want to see what would be deleted.
await api.deleteHostDiscoveries(ids, {
preview: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-host-discovery-keyword
Create a new host discovery keyword.
Example: Create a host discovery keyword of "hardenize", excluding matching hosts if they contain the substring "test".
await api.createHostDiscoveryKeyword('hardenize', {
keyword: 'hardenize',
exclusions: [ 'test' ]
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#delete-host-discovery-keyword
Delete a host discovery keyword.
await api.deleteHostDiscoveryKeyword('hardenize')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-host-discovery-keyword
Update an existing host discovery keyword.
Example: Enable confusables matching on the "hardenize" keyword.
await api.updateHostDiscoveryKeyword('hardenize', {
keyword: 'hardenize',
confusables: true
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-host-discovery-keywords
Gets the list of host discovery keywords.
const { data: { hostDiscoveryKeywords } } = await api.getHostDiscoveryKeywords()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#retrieve-host-discovery-keyword
Gets a host discovery keyword.
const { data: { hostDiscoveryKeyword } } = await api.getHostDiscoveryKeyword('hardenize')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-network-range
Create a new network range.
Example: Create a network range of "192.168.100.0/24" and enable scanning
await api.createNetworkRange('192.168.100.0/24', {
label: 'My Network Range',
description: 'A bunch of random hosts',
scan: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#delete-network-range
Delete a network range.
await api.deleteNetworkRange('192.168.100.0/24')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-network-ranges
Gets the list of network ranges.
const { data: { networkRanges } } = await api.getNetworkRanges()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-network-range
Update a network range.
Example: Disable scanning of "192.168.100.0/24"
await api.updateNetworkRange('192.168.100.0/24', {
scan: false,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-report-summaries
Fetch a list of reports.
Example: Fetch a list of reports for example.com
and it's subdomains. Only
include those with the production
group.
const { data: { reports } } = await api.getReports0({
name: 'example.com',
subdomains: true,
group: 'production'
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-organizations
Fetch a list of organizations.
Example:
const { data: { orgs } } = await api.getSubOrgs()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-organization
Create a sub organization to your account.
Example: Create an organization with an id of example
, a display name
of Example Ltd
. Set its initial status to dormant
, and generate api credentials for it.
const { data: { org } } = await api.createSubOrg('example', {
name: 'Example Ltd',
status: 'dormant',
generateApiCredentials: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-organization
Update an organization in your account.
Example: Update the status of an organization to active
and regenerate it's API credentials
const { data: { org } } = await api.updateSubOrg('example', {
status: 'active',
generateApiCredentials: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#delete-organization
Delete an organization from your account.
Example:
await api.deleteSubOrg('example')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-event-types
Fetch a list of event types
Example:
await api.getEventTypes()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-event-type
Update an event type.
Example: Disabling the "example.type" event type:
await api.updateEventType('example.type', { enabled: false })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-events
Get a list of events.
Example: Fetch a list of events (up to a max of 3), that have occured since a particular date/time, for a particular type only.
await api.getEvents({ type: 'example.type', since: '2018-06-20T12:05:12.123456Z', limit: 3 })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#get-event
Example:
await api.getEvent(5)
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-event-hook
Create an event hook.
Example:
const { data: { eventHook } } = await api.createEventHook({
hookType: 'webhook',
eventTypes: ['ct.entry'],
destination: 'https://www.example.com/webhooks/receive',
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#delete-event-hook
Delete an event hook.
Example:
await api.deleteEventHook('24673847d5cb283205568e34f8855ba2')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-event-hooks
Get a list of your event hooks.
Example:
const { data: { eventHooks } } = await api.getEventHooks()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-event-destinations
Get a list of your event hook destinations.
Example:
const { data: { eventDestinations } } = await api.getEventHookDestinations()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#test-event-hook
Test an event hook.
Example: Test with an invalid signature
const result = await api.testEventHook('24673847d5cb283205568e34f8855ba2', { invalid: 'signature' })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-event-hook
Update an event hook.
Example: Set the status to enabled
const { data: { eventHook } } = await api.updateEventHook('24673847d5cb283205568e34f8855ba2', { status: 'enabled' })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#list-users
Get users
Example:
const { data: { users } } = await api.getUsers()
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#get-user
Get user
Example: Get user id 1.
const { data: { user } } = await api.getUser(1)
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#invite-new-user
Invite a new user to the org
Example:
const { data: { user } } = await api.inviteUser({
name: 'Bob',
email: 'bob@example.com',
role: 'observer'
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#cancel-invite
Cancel a user invitation
Example: Cancel invite for user id 1
await api.cancelUserInvite(1)
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#create-service-account
Create a new service account
Example:
const { data: { user } } = await api.createServiceAccount({
name: 'Test Service Account',
role: 'observer'
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#update-user
Update user.
Example: Disable MFA for user id 1.
await api.updateUser(1, { deleteMfa: true })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#search-hdb-certs-by-sha256
Example: Fetch a cert, including the unpacked data.
const { data: { cert } } = await api.getHdbCertBySha256(sha256, { unpacked: true })
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#search-hdb-certs-by-host-suffix
Example: Fetch certs containing hardenize.com or a subdomain thereof. Include raw PEM in results.
const { data: { certs } } = await api.getHdbCertsByHostSuffix('hardenize.com', {
exact: true,
subdomains: true,
pem: true,
}).then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#search-hdb-certs-by-keyword
Example: Fetch certs containing the keyword "hardenize".
const { data: { certs } } = await api.getHdbCertsByKeyword('hardenize')
.then(response => response.fetchResults());
See https://www.hardenize.com/docs/api/v1/#search-hdb-certs-by-spki
Example: Fetch certs with a specific SPKI.
const { data: { certs } } = await api.getHdbCertBySpki(spki)
.then(response => response.fetchResults());
If you are a core developer of this library (you almost certainly aren't, unless you work for Hardenize Limited), you should check out ./DEVELOPMENT.md