Component Evaluation REST APIs - v2

The Component Evaluation REST API allows for a single component, or multiple components, to be evaluated against a specific application and the associated policies.

This API uses the following REST resources:

  • POST - to submit a component or list of components, as well as the application containing the polices the component(s) will be evaluated against.
  • GET - to check the status of the evaluation and retrieve the results when completed.

For the API we provide a step-by-step example using the HTTP client cURL, though any HTTP client tool could be used. In addition we’ll reference other APIs such as the one required to obtain an application’s internal ID.

Step 1 - Get Component Information

First, you need to decide which components you want to evaluate. You’ll need a bit of component information in the form of the GAVE (Group, Artifact, Version, and Extension) or the hash for each component you wish to evaluate.

There are a variety of ways to get the GAVE, the most common is to get the information from the repository that houses the component. For example, The Central Repository has the GAVE for all components stored there.

If you wish to use the hash, Sonatype uses sha1 for all components it processes.

Only components known to Sonatype will provide security, license, and popularity data related to policies. However, depending on the policies for the application you choose to evaluate the component against, other policy conditions, such as match state, will help in determining if the component is known to your instance of the IQ Server.

Step 2 - Get the Application ID

Next, you will need pick the application you want to evaluate your component against. This begins with obtaining the application’s public ID, which is used to retrieve the internal application ID.

The public ID can be found via the IQ Server GUI by navigating to the respective application and copying the application ID, which is located just below the application name.

This is done using the following GET REST resource from our application API:

GET /api/v2/applications?publicId={YourPublicId}

Using the cURL command, it would look like this:

curl -u admin:admin123 -X GET 'http://localhost:8070/api/v2/applications?publicId=MyApplicationID'

If you like, you can also return multiple applications by appending additional &publicId={SomeOtherPublicId} to the command above. Alternatively, if desired, all applications can always be returned by omitting the reference to the public id. This will give the public ID and internal application ID for all applications.

information will be returned (unique to your application). This has been formatted for readability:

{
    "applications": [
        {
            "id": "4537e6fe68c24dd5ac83efd97d4fc2f4",
            "publicId": "MyApplicationID",
            "name": "MyApplication",
            "organizationId": "bb41817bd3e2403a8a52fe8bcd8fe25a",
            "contactUserName": "NewAppContact",
            "applicationTags": [
                {
                    "id": "9beee80c6fc148dfa51e8b0359ee4d4e",
                    "tagId": "cfea8fa79df64283bd64e5b6b624ba48",
                    "applicationId": "4bb67dcfc86344e3a483832f8c496419"
                }
            ]
        }
    ]
}

From the information returned above, make note of the id. This is the internal application ID.

Step 3 - Submit Component for Evaluation

Alright, by now you should have either the GAVE or hash for your component, as well as the internal application ID. We’ll put this information together using the POST REST resource:

POST /api/v2/evaluation/applications/{applicationInternalId}

Added to this will be a JSON formatted body:

{
"components": 
  [
    {
      "hash": null,
      "componentIdentifier": {
        "format": "maven",
        "coordinates": {
          "artifactId": "commons-fileupload",
          "groupId": "commons-fileupload",
          "version": "1.2.2",
          "extension": "jar"      
        }
      }
    }
  ]
}


If desired, multiple components can be included, but remember, the extension is required when entering components by GAVE.

Together, this should look like this:

curl -u admin:admin123 -X POST -H "Content-Type: application/json" -d '{"components": [{"hash": null,"componentIdentifier": {"format": "maven","coordinates": {"artifactId": "commons-fileupload","groupId": "commons-fileupload","version": "1.2.2","extension":"jar"}}}]}' 'http://localhost:8070/api/v2/evaluation/applications/529b7f71bb714eca8955e5d66687ae2c'

A successful POST will result in JSON formatted data providing a confirmation that the evaluation was submitted.

{
   "resultId": "917e0c5e92a646a5b8879a40890078bc",
   "submittedDate": "2015-02-02T10:43:22.975-05:00",
   "applicationId": "529b7f71bb714eca8955e5d66687ae2c",
   "resultsUrl": "api/v2/evaluation/applications/529b7f71bb714eca8955e5d66687ae2c/results/917e0c5e92a646a5b8879a40890078bc"
}

Be sure to make note of resultID and "applicationID". These will be used to to check and retrieve results. If you are following along with cURL, you can simply copy the resultsURL.

Package URL example NEW IN RELEASE 67

As of release 67 we are now supporting purl as a means to represent the GAV (in addition to component identifier).

Let's look at the same example with the packageUrl parameter instead of componentIdentifier or hash. The JSON formatted body will now be:

{
"components": 
  [
    {
      "packageUrl": "pkg:maven/commmons-fileupload/commons-fileupload@1.2.2?type=jar"
    }
  ]
}

Together, this will look like:

curl -u admin:admin123 -X POST -H "Content-Type: application/json" -d '{"components": [{"packageUrl": "pkg:maven/commmons-fileupload/commons-fileupload@1.2.2?type=jar"}]}' 'http://localhost:8070/api/v2/evaluation/applications/529b7f71bb714eca8955e5d66687ae2c'

A successful POST will result in the same JSON formatted confirmation when submitted using the componentIdentifier.

Step 4 Get Evaluation Results

Now, depending on how many components you evaluated, the IQ Server may need some time to process them. You can check the status and obtain results using the following GET REST Resource:

GET /api/v2/evaluation/applications/{applicationInternalId}/results/{resultId}

In our example, we’re going to use the resultsURL and as before, cURL:

curl -u admin:admin123 -X GET 'http://localhost:8070/api/v2/evaluation/applications/529b7f71bb714eca8955e5d66687ae2c/results/917e0c5e92a646a5b8879a40890078bc'

If the report is ready, you will receive results similar to these below:


NEW IN RELEASE 67

The response field "packageUrl" is available from release 67.

If the report is not ready, you will receive a (404) error.

{
   "submittedDate": "2015-02-13T18:01:42.082-05:00",
   "evaluationDate": "2015-02-13T18:01:42.084-05:00",
   "applicationId": "529b7f71bb714eca8955e5d66687ae2c",
   "results": [
      {
         "component":{
            "hash": null,
            "packageUrl": "pkg:maven/commons-fileupload/commons-fileupload@1.2.2?type=jar",
            "componentIdentifier": {
               "format": "maven",
               "coordinates": {
                  "artifactId": "commons-fileupload",
                  "extension": "jar",
                  "groupId": "commons-fileupload",
                  "version": "1.2.2"
               }
            },
            "proprietary": false
         },
         "matchState": "exact",
         "catalogDate": "2010-07-29T16:41:12.000-04:00",
         "licenseData": {
            "declaredLicenses": [
               {
                  "licenseId": "Apache-2.0",
                  "licenseName": "Apache-2.0"
               }
            ],
            "observedLicenses": [
               {
                  "licenseId": "Apache-2.0",
                  "licenseName": "Apache-2.0"
               }
            ],
            "overriddenLicenses": [

            ],
            "status": "Open"
         },
         "securityData": {
            "securityIssues": [
               {
                  "source": "cve",
                  "reference": "CVE-2013-2186",
                  "severity": 7.5,
                  "status": "Open",
                  "url": "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2186",
                  "threatCategory": "critical"
               },
               {
                  "source": "osvdb",
                  "reference": "98703",
                  "severity": 7.5,
                  "status": "Open",
                  "url": "http://osvdb.org/98703",
                  "threatCategory": "critical"
               },
               {
                  "source": "cve",
                  "reference": "CVE-2014-0050",
                  "severity": 5.0,
                  "status": "Open",
                  "url": "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0050",
                  "threatCategory": "severe"
               },
               {
                  "source": "osvdb",
                  "reference": "102945",
                  "severity": 5.0,
                  "status": "Open",
                  "url": "http://osvdb.org/102945",
                  "threatCategory": "severe"
               }
            ]
         },
         "policyData": {
            "policyViolations": [
               {
                  "policyId": "0ccc3321662d491c86b32554ea84e4e9",
                  "policyName": "Security-High",
                  "threatLevel": 9,
                  "constraintViolations": [
                     {
                        "constraintId": "d2dfc91f3bf4460ba0da3f7201e4adb7",
                        "constraintName": "CVSS >=7 and <10",
                        "reasons": [
                           {
                              "reason": "Found 2 Security Vulnerabilities with Severity >= 7"
                           },
                           {
                              "reason": "Found 4 Security Vulnerabilities with Severity < 10"
                           },
                           {
                              "reason": "Found 4 Security Vulnerabilities with Status OPEN"
                           }
                        ]
                     }
                  ]
               },
               {
                  "policyId": "0f1b57e6788c4e9bb0f65cde3b6e9f1c",
                  "policyName": "Security-Medium",
                  "threatLevel": 7,
                  "constraintViolations": [
                     {
                        "constraintId": "12a71811de694876b51e4c06c10bad76",
                        "constraintName": "CVSS >=4 and <7",
                        "reasons": [
                           {
                              "reason": "Found 4 Security Vulnerabilities with Severity >= 4"
                           },
                           {
                              "reason": "Found 2 Security Vulnerabilities with Severity < 7"
                           },
                           {
                              "reason": "Found 4 Security Vulnerabilities with Status OPEN"
                           }
                        ]
                     }
                  ]
               }
            ]
         }
      }
   ],
   "isError": false,
   "errorMessage": null
}

The last bit of information indicates if there were any errors encountered during the evaluation. In this example, there were no errors.