Heimdall API Documentation - mitre/heimdall2 GitHub Wiki

Heimdall API Capabilities

The Heimdall Application Programming Interface (API) provides the following Representational State Transfer (REST) and Create, Read, Update, and Delete (CRUD) operations:

Important

  • To use any available CRUD capabilities provided by Heimdall, the environment variable API_KEY_SECRET must be set (see Environment Variable Configurations).
  • To create a secret to be used with the API_KEY_SECRET run: openssl rand -hex 33 then assign the value to the variable in the .env configuration file:
    • API_KEY_SECRET=91f82f...082fee

Upload evaluations scans via cURL

Heimdall enables data exchange between a device and the server through a terminal utilizing the client URL (cURL) command line using Users or Groups API Keys.

API cURL format to upload (POST) an evaluation to Heimdall:

curl -F "data=@<Path to Evaluation File>" \
-F "filename=<Filename To Show in Heimdall>" \
-F "public=true/false" \
-F "evaluationTags=<tag-name>,<another-tag-name>..." \
-H "Authorization: Api-Key apikeygoeshere" "http://localhost:3000/evaluations"

NOTE: cURL flags

  • The -F makes curl POST data using the Content-Type multipart/form-data
  • The @ makes a file get attached in the post as a file upload
  • The -H is used add the authorization to the regular request headers
Flag Description
-F "data=@ ..." File(s) to be uploaded
-F "filename= ..." File display name (single file upload)
(multiple files uploads use the local filename)
-F "public=true/false" Set the scan visibility
-F "evaluationTags= ..." Set Tag(s) associated with this scan
-H "Authorization: Api-Key ..." API Key value

API cURL format to upload (POST) multiple files at once (up to 100) to Heimdall:

curl -F "data=@<Path to first evaluation File>" \
-F "data=@<Path to second evaluation File>" ... \
-F "public=true/false" \
-F "evaluationTags=<tag-name>,<another-tag-name>..." \
-H "Authorization: Api-Key apikeygoeshere" "http://localhost:3000/evaluations"

top

Retrieve Evaluations from Heimdall

The Heimdall API supports the capability of retrieving results information previously uploaded to the Heimdall server. Evaluations are retrieved for a single user or for a group. Two options are available:

Important

  • Retrieving a single evaluation returns all data content, where retrieving all evaluations only returns the evaluation metadata

Find by ID

To obtain the data from a specific scan and additional metadata from Heimdall Server accessible to a user or group, use the appropriate API key. If the key does not have permissions to access a particular scan (the scan is not affiliated with the user/group making the request), a 403 Forbidden status will be returned.

API cURL format for retrieving a specific evaluation ID:

curl -X GET \
  -H "Authorization: Api-Key apikeyhere" \
  "<heimdall url>:<port>/evaluations/<ID#>"  
Flag/Parameter Description
-X GET Explicitly specify HTTP GET
-H "Authorization: Api-Key ..." API Key value
<heimdall url> The URL that Heimdall Server is deployed
<port> The port Heimdall Server is listening on
<ID#> The unique ID number of the evaluation to retrieve

API cURL example:

curl -X GET \
  -H "Authorization: Api-Key eyJhbGc...E-4QtA" \
  "localhost:3000/evaluations/1"  

Returns

{
    "id": "1",
    "filename": "test1",
    "data": // all data from the InSpec scan
    {
        "platform":
        {
        },
        "profiles":
        [
            {
            }
        ],
        "statistics":
        {
        },
        "version": "..."
    },
    "evaluationTags": // tag(s) assigned to scan
    [
        {
            "id": "1",
            "value": "tag1",
            "evaluationId": "1",
            "createdAt": "...",
            "updatedAt": "..."
        }
    ],
    "groups": // group(s) this scan belongs to
    [],
    "userId": "1",
    "groupId": null,
    "public": false,
    "createdAt": "...",
    "updatedAt": "...",
    "editable": true
}

top

Find All

Unlike Find by ID # which returns all data associated with a particular scan ID, the Find All returns the metadata of scans (within the provided query parameters - offset and limit) belonging to the provided user or group API key provided. The returned data is limited by URL query parameters (see table below for details)

API cURL format for retrieving all (see offset/limit) evaluations for a given user or group:

curl -X GET \
  -H "Authorization: Api-Key apikeyhere" \
  "<heimdall url>:<port>/evaluations?offset=0&limit=10&order\[\]=createdAt&order\[\]=DESC"  
Flag/Parameter Description
-X GET Explicitly specify HTTP GET
-H "Authorization: Api-Key ..." API Key value
<heimdall url> The URL that Heimdall Server is deployed
<port> The port Heimdall Server is listening on
offset Used to exclude from the response the first N items of a resource collection
(0 means start from the first record, 10, would mean start from the 10 record)
limit Specifies the number of scans that a single response page contains
(how many records are returned)
order order is an array (2 or 3 indices) query string parameter
As such it has the following format:
order\[\]=<value>&order\[\]=<value>... (note brackets [ ] need to be escaped on some platforms)
Available sort order fields are: createdAt, filename, groups, and evaluationTags)

When sorting by createdAt, filename fields use this format:
order\[\]=createdAt&order\[\]=[ASC or DESC]

When sorting by groups field use this format:
order\[\]=groups&order\[\]=name&order\[\]=[ASC or DESC}

When sorting by evaluationTags field use this format:
order\[\]=evaluationTags&order\[\]=value&order\[\]=[ASC or DESC}

NOTE: The URL query parameters are separated by the charact &

API cURL example:

curl -X GET \
  -H "Authorization: Api-Key eyJhbGc...E-4QtA" \
  "localhost:3000/evaluations?offset=0&limit=10&order\[\]=createdAt&order\[\]=DESC"  

Returns

{
    "evaluations": // this particular user has 2 scans stored
    [
        {
            "id": "2",
            "filename": "test2",
            "evaluationTags":
            [
                {
                    "id": "2",
                    "value": "tag2",
                    "evaluationId": "2",
                    "createdAt": "...",
                    "updatedAt": "..."
                }
            ],
            "groups":
            [],
            "userId": "1",
            "groupId": null,
            "public": false,
            "createdAt": "...",
            "updatedAt": "...",
            "editable": true
        },
        {
            "id": "1",
            "filename": "test1",
            "evaluationTags":
            [
                {
                    "id": "1",
                    "value": "tag1",
                    "evaluationId": "1",
                    "createdAt": "...",
                    "updatedAt": "..."
                }
            ],
            "groups":
            [],
            "userId": "1",
            "groupId": null,
            "public": false,
            "createdAt": "...",
            "updatedAt": "...",
            "editable": true
        }
    ],
    "totalCount": 2
}

Filtering can be used on this API endpoint to restrict return values. Filtering can be applied to these fields: file, group, and/or tag name The additional query parameters for filtering are:

Filtering Query Parameters Description
useClause Must be set to true (useClause=true)
operator The operation logic: OR or AND (operator=OR)
searchFields The searchFields is an array variable that represents file, group, and tag name
The first index is used for filename searchFields[]=(rhel_8)
The second index is used for group name searchFields[]=(myGroup)
The third index is used for tag name searchFields[]=(rhel8)

Multiple entries can be provided to each searchFields delimited by a vertical bar |
The text provided doesn't need to be exact, partial match supported

API cURL example filtering on scans containing filename rhel_8 or group name myGroup or tag name rhel8:

curl -X GET \
  -H "Authorization: Api-Key eyJhbGc...E-4QtA" \
  "localhost:3000/evaluations?offset=0&limit=10&order[]=createdAt&order[]=DESC&useClause=true&operator=OR&searchFields[]=(rhel_8)&searchFields[]=(myGroup)&searchFields[]=(rhel8)"

top

Programmatic API Key Generation

In order to generate an API key for a user programmatically, you must create a login session for either the admin account or the account of the user for which you wish to create an API key.

Login via API

curl '<your-heimdall-instance>:<PORT>/authn/login' \
  -H 'Content-Type: application/json' \
  --data-raw '{"email":"<email>","password":"<password>"}'

Tip

  • If you are running Heimdall via a local Docker deployment, you may not need a PORT, given that it is likely running on standard 443 or 80.
  • Add -k to ignore SSL certificate validation. This is unsafe. Do not use in production.
  • If your login is handled through a third party authentication service, you must complete the third party login flow programmatically or insert a user record into the database containing the email address of the user for which you wish to create the API key

The server returns a live JWT access token in response

{
	"userID": "1",
	"accessToken": "eyJhbGc...rqA3Zo"
}

The access token is used to issue an API key

NOTE: Use the returned accessToken for the -H 'Authorization: Bearer <accessToken>'

Issue an API key utilizing user identification (userID), the one returned by the login API call use:

curl 'http://localhost:8080/apikeys' \
  -H 'Authorization: Bearer eyJhbGc...rqA3Zo' \
  -H 'Content-Type: application/json' \
  --data-raw '{"userId":"<User ID>","currentPassword":"<Password>"}' \
  --compressed

Issue an API key utilizing the user email used for the login API call

curl 'http://localhost:8080/apikeys' \
  -H 'Authorization: Bearer eyJhbGc...rqA3Zo' \
  -H 'Content-Type: application/json' \
  --data-raw '{"userEmail":"<User Email>","currentPassword":"<Password>"}' \
  --compressed

The server will respond with the newly generated API key

{
	"id": "3", // This is the ID of the API key
	"name": null,
	"apiKey": "eyJhbGciOi...kPrGBVDOU"
}

top

How to Generate API Keys for Groups

Heimdall provides the ability for groups to have API key(s) that can be used to communicate with the application via the CLI.

To add an API key to a group, select "My Groups" from the user menu:


Select the "Edit" pencil icon to open the "Update Groups" dialog window:

On the "Update Groups" dialog window, click on "Manage API KEYS" link to open the "Group API Keys" dialog window:

The "Group API Keys" dialog window allows the user to do the following:
  • Add an API Key to the group
  • Regenerate an new API Key (if the old one is lost or compromised)
  • Delete an API Key

NOTE: To create a new API Key users must provide their password


Once the Add API Key is clicked a new API Key is generated. Provide a name for the key, copy and store the key value.

top

⚠️ **GitHub.com Fallback** ⚠️