Introduction
Using the GraphQL API
GraphQL Playground
Introduction
This document is intended to introduce and explicitly define a particular subset that can be considered officially supported for our GraphQL API. The entire Graph should be considered supported unless otherwise annotated (e.g. with depreciated
or experimental
warnings).
Note: The base URL of our Graph API has been changed to api.nowsecure.com. All requests to lab-api.nowsecure.com/graphql will be forwarded here.
Using the GraphQL API
The GraphQL API provides many resources detailing some of the ways to interface or consume a Graph. GraphQL client libraries can leverage a GraphQL API advertised service and type definitions in any language. While these resources aid in research of the API, a simple HTTP POST request is all you need to consume data.
HTTP Post
Interacting with the Graph API from code, e.g. through curl or via HTTP client library, is as simple as an HTTP POST with the relevant GraphQL query.
Here’s a query to list NowSecure’s findings, resolving just the finding id
and title
for each:
The results will come back as a JSON with a data
key. The values will be structured as requested (with results formatted and elided for clarity):
curl \
-X POST \
-H "Authorization: Bearer ${AUTH_TOKEN}" \
-H "Content-Type: application/json" \
--data '{ "query": "{ findings { list { id title } } }" }' \
https://api.nowsecure.com/graphql
{
"data": {
"findings": {
"list": [
{
"id": "asl",
"title": "System Log Messages (ASL)"
},
{
"id": "oslog",
"title": "System Log Messages (OSLog)"
},
{
"id": "geoip",
"title": "Network Connections"
},
{
"id": "snoop_network_hosts",
"title": "Network Connections"
},
// ...
]
}
}
}
Note: As described in the field documentation, the finding id
is a case and space normalized version of the legacy finding id used by the legacy lab auto api. You may also resolve the unnormalized key for each finding within the legacyFindingKey
field. If you have existing logic depending on identifying individual findings, use this legacyFindingKey
.
Errors
If the query issued contains one or more errors, these will be listed in a top level errors
array in the response. For example, this query and response:
curl \
-X POST \
-H "Authorization: Bearer ${AUTH_TOKEN}" \
-H "Content-Type: application/json" \
--data '{ "query": "{ findings { list { id title nonExistentField } } }" }' \
https://api.nowsecure.com/graphql
{
"errors": [
{
"message": "Cannot query field \"nonExistentField\" on type \"FindingCheck\"."
// ...
}
]
}
The same is true if your GraphQL query is syntactically invalid.
Note the response for a lack of closing }:
curl \
-X POST \
-H "Authorization: Bearer ${AUTH_TOKEN}" \
-H "Content-Type: application/json" \
--data '{ "query": "{ findings { list { id title"' \
https://api.nowsecure.com/graphql
{"error":true,"code":"UNKNOWN_ERROR_CODE","message":"Unexpected end of JSON input"}%
GraphQL Playground
The GraphQL playground is a web app for browsing and interacting with NowSecure’s GraphQL API. GraphQL playground is a standard tool within the GraphQL toolbox. It makes learning, browsing and prodding at any given GraphQL API much more accessible for everybody, even for those users who have no interest in interacting with our API programmatically. Among many other features, it provides auto-completion when authoring queries, syntax highlighting and auto-formatting of queries and results, and a powerful, searchable “Documentation Explorer” panel. This allows the entire API to be explored one type at a time. Any documentation available for a given type, and/or for any function arguments or record attributes, are surfaced right inline.
Authentication
In order to authenticate, you must also provide a valid Authorization: Bearer ...
header with the request, as for any other API request. In the GraphQL playground, this can be accomplished within the “HTTP HEADERS”, specifying any headers as a JSON object.
{
"Authorization": "Bearer INSERT_YOUR_JWT_API_TOKEN_HERE"
}
Alerts
The myAlerts
query node takes two arguments: the isRead
parameter allows filtering strictly for alerts that have been either read or unread (if unspecified, both read and unread alerts will be returned.) The sortDescending
parameter allows for fetching alerts by most recent first, rather than the default chronological order (the order alerts were created.)
To query for alerts for the authenticated user, use the myAlerts query node. For example, use this query for all unread alerts with most recent alerts sorted first.
POSTquery {
alerts {
myAlerts(isRead: false, sortDescending: true) {
id
eventType
createdAt
readAt
}
}
}
curl \
-X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
--data '{ "query": "{ alerts { myAlerts(isRead: false, sortDescending: true) { id eventType createdAt readAt } } }" }' \
https://api.nowsecure.com/graphql
{
"data": {
"alerts": {
"myAlerts": [
{
"id": 6172,
"eventType": "ASSESSMENT_DONE",
"createdAt": "2019-02-08T19:11:21.109Z",
"readAt": true
},
{
"id": 6171,
"eventType": "ASSESSMENT_DONE",
"createdAt": "2019-02-08T16:10:56.258Z",
"readAt": true
}
]
}
}
}
Change History Audit Logs
The audit > changes
node can be queried to see all changes on audited attributes for all entities across the org. (This feature requires org admin privileges to integrate with existing RBAC mechanisms.)
This query resolves all information for every historical change across the organization.
This result set can be sliced by timeframe using the optional since and until arguments, and an integer limit argument is also available. The results may also be filtered for specific entityTypes, and/or for a given set of attributes. Use this query to see all CVSS edits this year.
query {
audit {
changes {
entityType
entityRef
attribute
value
updatedAt
user {
ref
}
}
}
}
query {
audit {
changes(since: "2022-01-01T00:00:00Z", attributes: ["edit:cvss"]) {
value
updatedAt
user {
ref
}
}
}
}
{
"data": {
"audit": {
"changes": [
{
"value": 4.5,
"updatedAt": "2022-01-16T23:40:28.611Z",
"user": {
"ref": "81e3b350-0325-457e-8d32-f7202ce8a2a8"
}
},
{
"value": 5.4,
"updatedAt": "2019-01-22T17:26:58.562Z",
"user": {
"ref": "81e3b350-0325-457e-8d32-f7202ce8a2a8"
}
},
// ...
]
}
}
}
Note: The DateTime
type is not necessary for a response.
Long-term Depreciation Guideline
As the GraphQL API structure stabilizes, any graph nodes we would like to remove will be annotated with a deprecation warning, which should include instructions on where best to query for the relevant data. We will continue to support queries on these deprecated nodes, but using them when authoring new queries in the GraphQL playground, for instance, will issue warnings. While it is not advisable to develop new application logic against deprecated nodes, we will not remove any deprecated nodes/functionality without a great deal of advanced warning. We intend to be extremely conservative about preserving backward-compatibility, warts and all – we consider any breakage of backward-compatibility to be a bug.
Comments
Article is closed for comments.