Asset V2 Integration Guide#

Warning

This integration guide targets the V2 of the Asset API, which replaces the deprecated V1 API.

This guide is meant as a reference during testing and integration with the new API.

Detailed API documentation#

The Swagger API documentation is always up-to-date and lets you try out any query with your user session or an API-key.

Tip

Please read the General integration guide to learn the general concepts and common data structures used throughout the Argus API.

Integration Guide#

Note

The Asset service’s data model is highly interconnected. Make sure to get a decent understanding of the interdependencies before reading the rest of this guide.

Creating Assets#

To create an asset you need to specify the shortName, name, criticality triad, and asset definition. The asset definition describes what components we can eventually attach to the asset and must already exist. The optional forceIndex (default=false) option when creating, updating, and deleting resources in the Asset service determines whether any changes are immediately pushed to the search index i.e. making the changes immediately searchable.

curl -X POST -H "Argus-API-Key: my/api/key" -H "Content-Type: application/json" https://api.mnemonic.no/assets/v2/asset -d '{
    "customer": "mnemonic",
    "shortName": "a1",
    "name": "asset1",
    "criticality": {
        "confidentiality": "low",
        "integrity": "high",
        "availability": "unknown"
    },
    "assetDefinition": "ad1"
}'

Data Model

All endpoints for fetching, searching/listing, updating and deleting assets return the same data model.

See >Swagger API documentation for details on the returned data model.

Fetching Assets#

Fetching a single Asset is simply done by using the Asset ID or its shortName

curl -H "Argus-API-Key: my/api/key" https://api.mnemonic.no/assets/v2/asset/assetIdOrShortName

If successful, the above invocation will return the Asset basic model:

{
  "data": {
    "id": "0005cd25-2be2-44fa-a260-b0f735c9797a",
    "customer": { "id":1, "shortName":"mnemonic", ...},
    "shortName":"a1",
    "name":"asset1",
    "description":"This is the description for this asset",
    "assetDefinition": {
        "id": "00000000-0000-0000-0000-000000000001",
            "domain": {
                "id": 1,
                "name": "MNEMONIC"
            },
        "shortName": "HostAsset",
        "name": "HostAsset"
    },
    "components": [...],
    ...
  }
}

Updating Assets#

Updating the basic fields of an asset is done with a PUT request to the asset resource. Asset components can also be added, and removed, via this request.

If no parameters are provided, no changes are performed. Similarily, for any paramater sent to this endpoint, a null value will cause no change to the current value.

curl -X PUT -H "Argus-API-Key: my/api/key" -H "Content-Type: application/json" https://api.mnemonic.no/assets/v2/asset/assetIdOrShortName -d '{
    "criticality": {
        "confidentiality": "high",
        "integrity": "low",
        "availability": "high"
    },
    "addComponents": [
        {
            "componentDefinition": "cd1",
            "value": "componentValue",
            "ttl": 0
        }
    ],
    "deleteComponents": [
        "0005cd25-2be2-44fa-a260-b0f735c9797a",
        "0005cd25-2be2-44fa-a260-b0f735c9797a"
    ]
}'

Asset Components

Similar to Assets, Components are defined by an Asset Component Definition, which must exist and be listed in the specific Asset’s Definition

Searching for Assets#

Assets are searchable by their basic properties and their relationships with other resources in the Asset Service e.g. parent or ancestor group(s). All searches are restricted to assets belonging to customers for whom the current user has at least read permission.

curl -X POST -H "Argus-API-Key: my/api/key" -H "Content-Type: application/json" https://api.mnemonic.no/assets/v2/asset/search -d '{
    "sortBy": [
        "lastUpdatedTimestamp"
    ],
    "keywords": [
        "content"
    ],
    "keywordFieldStrategy": [
        "description"
    ]
    "parent": [
        "assetGroupShortName"
    ],
    ...
}'

Asset Statistics#

Warning

The Asset Statistics API is not completely stable i.e. new features are still under development. Please contact Mnemonic directly for clarification.

The Asset statistics endpoint allows a user to retrieve quantitative data about a set of assets that match certain search criteria.

The statistics request supports the same search criteria as the search endpoint; the statistics criteria then apply to the results of the search.

The statistics request itself is composed of 3 key components:

  • field aggregation - the field(s) by which we want to group the resulting assets and structure the response

  • range metrics - return counts for assets matching the defined timestamp filters

  • statistics metrics - return basic statistical data (min, max, median, avg, e.t.c) for asset numerical fields e.g. cvss or vulnerability count

For example we could ask for vulnerability statistics for assets created within the last month and also determine which of them have been updated during the same time period, aggregated by the types of assets and the groups to which they belong:

curl -X 'POST' \
  'https://api.mnemonic.no/assets/v2/asset/statistics' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Argus-API-Key: my/api/key' \
  -d '{
  "startTimestamp": "now-1month",
  "endTimestamp": "now",
  "timeFieldStrategy": [
    "createdTimestamp"
  ],
  "fieldAggregation": [
    {
      "field": "assetGroup",
      "limit": 25
    },
    {
      "field": "assetDefinition",
      "limit": 25
    }
  ],
  "rangeMetric": [
    {
      "name": "updatedThisWeek",
      "field": "lastUpdated",
      "startTimestamp": "now-1week",
      "endTimestamp": "now"
    }
  ],
  "statisticsMetric": [
    {
      "field": "vulnerabilities"
    }
  ],
  "includeDeleted": false
}'

The response’ structure is a simple tree where the branches represent unique field aggregation values i.e. in this example groups and definitions.

Each branch consists of the count of assets within the branch and metadata containing

  • identifier - the unique ID of the object

  • shortName - the unique human/machine readable identifier

  • name - the human readable non-unique identifier

  • type - the type (assetGroup or assetDefinition in this example) of the metadata

Each branch then potentially contains buckets, which represent the next layer in the tree.

The leaves contains the actual metrics response e.g.:

{
  "metadata": {
    "identifier": "assetGroupUUID",
    "shortName": "assetGroupShortName",
    "name": "Asset Group Name",
    "type": "assetGroup"
  },
  "count": 291,
  "buckets": [
    {
      "metadata": {
        "identifier": "00000000-0000-0000-0000-000000000001",
        "shortName": "HostAsset",
        "name": "Host Asset",
        "type": "assetDefinition"
      },
      "count": 291,
      "buckets": [
        
      ],
      "rangeMetrics": [
        {
          "key": "updatedThisWeek",
          "count": 1,
          "startTimestamp": 1681198844900,
          "endTimestamp": 1681803644900
        }
      ],
      "statisticsMetrics": [
        {
          "key": "vulnerabilities",
          "count": 291,
          "min": 0,
          "max": 441,
          "avg": 48.67697594501718,
          "sum": 14165
        }
      ]
    }
  ],
  "rangeMetrics": [
    
  ],
  "statisticsMetrics": [
    
  ]
}

Creating Asset Groups#

To create an asset you need to specify the shortName, name, and criticality triad.

curl -X POST -H "Argus-API-Key: my/api/key" -H "Content-Type: application/json" https://api.mnemonic.no/assets/v2/group -d '{
    "customer": "mnemonic",
    "shortName": "ag1",
    "name": "assetGroup1",
    "criticality": {
        "confidentiality": "low",
        "integrity": "high",
        "availability": "unknown"
    }
}'

Attaching Assets to a Group#

To add Assets to a Group simply submit their IDs or short names to the group’s attach endpoint.

curl -X POST -H "Argus-API-Key: my/api/key" -H "Content-Type: application/json" https://api.mnemonic.no/assets/v2/group/groupShortNameOrID/assets -d '{
        "assets": [
            "asset1",
            "asset2"
        ]
    }
}'

Searching for Groups#

Similar to Assets, Groups are searchable by their basic properties and by their relationships to other resources in the Asset Service. groups e.g. parent, ancestor, or child group(s) and member assets. All searches are restricted to groups belonging to customers for whom the current user has at least read permission.

curl -X POST -H "Argus-API-Key: my/api/key" -H "Content-Type: application/json" https://api.mnemonic.no/assets/v2/group/search -d '{
    "sortBy": [
        "lastUpdatedTimestamp"
    ],
    "keywords": [
        "content"
    ],
    "keywordFieldStrategy": [
        "description"
    ]
    "parent": [
        "assetGroupIDOrShortName"
    ],
    "asset": [
        "assetIdOrShortName"
    ],
    "child": [
        "assetGroupIDOrShortName"
    ]
    ...
}'

Creating Vulnerabilities#

To create a Vulnerability you need to specify the asset, by its UUID or shortname, on which the vulnerability was detected, its vulnerability definition, and CVSS value. If a severity is not specified, it will be assigned based on the submitted CVSS value. The optional forceIndex option (default=false) will instruct the service to refresh the search index such that new vulnerabilities are immediately searchable. Similar to Assets, Vulnerabilities can be created bound to specific components. The time to live (TTL) field determines how long the component information is considered valid. Ideally it should be longer than the scan interval so that component information is not invalidated before it can be updated. Please see the Swagger API for how the other fields are handled or determined if not provided.

Specify Customer

NB: If the request does not explicitly specify the Customer who owns the Asset on which the Vulnerability was detected and the Asset was defined by its short name then the service will attempt to resolve the Asset based on the requesting user’s Customer. As Asset shortNames are unique per customer it’s possible that this request might fail.

curl -X POST -H "Argus-API-Key: my/api/key" -H "accept: application/json" 
"https://api.mnemonic.no/assets/v2/vulnerability" -d '{
    "customer": "mnemonic",
    "asset": "internalAsset",
    "vulnerability": "vulnerabilityDefinition",
    "components": [
        {
            "componentDefinition": "cpeComponentDefinition",
            "value": "cpe:2.3:o:microsoft:windows:2008:r2",
            "ttl": 0
        }
    ],
    "cvss": 3,
    "severity": "low",
    "rawOutput": "output from scanner",
    "ttl": 0
}'

Fetching Vulnerabilities#

To fetch a single Vulnerability you need to provide its UUID:

curl -H "Argus-API-Key: my/api/key" https://api.mnemonic.no/assets/v2/vulnerability/53477c72-f4c8-4929-bc05-3a8c7d4ba7a2

A successful request will return the Vulnerability’s data model:

{
    "id": "53477c72-f4c8-4929-bc05-3a8c7d4ba7a2",
    "customer": {
        "id": 1,
        "name": "mnemonic",
        "shortName": "mnemonic",
        "domain": {
            "id": 1,
            "name": "MNEMONIC"
        }
    },
    "asset": {
        "id": "4cb3797b-35f6-4ca7-8102-46e8a3946829",
        "customer": {
            ...
        },
        "shortName": "GraphQLAsset_2",
        "name": "Asset 2 - Asset V2 Test"
    },
    "vulnerabilityID": "COVID-19",
    "vulnerabilityDefinition": null,
    "components": [],
    "cvss": 8.8,
    "severity": "high",
    "resolution": "unresolved",
    "resolutionTimestamp": 0,
    "resolvedByUser": null,
    "resolutionComment": null,
    "rawOutput": null,
    "firstSeenTimestamp": 1596539880803,
    "lastSeenTimestamp": 1596539880803,
    "firstSeenByUser": {
        "id": 8982,
        "shortName": "testUser",
        "name": "Test User",
        "domain": null,
        "customer": {
            ...
        },
        "type": "user"
    },
    "lastSeenByUser": {...},
    "ttl": 0,
    "expireTimestamp": 0,
    "createdTimestamp": 1596539880803,
    "createdByUser": {...},
    "lastUpdatedTimestamp": 1596539880803,
    "lastUpdatedByUser": {...},
    "deletedTimestamp": 0,
    "deletedByUser": null,
    "flags": []
}

Resolving Vulnerabilities#

To resolve a vulnerability simply submit a resolution request to the vulnerability’s resolution endpoint:

curl -X PUT -H "Argus-API-Key: my/api/key" "accept: application/json" -H "Content-Type: application/json" \
    "https://devapi.mnemonic.no/assets/v2/vulnerability/4cb3797b-35f6-4ca7-8102-46e8a3946829/resolve" -d \
    '{ 
        "resolution": "accepted",
        "comment": "cannot resolve now"
    }'

Searching for Vulnerabilities#

Vulnerability are searchable by their basic properties and their direct relationship with the asset on which they were detected. All searches are restricted to Vulnerabilities on Assets belonging to the customer(s) for whom the requesting user has permission to access. Unlike Asset and Asset Groups, Vulnerabilities currently have no keyword fields. Only exact matches will return results.

{
    "sortBy": [
        "vulnerabilityID"
    ],
    "startTimestamp": 0,
    "endTimestamp": 0,
    "timeFieldStrategy": [
        "all"
    ],
    "timeMatchStrategy": "any",
    "userFieldStrategy": [
        "lastUpdatedByUser"
    ],
    "user": [
        "testUser"
    ],
    "asset": [
        "myVeryImportantAsset"
    ],
    "customer": [
        "mnemomnic"
    ],
    "severity": "info",
    "resolution": "unresolved",
    "minimumCvss": 1,
    "maximumCvss": 2,
    "includeRawOutput": false,
    "limit": 0,
    "offset": 0,
    "includeDeleted": false
}

Sort By Severity#

Note

Sort by severity will sort Vulnerabilities by Severity’s natural order i.e. info, low, medium, high, critical

To, for example, retrieve all open Vulnerabilities created on Assets belong to a particular Customer for the last week you could submit the following query:

{
    "sortBy": [
        "createdTimestamp"
    ],
    "customer": [
        "customerIdOrShortName"
    ],
    "resolution": "unresolved",
    "startTimestamp": "startOfWeek - 1 week",
    "endTimestamp": "startOfWeek"
}