API Quickstart
This is a good place to get started if you haven't used Polaris APIs before.
You will need the following.
- Polaris sign-in credentials.
- Access to a project where at least one test has finished. (If it is the first test on your project, keep in mind that the first test can take longer than usual to complete, because there are steps to verify that the test ran properly. Your subscription may call for triage on the first test, which also can make the test take longer.)
This quickstart will walk you through a set of steps to get the issue data from a recent test and examine some security vulnerabilities found in the results. Retrieving issue data is the most common use of Polaris APIs.
These steps won't necessarily be the exact steps you use later when scripting API calls. If you already have some of the things that these steps retrieve, like portfolio ID and application ID, you won't need to retrieve them, and you can get your issue data more quickly. For this quickstart, we'll assume that you don't have that information and we'll help you get it from scratch. This takes a few more steps, but it's useful to know how and the process demonstrates how everything fits together in Polaris.
-
Make an access token.
Note: Access tokens expire if unused for 30 days.
- In Polaris, click your profile name, then select Account.
- Click Access Tokens.
-
Click Create New Token.
-
Enter a name for the token (limit is 255 characters) and click
Save.
-
Copy the token and store it in a safe place.
Note: You only get one chance to copy the token. If it is lost, you won't be able to copy it again, but you can make a new one.Note: The API reference docs in this portal are interactive. With an access token, you can use the API reference docs to generate requests that interact with your applications and projects. After you open a service's reference docs, click the Authorize button. Enter your token in the Value field and select Authorize. Enter the token separately for each service you use and sign out of the service when finished.
-
Get your portfolio ID.
Purpose: The portfolio ID is needed in a subsequent step.
Request:
curl --location --request GET "https://polaris.blackduck.com/api/portfolio/portfolios" \ --header 'Accept: application/vnd.pm.portfolio-1+json' \ --header 'Api-token: {token}'
About this request:
- Note the Api-Token header. This is required for every call to Polaris APIs, although the Swagger reference docs don't append it automatically when they generate an example. In all these calls we replace the web token with a placeholder in curly brackets.
- For this operation, Polaris can retrieve the portfolio ID based on your token, because the token is associated with you and your organization, and an organization has only one portfolio.
- The header 'Accept: application/vnd.pm.portfolio-1+json' tells Polaris what kind of JSON data you expect to receive in the response. You'll see what that format looks like as soon as you send the request.
Response:
{ "_items": [ { "id": "1e94e60f-8ee1-46d9-b92c-23a1c6dc4624" } ], "_links": [ { "href": "https://polaris.blackduck.com/api/portfolio/portfolios?_offset=0&_limit=100", "rel": "first", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios?_offset=0&_limit=100", "rel": "next", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios?_offset=0&_limit=100", "rel": "prev", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios?_offset=0&_limit=100", "rel": "last", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios?_offset=0&_limit=100", "rel": "self", "method": "GET" } ], "_collection": { "itemCount": 1, "currentPage": 1, "pageCount": 1 } }
About this response:
- The _items property (near the top) contains the portfolio ID, which is needed in the next step.
-
Get the portfolio item ID.
Purpose: Use the portfolioId to obtain the portfolioItemId, which is required in a subsequent step.
Request:
curl --location --request GET \ "https://polaris.blackduck.com/api/portfolio/portfolios/1e94e60f-8ee1-46d9-b92c-23a1c6dc4624/portfolio-items" \ --header 'accept: application/vnd.pm.portfolio-items-1+json' \ --header 'Api-token: {token}'
About this request:
- Use the portfolio ID as an in-path parameter, between /portfolios and /portfolio-items.
- This request returns a complete, unfiltered list of all the portfolio items (applications) in your organization's portfolio.
- At present, applications are the only type of item in the portfolio, so the term "portfolio item" is interchangeable with application. Likewise, "portfolio subitem" is interchangeable with "project."
Response:
{ "_items": [ { "id": "91109f16-7927-4611-bc2f-f72c54535043", "name": "Docs on CDEV", "description": "Docs applications that can be tested.", "itemType": "APPLICATION", "portfolioId": "1e94e60f-8ee1-46d9-b92c-23a1c6dc4624", "inTrash": false, "createdAt": "2022-08-20 02:52:38", "updatedAt": "2022-08-20 02:52:38" }, { "id": "1fa58841-6a8c-4e58-82d3-d4587644d3ed", "name": "GUI User Guide", "description": "reviewing docs", "itemType": "APPLICATION", "portfolioId": "1e94e60f-8ee1-46d9-b92c-23a1c6dc4624", "inTrash": false, "createdAt": "2022-08-30 00:11:06", "updatedAt": "2022-08-30 00:11:06" }, { "id": "335d5600-f456-47c6-bcd5-81520d25bfc6", "name": "Test GitHub", "description": "testing for documentation", "itemType": "APPLICATION", "portfolioId": "1e94e60f-8ee1-46d9-b92c-23a1c6dc4624", "inTrash": false, "createdAt": "2022-08-25 02:06:18", "updatedAt": "2022-08-25 02:07:53" } ], "_links": [ { "href": "https://polaris.blackduck.com/api/portfolio/portfolios/1e94e60f-8ee1-46d9-b92c-23a1c6dc4624/portfolio-items?_offset=0&_limit=100", "rel": "first", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios/1e94e60f-8ee1-46d9-b92c-23a1c6dc4624/portfolio-items?_offset=0&_limit=100", "rel": "next", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios/1e94e60f-8ee1-46d9-b92c-23a1c6dc4624/portfolio-items?_offset=0&_limit=100", "rel": "prev", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios/1e94e60f-8ee1-46d9-b92c-23a1c6dc4624/portfolio-items?_offset=0&_limit=100", "rel": "last", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolios/1e94e60f-8ee1-46d9-b92c-23a1c6dc4624/portfolio-items?_offset=0&_limit=100", "rel": "self", "method": "GET" } ], "_collection": { "itemCount": 3, "currentPage": 1, "pageCount": 1 } }
About this response:
- The _items list contains three objects, each corresponding to a different application.
- Choose the ID of the portfolio item (application) that interests you. That would be the one containing the subitem (project) that you tested.
-
Get the portfolio subitem ID.
Purpose: Use the portfolioItemId to obtain a portfolioSubitemId which is required in a subsequent step.
Request:
curl --location --request GET \ "https://polaris.blackduck.com/api/portfolio/portfolio-items/335d5600-f456-47c6-bcd5-81520d25bfc6/portfolio-sub-items" \ --header 'Accept: application/vnd.pm.portfolio-subitems-1+json' \ --header 'Api-token: {token}'
About this request:
- Use the portfolioItemId as an in-path parameter, between /portfolio-items and /portfolio-sub-items.
- This request returns a complete list of projects in the application. At present, projects are the only type of subitem.
Response:
{ "_items": [ { "id": "c937bfc1-164a-4c95-adc3-f74b964a6321", "name": "docs", "description": "", "subItemType": "PROJECT", "inTrash": false, "portfolioItemId": "335d5600-f456-47c6-bcd5-81520d25bfc6", "createdAt": "2022-08-30 00:13:24", "updatedAt": "2022-08-30 00:13:24" }, { "id": "d49afe7b-f5b7-42d3-9384-ea2dab7cda2f", "name": "GitHub", "description": "test integration", "subItemType": "PROJECT", "inTrash": false, "portfolioItemId": "335d5600-f456-47c6-bcd5-81520d25bfc6", "createdAt": "2022-08-25 04:03:47", "updatedAt": "2022-08-25 04:03:47" }, { "id": "8b0c7b11-b1b4-4d96-ba1e-36a724291e26", "name": "New", "description": "New Project", "subItemType": "PROJECT", "inTrash": false, "portfolioItemId": "335d5600-f456-47c6-bcd5-81520d25bfc6", "createdAt": "2022-09-12 21:06:25", "updatedAt": "2022-09-12 21:06:25" }, { "id": "3aa00e09-a66f-42ab-9aa0-8110e544431d", "name": "Webgoat111", "description": "generic test", "subItemType": "PROJECT", "inTrash": false, "portfolioItemId": "335d5600-f456-47c6-bcd5-81520d25bfc6", "createdAt": "2022-08-25 02:35:48", "updatedAt": "2022-08-30 02:48:27" } ], "_links": [ { "href": "https://polaris.blackduck.com/api/portfolio/portfolio-items/335d5600-f456-47c6-bcd5-81520d25bfc6/portfolio-sub-items?_offset=0&_limit=100", "rel": "first", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolio-items/335d5600-f456-47c6-bcd5-81520d25bfc6/portfolio-sub-items?_offset=0&_limit=100", "rel": "next", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolio-items/335d5600-f456-47c6-bcd5-81520d25bfc6/portfolio-sub-items?_offset=0&_limit=100", "rel": "prev", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolio-items/335d5600-f456-47c6-bcd5-81520d25bfc6/portfolio-sub-items?_offset=0&_limit=100", "rel": "last", "method": "GET" }, { "href": "https://polaris.blackduck.com/api/portfolio/portfolio-items/335d5600-f456-47c6-bcd5-81520d25bfc6/portfolio-sub-items?_offset=0&_limit=100", "rel": "self", "method": "GET" } ], "_collection": { "itemCount": 4, "currentPage": 1, "pageCount": 1 } }
About this response:
- The application in question contains four projects. These are at the beginning of the response, as a list of objects contained in the _items property. When you go in search of your own test results, you'll likely be able to identify your project by name here.
- The _collection object describes the total number of records (the four projects), the total number of pages containing results, and the current page. This is useful when you have more records than can be viewed at one time.
- Collect the ID of the project for use in the next step.
-
Get a list of issues from the latest test in the project.
Purpose: Use portfolioSubitemId collected in the previous step to get the issues in your recent test.
Request:
curl --location --request GET "https://polaris.blackduck.com/api/specialization-layer-service/issues/_actions/list?portfolioSubItemId=3aa00e09-a66f-42ab-9aa0-8110e544431d&testId=latest&_first=100&_includeAttributes=true"\ --header 'Accept: application/vnd.polaris-one.issue-management.issue-paginated-list-1+json' \ --header 'Accept-Language: en-CA,en;q=0.9' \ --header 'Api-Token: {token}'
About this request:
- Note that portfolioSubItemId is provided as an in-path parameter. This request requires that you provide either portfolioSubItemId or portfolioItemId; but not both.
- Note that the names of these properties in Findings are not the same as the names they had in Portfolio, where they were collected. What was the portfolio subitem id (two-letter parameter name) becomes portfolioSubItemId.
- The query
testId=latest
tells Polaris to return results from the most recent test completed on this project. Alternatively, you could supply a testId, which can be obtained from the Bridge CLI tool or from the web UI after you start a test. - The query
_first=100
tells Polaris to provide only the first 100 records found in this search. The reference docs explain how you can grab the first or last n records, or sort the results, or filter on things like issue type, severity, or triage properties. - The query
_includeAttributes=true
tells Polaris to include tool-provided issue data in the response. If this were set to false, we'd see little more than issue name, ID, family ID, and other generic information about this type of issue.
Response:
This is a shortened version of the original response.
{ "_items": [ ( . . .) { "id": "aab69a20-25f5-411a-be55-b1ea4901451b", "familyId": "49A2233D3C63D46B1904205DEA7D71C4", "familyKey": "9dfaab47-e7a8-4cc0-a837-d3f314d3e6be::CVE-2017-15288::CWE-732", "uploadSet": "1a94ab4c-95a8-480c-b8e7-15a340532195", "type": { "id": "w-1158", "name": "w-1158", "_localized": { "name": "Incorrect Permission Assignment for Critical Resource", "otherDetail": [ { "key": "description", "value": "The product specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors." }, { "key": "remediation", "value": "Potential mitigations include the following:\n 1. When using a critical resource such as a configuration file, check to see if the resource has insecure permissions (such as being modifiable by any regular user) [REF-62], and generate an error or even exit the software if there is a possibility that the resource could have been modified by an unauthorized party.\n 2. Divide the software into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully defining distinct user groups, privileges, and/or roles. Map these against data, functionality, and the related resources. Then set the permissions accordingly. This will allow you to maintain more fine-grained control over your resources. [REF-207]\n 3. Run the code in a \"jail\" or similar sandbox environment that enforces strict boundaries between the process and the operating system. This may effectively restrict which files can be accessed in a particular directory or which commands can be executed by the software.\n\nOS-level examples include the Unix chroot jail, AppArmor, and SELinux. In general, managed code may provide some protection. For example, java.io.FilePermission in the Java SecurityManager allows the software to specify restrictions on file operations.\n\nThis may not be a feasible solution, and it only limits the impact to the operating system; the rest of the application may still be subject to compromise.\n\nBe careful to avoid CWE-243 and other weaknesses related to jails.\n\n 4. During program startup, explicitly set the default permissions or umask to the most restrictive setting possible. Also set the appropriate permissions during program installation. This will prevent you from inheriting insecure permissions from any user who installs or runs the program.\n 5. For all configuration files, executables, and libraries, make sure that they are only readable and writable by the software's administrator.\n 6. Do not suggest insecure configuration changes in documentation, especially if those configurations can extend to resources and other programs that are outside the scope of the application.\n 7. Do not assume that a system administrator will manually change the configuration to the settings that are recommended in the software's manual.\n 8. Ensure that the software runs properly under the Federal Desktop Core Configuration (FDCC) [REF-199] or an equivalent hardening configuration guide, which many organizations use to limit the attack surface and potential risk of deployed software." } ] } }, "attributes": [ { "key": "description", "value": "The compilation daemon in Scala before 2.10.7, 2.11.x before 2.11.12, and 2.12.x before 2.12.4 uses weak permissions for private files in /tmp/scala-devel/${USER:shared}/scalac-compile-server-port, which allows local users to write to arbitrary class files and consequently gain privileges." }, { "key": "major-version-upgrade-guidance-low-count", "value": 0 }, { "key": "component-version-id", "value": "4b646579-7613-4d39-b33a-410c623a2521" }, { "key": "minor-version-upgrade-guidance-high-count", "value": 0 }, { "key": "published-date", "value": "2017-11-15T16:29Z" }, { "key": "major-version-upgrade-guidance-external-id", "value": "org.scala-lang:scala-library:2.13.9" }, { "key": "major-version-upgrade-guidance-critical-count", "value": 0 }, { "key": "component-id", "value": "5defcec1-ef02-4263-828f-7bb1e139a2af" }, { "key": "minor-version-upgrade-guidance-unscored-count", "value": 0 }, { "key": "component-version-name", "value": "2.11.7" }, { "key": "vulnerability-id", "value": "CVE-2017-15288" }, { "key": "vulnerability-source", "value": "CVE" }, { "key": "minor-version-upgrade-guidance-external-id", "value": "org.scala-lang:scala-library:2.13.9" }, { "key": "severity", "value": "high" }, { "key": "version", "value": 1 }, { "key": "component-origin-id", "value": "9dfaab47-e7a8-4cc0-a837-d3f314d3e6be" }, { "key": "component-origin-external-id", "value": "org.scala-lang:scala-library:2.11.7" }, { "key": "cwe", "value": "CWE-732" }, { "key": "major-version-upgrade-guidance-version-name", "value": "2.13.9" }, { "key": "minor-version-upgrade-guidance-medium-count", "value": 0 }, { "key": "major-version-upgrade-guidance-high-count", "value": 0 }, { "key": "major-version-upgrade-guidance-medium-count", "value": 0 }, { "key": "overall-score", "value": "7.8" }, { "key": "minor-version-upgrade-guidance-version-name", "value": "2.13.9" }, { "key": "minor-version-upgrade-guidance-critical-count", "value": 0 }, { "key": "component-name", "value": "Scala" }, { "key": "component-origin-external-namespace", "value": "maven" }, { "key": "minor-version-upgrade-guidance-low-count", "value": 0 }, { "key": "location", "value": "Scala 2.11.7" }, { "key": "major-version-upgrade-guidance-unscored-count", "value": 0 } ], "tenantId": "57e78b5e-ad79-4d3f-acc8-1983fd390c68", "_cursor": "AAAATA==", "_links": [ { "href": "http://polaris.blackduck.com/api/specialization-layer-service/issues/aab69a20-25f5-411a-be55-b1ea4901451b?portfolioSubItemId=6a23d406-9bf8-4124-91dc-373e0467c224&_includeAttributes=true", "rel": "self", "method": "GET" } ] }, ], "_collection": { "itemCount": 583, "currentPage": 1, "pageCount": 6 } }
About this response:
- The _collection property at the end of this paginated response explains how much data there is. The test returned a total of 583 issues. Since the request included the _first=100 query, that's how many issues were returned on this one page. The remaining five pages in the page count, contain the other 483 issues.
- The reference documentation explains how to page through the remaining results.
- The _items object in this response is trimmed down to contain just one of the 100 issues returned in the response. Most of the data in that issue is the attributes property, which contains specific information about this finding, including the severity, the CVE number, and the location of the vulnerability.