Introduction

With IBM Cloud™ Security Advisor you can receive alerts for possible issues, which helps you to feel more confident in the security of your IBM Cloud account and resources.

Based on Grafeas, the Findings API is used to find and display occurrences of security issues in your IBM Cloud account by using the artifact metadata specification. Findings are summarized in cards in the Security Advisor dashboard that allow you to see the security status of your account at a glance and start an investigation into any potential issues.

For more information about getting started with Security Advisor, see the docs.

The code examples on this tab use the client library that is provided for Java.

Maven

<dependency>
    <groupId>com.ibm.cloud</groupId>
    <artifactId>securityadvisor</artifactId>
    <version>1.0.1</version>
</dependency>

Gradle

compile 'com.ibm.cloud:securityadvisor:1.0.1'

The code examples on this tab use the client library that is provided for Go.

Installation using Go modules. Add the following import to your Go application.

import (
  "github.com/ibm-cloud-security/security-advisor-sdk-go/findingsapiv1"
)

Run the following commands to download and install the new dependency.

go mod init <module_path> // If the module is not already initialized
go mod tidy

The code examples on this tab use the client library that is provided for Node.js.

Installation

npm install ibm-security-advisor

The code examples on this tab use the client library that is provided for Python.

Installation

pip install --upgrade "ibm_cloud_security_advisor>=1.0.0"

Authentication

To work with the API, use an IBM Cloud IAM access token in each API request. You can generate an access token by first creating an API key and then exchanging your API key for an IBM Cloud IAM token.

Don't have an API key? Try running ibmcloud oauth-tokens in the IBM Cloud Shell to quickly generate a personal access token.

To generate an access token from your API key, run the following cURL command:

curl -X POST \
  "https://iam.cloud.ibm.com/identity/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --header "Accept: application/json" \
  --data-urlencode "grant_type=urn:ibm:params:oauth:grant-type:apikey" \
  --data-urlencode "apikey={api_key}"

Replace {api_key} with your IBM Cloud API key. To learn more, check out the IAM docs.

You authenticate to the API by using Cloud Identity and Access Management (IAM). You can pass either a bearer token in an authorization header or an API key.

The SDK provides initialization methods for each form of authentication.

  • Use the API key to have the SDK manage the lifecycle of the access token. The SDK requests an access token, ensures that the access token is valid, and refreshes it if necessary.
  • Use the access token to manage the lifecycle yourself. Keep in mind that access tokens are valid for 1 hour, so you must refresh them regularly to maintain access.

For more information, see IAM authentication with the SDK.

For more information, see IAM authentication with the SDK.

For more information, see IAM authentication with the SDK.

For more information, see IAM authentication with the SDK.

Example that uses IAM authentication

curl -X {request_method} "{url}/{method}" --header "Authorization: Bearer {IAM_token}"

Replace {IAM_token} with your IBM Cloud IAM access token.

Example that uses IAM authentication

IamAuthenticator authenticator = new IamAuthenticator("{api_key}");
FindingsApi findings_api = new FindingsAPI("findings_api",authenticator);

Replace {api_key} with your credentials.

Example that uses IAM authentication

import (
  "github.com/IBM/go-sdk-core/v3/core"
  "github.com/ibm-cloud-security/security-advisor-sdk-go/findingsapiv1"
)

authenticator := &core.IamAuthenticator{
ApiKey: "{api_key}",
}

service, err := findingsapiv1.NewFindingsApiV1(&findingsapiv1.FindingsApiV1Options{
  Authenticator: authenticator,
  URL: "{url}", 
})

Replace {api_key} with your credentials.

Example that uses IAM authentication

from ibm_cloud_security_advisor import FindingsApiV1 
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

authenticator = IAMAuthenticator('{api_key}')
ibm_cloud_security_advisor =  FindingsApiV1(authenticator=authenticator)

Replace {api_key} with your credentials.

Example that uses IAM authentication

const { IamAuthenticator } = require('ibm-security-advisor/auth')

const authenticator = new IamAuthenticator({
  apikey: '{api_key}',
});

Replace {api_key} with your credentials.

Endpoint URLs

Security Advisor supports regional endpoint URLs that you can use to interact with the service over the public internet. When you call the API, use the endpoint URL that corresponds with the location that you see in the Security Advisor dashboard.

Endpoint URLS by location

  • Dallas: https://us-south.secadvisor.cloud.ibm.com/findings
  • London: https://eu-gb.secadvisor.cloud.ibm.com/findings

Security Advisor supports regional endpoint URLs that you can use to interact with the service over the public internet. To target a Security Advisor endpoint URL, use the setServiceUrl method. Include the endpoint URL that corresponds with the location that you see in the Security Advisor dashboard.

Endpoint URLS by location

  • Dallas: https://us-south.secadvisor.cloud.ibm.com/findings
  • London: https://eu-gb.secadvisor.cloud.ibm.com/findings

Security Advisor supports regional endpoint URLs that you can use to interact with the service over the public internet. To target a Security Advisor endpoint URL, use the URL parameter. Include the endpoint URL that corresponds with the location that you see in the Security Advisor dashboard.

Endpoint URLS by location

  • Dallas: https://us-south.secadvisor.cloud.ibm.com/findings
  • London: https://eu-gb.secadvisor.cloud.ibm.com/findings

Security Advisor supports regional endpoint URLs that you can use to interact with the service over the public internet. To target a Security Advisor endpoint URL, use the setServiceUrl method. Include the endpoint URL that corresponds with the location that you see in the Security Advisor dashboard.

Endpoint URLS by location

  • Dallas: https://us-south.secadvisor.cloud.ibm.com/findings
  • London: https://eu-gb.secadvisor.cloud.ibm.com/findings

Security Advisor supports regional endpoint URLs that you can use to interact with the service over the public internet. To target a Security Advisor endpoint URL, use the set_service_url method. Include the endpoint URL that corresponds with the location that you see in the Security Advisor dashboard.

Endpoint URLS by location

  • Dallas: https://us-south.secadvisor.cloud.ibm.com/findings
  • London: https://eu-gb.secadvisor.cloud.ibm.com/findings

Base URL

https://{region}.secadvisor.cloud.ibm.com/findings

Example for the Dallas location

curl -X {request_method} "https://us-south.secadvisor.cloud.ibm.com/findings/v1/{account_ID}/{method}" --header "Authorization: Bearer {IAM_token}"

Replace {account_ID} and {IAM_token} with your credentials.

Base URL

https://{region}.secadvisor.cloud.ibm.com/findings

Example for the Dallas location

IamAuthenticator authenticator = new IamAuthenticator("{api_key}");
FindingsApi findings_api = new FindingsAPI("findings_api",authenticator);
findings_api.setServiceUrl("https://us-south.secadvisor.cloud.ibm.com/findings");

Replace {api_key} with your credentials.

Base URL

https://{region}.secadvisor.cloud.ibm.com/findings

Example for the Dallas location

import (
  "github.com/IBM/go-sdk-core/v3/core"
  "github.com/ibm-cloud-security/security-advisor-sdk-go/findingsapiv1"
)

authenticator := &core.IamAuthenticator{
ApiKey: "{api_key}",
}

service, err := findingsapiv1.NewFindingsApiV1(&findingsapiv1.FindingsApiV1Options{
  Authenticator: authenticator,
  URL: "https://us-south.secadvisor.cloud.ibm.com/findings",
})

Replace {api_key} with your credentials.

Base URL

https://{region}.secadvisor.cloud.ibm.com/findings

Example for the Dallas location

from ibm_cloud_security_advisor import FindingsApiV1 
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator

authenticator = IAMAuthenticator('{api_key}')
ibm_cloud_security_advisor =  FindingsApiV1(authenticator=authenticator)

ibm_cloud_security_advisor.set_service_url("https://us-south.secadvisor.cloud.ibm.com/findings")

Replace {api_key} with your credentials.

Base URL

https://{region}.secadvisor.cloud.ibm.com/findings

Example for the Dallas location

const FindingsAPI =  require('ibm-security-advisor/findings-api/v1');
const { IamAuthenticator } = require('ibm-security-advisor/auth');

const findingsAPIClient = new FindingsAPI({
  authenticator: new IamAuthenticator({ apikey: '{api_key}' }),
});

findingsAPIClient.setServiceUrl('https://us-south.secadvisor.cloud.ibm.com/findings');

Replace {api_key} with your credentials.

Error handling

Security Advisor uses standard HTTP response codes to indicate whether a method completed successfully. A 200 response always indicates success. A 400 type response is some sort of failure, and a 500 type response usually indicates an internal system error.

Status code summary
Status code Description
200 OK Everything worked as expected.
201 OK Everything worked as expected. No content is returned.
400 Bad Request The request was unsuccessful, often due to a missing required parameter.
401 Unauthorized The parameters were valid but the request failed due insufficient permissions.
404 Not Found The requested resource doesn't exist.
409 Conflict The requested resource conflicts with an already existing resource.
410 Gone The requested resource was deleted and no longer exists.
429 Too Many Requests Too many requests hit the API too quickly.
500 Internal Server Error Something went wrong on Security Advisor's end.

Methods

Query findings

Query findings by using the GraphQL query language. For more information about using GraphQL, see the GraphQL documentation.

POST /v1/{account_id}/graph

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

  • Allowable values: [application/graphql,application/json]

Path Parameters

  • Your IBM Cloud account ID.

Body for query findings.

  • curl -X POST "https://<region>.secadvisor.cloud.ibm.com/findings/v1/graph"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'   --data-raw '{
          "query": "{occurrences(kind: \"FINDING\") {name}}"
        }'
  • public class PostGraph {
    
        private PostGraph() { }
    
        public static void main(String[] args) {
            String body = "{notes{id}}";
    
            PostGraphOptions opts = new PostGraphOptions.Builder()
            .accountId("<account_ID>")
            .body(new ByteArrayInputStream(body.getBytes()))
            .contentType("application/graphql")
            .build();
    
            Response<Void> resp = findingsApi.postGraph(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func PostGraph() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/graphql"
    
      accountID := "<account_ID>"
    
      // Query using ioutils
      newQuery := ioutil.NopCloser(strings.NewReader(`query {findingCount: occurrenceCount(kind: "FINDING")}`))
      postGraphOptions := service.NewPostGraphOptions(accountID)
      postGraphOptions.SetBody(newQuery)
      postGraphOptions.SetHeaders(headers)
      res, operationErr := service.PostGraph(postGraphOptions)
      if operationErr != nil {
        fmt.Println("Err", operationErr)
      }
      fmt.Println(res.Result)
    
    }    
  • const params = {
      accountId: "<account_ID>",
      contentType: "application/graphql",
      body: 'query {occurrences(kind: "FINDING") {name}}'
    };
    
    findingsAPIClient
      .postGraph(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.post_graph(
      account_id="<account_ID>",
      body='query {occurrences(kind: "FINDING") {name}}',
      content_type="application/graphql"
    )
    
    print(response)

Response

Status Code

  • OK

Example responses
  • {
      "data": {
        "occurrences": [
          {
            "name": "fd2349bf5144594dt9914c08c91b6a15a/providers/security-advisor/occurrences/ata-1594862964602"
          },
          {
            "name": "fd2349bf5144594dt9914c08c91b6a15a/providers/security-advisor/occurrences/occurence1"
          },
          {
            "name": "fd2349bf5144594dt9914c08c91b6a15a/providers/security-advisor/occurrences/critical-finding"
          }
        ]
      }
    }

List providers

A provider is the tool or service that defines the type of finding and then flags any occurence of that findings to Security Advisor. You can list all of the providers that are attached to an account by specifying an account ID.

GET /v1/{account_id}/providers

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

Query Parameters

  • Limit the number of the returned providers to a specified number. The limit must be greater than 1. If it is 1 or less, a 400 status code is thrown. If not provided, this field is ignored and it returns all the providers.

    Constraints: value ≥ 2

  • The offset is the index of the item from which you want to start returning data from.

    Default: 0

  • The first provider ID that is included in the results. If not provided, this field is ignored.

  • The last provider ID that is included in the results. If not provided, this field is ignored.

  • curl -X GET "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public class ListProviders {
    
        private ListProviders() { }
    
        public static void main(String[] args) {
            ListProvidersOptions opts = new ListProvidersOptions.Builder()
            .accountId("<account_ID>")
            .build();
    
            Response<ApiListProvidersResponse> resp = findingsApi.listProviders(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func ListProviders() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/json"
    
      accountID := "<account_ID>"
    
      var listProvidersOptions = service.NewListProvidersOptions(accountID)
      listProvidersOptions.SetLimit(5)
      listProvidersOptions.SetStartProviderID("a")
      listProvidersOptions.SetEndProviderID("p")
    
      res, _, err := service.ListProviders(listProvidersOptions)
      if err != nil {
        fmt.Println("Failed to get list of providers: ", err)
      } else {
        fmt.Printf(`Found %d providers between "a" and "p". Limit is set to 5 per page.`, len(res.Providers))
        fmt.Println()
        if len(res.Providers) > 0 {
          fmt.Println("Providers 1 ID: ", *res.Providers[0].ID)
          fmt.Println("Providers 1 name: ", *res.Providers[0].Name)
    
        }
      }
    }  
  • const params = {
      accountId: "<account_ID>"
    };
    
    findingsAPIClient
      .listProviders(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.list_providers(account_id="<account_ID>")
    
    print(response)

Response

A list of providers is returned.

Status Code

  • Success

Example responses
  • {
      "providers": [
        {
          "name": "fd2349bf5144594dt9914c08c91b6a15a/providers/secadvisor",
          "id": "secadvisor"
        },
        {
          "name": "fd2349bf5144594dt9914c08c91b6a15a/providers/security-advisor",
          "id": "security-advisor"
        }
      ]
    }

Create a note

To register a new finding with Security Advisor, create a note.

POST /v1/{account_id}/providers/{provider_id}/notes

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

Body for note creation.

  • curl -X POST "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_id>/providers/<provider_id>/notes"   -H 'accept: application/json'   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'   -d '{
            "kind": "FINDING",
            "short_description": "Inactive user(s) in account",
            "long_description": "Non-active users listed in account",
            "id": "inactiveUsers",
            "reported_by": {
                "id": "my-custom-IAM-scanner",
                "title": "IAMScanner"
            },
            "finding": {
              "severity": "MEDIUM",
              "next_steps": [
                {
                  "title": "Go to account user management",
                  "url": "https://cloud.ibm.com/iam/users"
                },
                {
                  "title": "Visit account user management"
                },
                {
                  "title": "Validate and remove non-active users"
                }
              ]
            }
          }'
  • public class CreateFinding {
    
        private CreateFinding() { }
    
        public static void main(String[] args) {
            Reporter reporterModel = new Reporter.Builder()
                .id("my-custom-IAM-scanner")
                .title("IAMScanner")
                .build();
    
            RemediationStep nextStep = new RemediationStep.Builder()
                .title("Validate and remove non-active users")
                .url("https://cloud.ibm.com/iam/users")
                .build();
    
            FindingType findingModel = new FindingType.Builder()
                .severity("MEDIUM")
                .nextSteps(new java.util.ArrayList<RemediationStep>(java.util.Arrays.asList(nextStep)))
                .build();
    
            CreateNoteOptions createNoteOptionsModel = new CreateNoteOptions.Builder()
                .accountId("<account_Id>")
                .providerId("my-custom-security-tool")
                .shortDescription("Inactive user(s) in account")
                .longDescription("Non-active users listed in account")
                .kind("FINDING")
                .id("inactiveUsers")
                .reportedBy(reporterModel)
                .finding(findingModel)
                .build();
    
            Response<ApiNote> resp = findingsApi.createNote(createNoteOptionsModel).execute();
            System.out.println(resp.getResult());
        }
    }
  • func CreateFindingNote() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/json"
    
      accountID := "<account_ID>"
      providerID := "my-custom-security-tool"
      shortDescription := "Inactive user(s) in account"
      longDescription := "Non-active users listed in account"
      kind := "FINDING"
      id := "inactiveUsers"
      reportedBy, _ := service.NewReporter("my-custom-IAM-scanner", "https://example.com")
      remediationTitle := "Validate and remove non-active users"
      remediationURL := "https://cloud.ibm.com/iam/users"
      nextStep := []findingsapiv1.RemediationStep{{Title: &remediationTitle, URL: &remediationURL}}
      severity := "MEDIUM"
      finding := findingsapiv1.FindingType{Severity: &severity, NextSteps: nextStep}
    
      var createNoteOptions = service.NewCreateNoteOptions(accountID, providerID, shortDescription, longDescription, kind, id, reportedBy)
      createNoteOptions.SetHeaders(headers)
      createNoteOptions.SetFinding(&finding)
    
      result, response, operationErr := service.CreateNote(createNoteOptions)
      if operationErr != nil {
        fmt.Println("Failed to create note: ", operationErr)
        fmt.Println(response.Result)
      } else {
        fmt.Println(response.StatusCode)
        fmt.Println(*result.ID)
        fmt.Println(*result.Kind)
        fmt.Println(*result.ShortDescription)
      }
    
    }
  • const params = {
      accountId: "<account_ID>",
      providerId: "my-custom-security-tool",
      newId: "inactiveUsers"
      newKind: "FINDING",
      newShortDescription: "Inactive user(s) in account",
      newLongDescription: "Non-active users listed in account",
      newReportedBy: {
        newId: "my-custom-IAM-scanner",
        title: "IAMScanner"
      },
      newFinding: {
        severity: "MEDIUM",
        next_steps: [{
          title: "Go to account user management",
          url: "https://cloud.ibm.com/iam/users"
          },
          {
          title: "Visit account user management"
          },
          {
          title: "Validate and remove non-active users"
          }
        }]
      }
    };
    
    findingsAPIClient
      .createNote(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.create_note(
      account_id="<account_ID>",
      provider_id="my-custom-security-tool",
      short_description="Inactive user(s) in account",
      long_description="Non-active users listed in account",
      kind="FINDING",
      id="inactiveUsers",
      reported_by={'id':'my-custom-IAM-scanner','title':'IAMScanner'},
      finding={
        "severity": "MEDIUM",
        "next_steps": [
          {
            "title": "Go to account user management",
            "url": "https://cloud.ibm.com/iam/users"
          },
          {
            "title": "Visit account user management"
          },
          {
            "title": "Validate and remove non-active users"
          }
        ]
      }
    )
    
    print(response)

Response

Provides a detailed description of a note.

Status Code

  • The note was created successfully.

Example responses
  • {
      "short_description": "Inactive user(s) in account",
      "long_description": "Non-active users listed in account",
      "kind": "FINDING",
      "related_url": [
        {
          "label": "IAMScanner",
          "url": "https://cloud.ibm.com/iam/users"
        }
      ],
      "expiration_time": "2020-09-03T12:20:19.442Z",
      "create_time": "2020-09-03T12:20:19.442Z",
      "update_time": "2020-09-03T12:20:19.442Z",
      "id": "inactiveUsers",
      "shared": true,
      "reported_by": {
        "id": "my-custom-IAM-scanner",
        "title": "IAMScanner",
        "url": "https://cloud.ibm.com/iam/users"
      },
      "finding": {
        "severity": "MEDIUM",
        "next_steps": [
          {
            "title": "Go to account user management",
            "url": "https://cloud.ibm.com/iam/users"
          },
          {
            "title": "Visit account user management"
          },
          {
            "title": "Validate and remove non-active users"
          }
        ]
      }
    }

List notes

List all the notes associated with the provider ID that you specify.

GET /v1/{account_id}/providers/{provider_id}/notes

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

Query Parameters

  • Number of notes to return in the list. The page_size value must be greater than 1.

    Constraints: value ≥ 2

  • Token to provide to skip to a particular spot in the list.

  • curl -X GET "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_id>/providers/<provider_id>/notes"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json' \
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>"
    };
    
    findingsAPIClient
      .listNotes(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • public class ListNotes {
    
        private ListNotes() { }
    
        public static void main(String[] args) {
            ListNotesOptions opts = new ListNotesOptions.Builder()
            .accountId("<account_ID>")
            .providerId("<provider_ID>")
            .build();
    
            Response<ApiListNotesResponse> resp = findingsApi.listNotes(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func ListNotes() {
      accountID :=  "<account_ID>"
      providerID := "<provider_ID>"
    
      listNotesOptions := service.NewListNotesOptions(accountID, providerID)
      listNotesOptions.SetPageSize(2)
    
      listNotesResult, listNotesResponse, err := service.ListNotes(listNotesOptions)
      if err != nil {
        fmt.Println(err)
        fmt.Println(listNotesResponse.Result)
        return
      }
    
      fmt.Println(listNotesResponse.Result)
      fmt.Println("Result: ", listNotesResult.Notes[0])
    }   
  • response = ibm_cloud_security_advisor.list_notes(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
    )
    
    print(response)

Response

Response including listed notes.

Status Code

  • The list of notes was retrieved successfully.

Example responses
  • {
      "next_page_token": null,
      "notes": [
        {
          "short_description": "Inactive user(s) in account",
          "long_description": "Non-active users listed in account",
          "kind": "FINDING",
          "related_url": [
            {
              "label": "IAMScanner",
              "url": "https://cloud.ibm.com/iam/users"
            }
          ],
          "expiration_time": "2020-09-03T12:20:19.442Z",
          "create_time": "2020-09-03T12:20:19.442Z",
          "update_time": "2020-09-03T12:20:19.442Z",
          "id": "inactiveUsers",
          "shared": true,
          "reported_by": {
            "id": "my-custom-IAM-scanner",
            "title": "IAMScanner",
            "url": "https://cloud.ibm.com/iam/users"
          },
          "finding": {
            "severity": "MEDIUM",
            "next_steps": [
              {
                "title": "Go to account user management",
                "url": "https://cloud.ibm.com/iam/users"
              },
              {
                "title": "Visit account user management"
              },
              {
                "title": "Validate and remove non-active users"
              }
            ]
          }
        }
      ]
    }

Get a note

Get details of a note associated with the note ID and provider ID that you specify.

GET /v1/{account_id}/providers/{provider_id}/notes/{note_id}

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

  • The ID that uniquely identifies the note.

  • curl -X GET "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers/<provider_ID>/notes/<notes_ID>"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public final class GetNote {
    
        private GetNote() { }
    
        public static void main(String[] args) {
            GetNoteOptions opts = new GetNoteOptions.Builder()
            .accountId("<account_ID>")
            .providerId("<provider_ID>")
            .noteId("<note_ID>")
            .build();
    
            Response<GetNoteResponse> resp = findingsApi.getNote(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func GetNote() {
      accountID := "<account_ID>"
      providerID := "<provider_ID>"
      noteID := "<note_ID>"
    
      getNotesOptions := service.NewGetNoteOptions(accountID, providerID, noteID)
    
      result, response, err := service.GetNote(getNotesOptions)
      if err != nil {
        fmt.Println(err)
        fmt.Println(response.Result)
        return
      }
    
      fmt.Println(response.Result)
      fmt.Println(*result.Kind)
      fmt.Println(*result.ID)
    
    }  
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      noteId: "<note_ID>"
    };
    
    findingsAPIClient
      .getNote(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.get_note(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      note_id="<note_ID>"
    )
    
    print(response)

Response

Provides a detailed description of a note.

Status Code

  • The note was retrieved successfully.

Example responses
  • {
      "short_description": "Inactive user(s) in account",
      "long_description": "Non-active users listed in account",
      "kind": "FINDING",
      "related_url": [
        {
          "label": "IAMScanner",
          "url": "https://cloud.ibm.com/iam/users"
        }
      ],
      "expiration_time": "2020-09-03T12:20:19.442Z",
      "create_time": "2020-09-03T12:20:19.442Z",
      "update_time": "2020-09-03T12:20:19.442Z",
      "id": "inactiveUsers",
      "shared": true,
      "reported_by": {
        "id": "my-custom-IAM-scanner",
        "title": "IAMScanner",
        "url": "https://cloud.ibm.com/iam/users"
      },
      "finding": {
        "severity": "MEDIUM",
        "next_steps": [
          {
            "title": "Go to account user management",
            "url": "https://cloud.ibm.com/iam/users"
          },
          {
            "title": "Visit account user management"
          },
          {
            "title": "Validate and remove non-active users"
          }
        ]
      }
    }

Update a note

Update a note.

PUT /v1/{account_id}/providers/{provider_id}/notes/{note_id}

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

  • The ID that uniquely identifies the note.

Body for updating a note.

  • curl -X PUT "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_id>/providers/<provider_id>/notes/<note_ID>"   -H 'accept: application/json'   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'   -d '{
            "kind": "FINDING",
            "short_description": "LogDNA errors",
            "long_description": "We found errors in LogDNA logs, indicating possible security problems",
            "id": "<note_ID>",
            "reported_by": {
                "id": "my-custom-logdna-scanner",
                "title": "LogDNAScanner"
            },
            "finding": {
              "severity": "MEDIUM",
              "next_steps": [
                {
                  "title": "Go to the LogDNA dashboard",
                  "url": "https://cloud.ibm.com/observe/activitytracker"
                },
                {
                  "title": "Review LogDNA logs"
                }
              ]
            }
          }'
  • public class UpdateNote {
    
        private UpdateNote() { }
    
        public static void main(String[] args) {
            UpdateNoteOptions opts = new UpdateNoteOptions.Builder()
            .accountId("<account_ID>")
            .providerId("<provider_ID>")
            .noteId("<note_ID>")
            .shortDescription("LogDNA errors")
            .longDescription("We found errors in LogDNA logs, indicating possible security problems")
            .kind("FINDING")
            .id("logdna")
            .severity(new java.util.ArrayList<String>(java.util.Arrays.asList("MEDIUM")))
            .build();
    
            Response<UpdateNoteResponse> resp = findingsApi.updateNote(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func UpdateNote() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/json"
    
      accountID := "<account_ID>"
      providerID := "my-custom-security-tool"
      noteID := accountID + "/providers/my-custom-security-tool/notes/logdna"
      shortDescription := "LogDNA errors"
      longDescription := "We found errors in LogDNA logs, indicating possible security problems"
      kind := "FINDING"
      id := "logdna"
      reportedBy, _ := service.NewReporter("LogDNAScanner", "https://example.cp")
      remediationTitle := "Review LogDNA logs"
      remediationURL := "https://cloud.ibm.com/observe/activitytracker"
      nextStep := []findingsapiv1.RemediationStep{{Title: &remediationTitle, URL: &remediationURL}}
      severity := "MEDIUM"
      finding := findingsapiv1.FindingType{Severity: &severity, NextSteps: nextStep}
    
      var updateNoteOptions = service.NewUpdateNoteOptions(accountID, providerID, noteID, shortDescription, longDescription, kind, id, reportedBy)
      updateNoteOptions.SetHeaders(headers)
      updateNoteOptions.SetAccountID(accountID)
      updateNoteOptions.SetFinding(&finding)
    
      result, response, operationErr := service.UpdateNote(updateNoteOptions)
      if operationErr != nil {
        fmt.Println("Failed to edit note: ", operationErr)
        fmt.Println(response.Result)
      } else {
        fmt.Println(*result.ShortDescription)
        fmt.Println(result)
        fmt.Println(response.StatusCode)
    
      }
    }   
  • const params = {
      accountId: "<account_ID>",
      providerId: "my-custom-security-tool",
      newId: "logdna"
      newKind: "FINDING",
      newShortDescription: "LogDNA errors",
      newLongDescription: "We found errors in LogDNA logs, indicating possible security problems",
      newReportedBy: {
        newId: "my-custom-logdna-scanner",
        title: "LogDNAScanner"
      },
      newFinding: {
        severity: "MEDIUM",
        next_steps: [{
          title: "Go to the LogDNA dashboard",
          url: "https://cloud.ibm.com/observe/activitytracker"
          },
          {
          title: "Review LogDNA logs"
          }
        }]
      }
    };
    
    findingsAPIClient
      .updateNote(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.update_note(
      account_id="<account_ID>",
      provider_id="my-custom-security-tool",
      short_description="LogDNA errors",
      long_description="We found errors in LogDNA logs, indicating possible security problems",
      kind="FINDING",
      id="logdna",
      reported_by={
        'id':'my-custom-logdna-scanner',
        'title':'LogDNAScanner',
        'url':'https://example.com'
      },
      finding={
          "severity": "MEDIUM",
          "next_steps": [
            {
              "title": "Review LogDNA logs",
              "url": "https://cloud.ibm.com/observe/activitytracker"
            }
          ]
      }
    )
    
    print(response)

Response

Provides a detailed description of a note.

Status Code

  • The note was updated successfully.

Example responses
  • {
      "short_description": "LogDNA errors",
      "long_description": "We found errors in LogDNA logs, indicating possible security problems",
      "kind": "FINDING",
      "related_url": [
        {
          "label": "LogDNAScanner",
          "url": "https://example.com"
        }
      ],
      "expiration_time": "2020-09-03T12:20:19.442Z",
      "create_time": "2020-09-03T12:20:19.442Z",
      "update_time": "2020-09-03T12:20:19.442Z",
      "id": "logdna",
      "shared": true,
      "reported_by": {
        "id": "my-custom-logdna-scanner",
        "title": "LogDNAScanner",
        "url": "https://example.com"
      },
      "finding": {
        "severity": "MEDIUM",
        "next_steps": [
          {
            "title": "Review LogDNA logs",
            "url": "https://cloud.ibm.com/observe/activitytracker"
          }
        ]
      }
    }

Delete a note

Delete a note with ID and provider ID that you specify.

DELETE /v1/{account_id}/providers/{provider_id}/notes/{note_id}

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

  • The ID that uniquely identifies the note.

  • curl -X DELETE "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_id>/providers/<provider_ID>/notes/<note_ID>"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public class DeleteNote {
    
        private DeleteNote() { }
    
        public static void main(String[] args) {
            DeleteNoteOptions opts = new DeleteNoteOptions.Builder()
                .accountId("<account_ID>")
                .providerId("<provider_ID>")
                .noteId("<note_ID>")
                .build();
    
            Response<Void> resp = findingsApi.deleteNote(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func DeleteNote() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/json"
    
      accountID := "<account_ID>"
      providerID := "<provider_ID>"
      noteID := "<note_ID>"
    
      var deleteOptions = service.NewDeleteNoteOptions(accountID, providerID, noteID)
      response, err := service.DeleteNote(deleteOptions)
      if err != nil {
        fmt.Println("Failed to delete newly created note with error: ", err)
        fmt.Println(response.Result)
      } else {
        fmt.Println(response.StatusCode)
      }
    }  
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      noteId: "<note_ID>"
    };
    
    findingsAPIClient
      .deleteNote(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.delete_note(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      note_id="<note_ID>",
    )
    
    print(response)

Response

Status Code

  • The note was deleted successfully.

Example responses
  • {}

Get an occurrence note

Retrieves a note that is associated with the occurrence ID that you specify.

GET /v1/{account_id}/providers/{provider_id}/occurrences/{occurrence_id}/note

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

  • The ID that uniquely identifies the occurrence.

  • curl -X GET "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_id>/providers/<provider_ID>/occurrences/<occurrence_ID>/note"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public final class GetOccurrenceNote {
    
        private GetOccurrenceNote() { }
    
        public static void main(String[] args) {
            GetOccurrenceNoteOptions opts = new GetOccurrenceNoteOptions.Builder()
            .accountId("<account_ID>")
            .providerId("<provider_ID>")
            .occurrenceId("<occurrence_ID")
            .build();
    
            Response<GetOccurrenceNoteResponse> resp = findingsApi.getOccurrenceNote(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func GetOccurrenceNote() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/json"
    
      accountID := "<account_ID>"
      providerID := "<provider_ID>"
      occID := "<occurrence_ID>"
    
      var getOccurrenceNoteOptions = service.NewGetOccurrenceNoteOptions(accountID, providerID, occID)
    
      res, response, err := service.GetOccurrenceNote(getOccurrenceNoteOptions)
      if err != nil {
        fmt.Println("Failed to GetOccurrenceNote, err: ", err)
        fmt.Println(response.Result)
      } else {
        fmt.Println(response.StatusCode)
        fmt.Println(*res.ID)
        fmt.Println(*res.Kind)
        fmt.Println(*res.ShortDescription)
      }
    
    }  
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      occurrenceId: "<occurrence_ID>"
    };
    
    findingsAPIClient
      .getOccurrenceNote(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.get_occurrence_note(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      occurrence_id="<occurrence_ID>",
    )
    
    print(response)

Response

Provides a detailed description of a note.

Status Code

  • The note was retrieved successfully.

Example responses
  • {
      "short_description": "Inactive user(s) in account",
      "long_description": "Non-active users listed in account",
      "kind": "FINDING",
      "related_url": [
        {
          "label": "IAMScanner",
          "url": "https://cloud.ibm.com/iam/users"
        }
      ],
      "expiration_time": "2020-09-03T12:20:19.442Z",
      "create_time": "2020-09-03T12:20:19.442Z",
      "update_time": "2020-09-03T12:20:19.442Z",
      "id": "inactiveUsers",
      "shared": true,
      "reported_by": {
        "id": "my-custom-IAM-scanner",
        "title": "IAMScanner",
        "url": "https://cloud.ibm.com/iam/users"
      },
      "finding": {
        "severity": "MEDIUM",
        "next_steps": [
          {
            "title": "Go to account user management",
            "url": "https://cloud.ibm.com/iam/users"
          },
          {
            "title": "Visit account user management"
          },
          {
            "title": "Validate and remove non-active users"
          }
        ]
      }
    }

Create an occurrence

An occurrence describes provider-specific details of a note and contains the vulnerability details, remediation steps, and other general information. Create an occurrence to denote the existence of a particular type of finding.

POST /v1/{account_id}/providers/{provider_id}/occurrences

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

  • If set to true, this parameter allows replacing an existing occurrence.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

Body for occurrence creation.

  • curl -X POST "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers/<provider_ID>/occurrences"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'   -H 'Accept: application/json'
      -d '{
            "note_name": "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
            "kind": "FINDING",
            "id": "<occurrence_ID>",
            "context": {},
            "finding": {
              "severity": "LOW",
              "next_steps": [
                {
                  "title": "Remediation title",
                  "url": "https://example.com"
                }
              ]
            } 
          }'
  • public class CreateOccurrence {
    
        private CreateOccurrence() { }
    
        public static void main(String[] args) {
    
            RemediationStep remediationStepModel = new RemediationStep.Builder()
                .title("Remediation title")
                .url("https://example.com")
                .build();
    
            Finding findingModel = new Finding.Builder()
                .severity("MEDIUM")
                .certainty("LOW")
                .nextSteps(new java.util.ArrayList<RemediationStep>(java.util.Arrays.asList(remediationStepModel)))
                .build();
    
            CreateOccurrenceOptions createOccurrenceOptionsModel = new CreateOccurrenceOptions.Builder()
                .accountId("<account_ID>")
                .providerId("<provider_ID")
                .noteName("<account_ID>" + "/providers" + "/<provider_ID>/notes/" + "custom-name")
                .kind("FINDING")
                .id("test-finding")
                .resourceUrl("https://cloud.ibm.com")
                .remediation(remediationStepModel)
                .finding(findingModel)
                .replaceIfExists(true)
                .build();
    
            Response<ApiOccurrence> resp = findingsApi.createOccurrence(createOccurrenceOptionsModel).execute();
            System.out.println(resp.getResult());
        }
    }
  • func CreateFindingOccurrence() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/json"
    
      accountID := "<account_ID>"
      providerID := "<provider_ID>"
      ID := "test-finding"
      noteName := accountID + "/providers/<provider_ID>/notes/custom-note"
      kind := "FINDING"
      remediationTitle := "Remediation title"
      remediationURL := "https://example.com"
      nextStep := []findingsapiv1.RemediationStep{{Title: &remediationTitle, URL: &remediationURL}}
      severity := "MEDIUM"
      certainity := "LOW"
      finding := findingsapiv1.Finding{Severity: &severity, Certainty: &certainity, NextSteps: nextStep}
      region := "us-south"
      resourceType := "cluster"
      resourceName := "test"
      context := findingsapiv1.Context{Region: &region, ResourceType: &resourceType, ResourceName: &resourceName}
    
      var createOccurrenceOptions = service.NewCreateOccurrenceOptions(accountID, providerID, noteName, kind, ID)
      createOccurrenceOptions.SetHeaders(headers)
      createOccurrenceOptions.SetAccountID(accountID)
      createOccurrenceOptions.SetFinding(&finding)
      createOccurrenceOptions.SetContext(&context)
    
      result, response, operationErr := service.CreateOccurrence(createOccurrenceOptions)
      if operationErr != nil {
        fmt.Println("Failed to create occurrence: ", operationErr)
        fmt.Println(response.Result)
      } else {
        fmt.Println(response.StatusCode)
        fmt.Println(*result.ID)
      }
    }   
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      noteName: "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
      newKind: "FINDING",
      newId: "<occurrence_ID>",
      newFinding: {
        severity: "LOW",
        next_steps: [{
          title: "Remediation title",
          url: "https://example.com"
          }
        }]
      }
    };
    
    findingsAPIClient
      .createOccurrence(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.create_occurrence(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      note_name="<account_ID>/providers/<provider_ID>/notes/<note_ID>",
      kind="FINDING",
      id="<occurrence_ID>",
      finding={
          "severity": "LOW",
          "next_steps": [
            {
              "title": "Remediation title",
              "url": "https://example.com"
            }
          ]
      }
    )
    
    print(response)

Response

Information about analysis occurrences for an image.

Status Code

  • The occurrence was created successfully.

Example responses
  • {
      "author": {
        "account_id": "<account_ID>",
        "email": "user@ibm.com",
        "id": "IBMid-8880003AMTP",
        "kind": "user"
      },
      "note_name": "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
      "kind": "FINDING",
      "create_time": "2020-09-03T12:18:38.325Z",
      "create_timestamp": "2020-09-03T12:18:38.325Z",
      "update_time": "2020-09-03T12:18:38.325Z",
      "id": "finding_note_occurrence",
      "context": {
        "region": "us-south",
        "resource_crn": "resource_crn",
        "resource_id": "372e62838e57e8e918788c49cfd94e52",
        "resource_name": "LogDNAScanner",
        "resource_type": "type",
        "service_crn": "crn",
        "service_name": "LogDNA"
      },
      "finding": {
        "severity": "LOW",
        "certainty": "LOW",
        "next_steps": [
          {
            "title": "Remediation title",
            "url": "https://example.com"
          }
        ]
      },
      "insertion_timestamp": 1596803278031,
      "long_description": "We found errors in LogDNA logs, indicating possible security problems",
      "short_description": "LogDNA errors",
      "name": "<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>",
      "provider_id": "<provider_ID>",
      "reported_by": {
        "id": "my-custom-logdna-scanner",
        "title": "LogDNAScanner",
        "url": "https://example.com"
      },
      "resource_url": "https://example.com",
      "update_timestamp": 1596803278031,
      "update_week_date": "2020-W32-5"
    }

List occurrences

List all of the occurrences that are associated with the provider ID that you specify.

GET /v1/{account_id}/providers/{provider_id}/occurrences

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

Query Parameters

  • Number of occurrences to return in the list. page_size value should be greater than 1. In case of 0 and 1, status code 400 will be thrown.

    Constraints: value ≥ 2

  • Token to provide to skip to a particular spot in the list.

  • curl -X GET "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers/<provider_ID>/occurrences"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public class ListOccurrences {
    
        private ListOccurrences() { }
    
        public static void main(String[] args) {
            ListOccurrencesOptions opts = new ListOccurrencesOptions.Builder()
            .accountId("<account_ID>")
            .providerId("<provider_ID>")
            .build();
    
            Response<ApiListOccurrencesResponse> resp = findingsApi.listOccurrences(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func GetProviderOccurrences() {
      accountID := "<account_ID>"
      providerID := "<provider_ID"
    
      listProviderOccurrencesOptions := service.NewListOccurrencesOptions(accountID, providerID)
      listProviderOccurrencesOptions.SetPageSize(2)
      res, detailedResponse, err := service.ListOccurrences(listProviderOccurrencesOptions)
      if err != nil {
        fmt.Println(err)
        fmt.Println(detailedResponse.Result)
      }
    
      fmt.Println(len(res.Occurrences))
      fmt.Println(*res.Occurrences[0].ID)
      fmt.Println(*res.Occurrences[1].ID)
      // fmt.Println(*res.NextPageToken)
      fmt.Println(detailedResponse.StatusCode)
    }  
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>"
    };
    
    findingsAPIClient
      .listOccurrences(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.list_occurrences(
      account_id="<account_ID>",
      provider_id="<provider_ID>"
    )
    
    print(response)

Response

Response including listed active occurrences.

Status Code

  • The list of active occurrences was retrieved successfully.

Example responses
  • {
      "next_page_token": null,
      "occurrences": [
        {
          "author": {
            "account_id": "<account_ID>",
            "email": "user@ibm.com",
            "id": "IBMid-8880003AMTP",
            "kind": "user"
          },
          "note_name": "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
          "kind": "FINDING",
          "create_time": "2020-09-03T12:18:38.325Z",
          "create_timestamp": "2020-09-03T12:18:38.325Z",
          "update_time": "2020-09-03T12:18:38.325Z",
          "id": "finding_note_occurrence",
          "context": {
            "region": "us-south",
            "resource_crn": "resource_crn",
            "resource_id": "372e62838e57e8e918788c49cfd94e52",
            "resource_name": "LogDNAScanner",
            "resource_type": "type",
            "service_crn": "crn",
            "service_name": "LogDNA"
          },
          "finding": {
            "severity": "LOW",
            "certainty": "LOW",
            "next_steps": [
              {
                "title": "Remediation title",
                "url": "https://example.com"
              }
            ]
          },
          "insertion_timestamp": 1596803278031,
          "long_description": "We found errors in LogDNA logs, indicating possible security problems",
          "short_description": "LogDNA errors",
          "name": "<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>",
          "provider_id": "<provider_ID>",
          "reported_by": {
            "id": "my-custom-logdna-scanner",
            "title": "LogDNAScanner",
            "url": "https://example.com"
          },
          "resource_url": "https://example.com",
          "update_timestamp": 1596803278031,
          "update_week_date": "2020-W32-5"
        }
      ]
    }

List note occurrences

Retrieves a list of occurrences that are associated with the note ID that you specify.

GET /v1/{account_id}/providers/{provider_id}/notes/{note_id}/occurrences

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

  • The ID that uniquely identifies the note.

Query Parameters

  • Number of notes to return in the list. The page_size value must be greater than 1.

    Constraints: value ≥ 2

  • Token to provide to skip to a particular spot in the list.

  • curl -X GET "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers/<provider_ID>/notes/<note_ID>/occurrences"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public class ListNoteOccurrences {
    
        private ListNoteOccurrences() { }
    
        public static void main(String[] args) {
            ListNoteOccurrencesOptions opts = new ListNoteOccurrencesOptions.Builder()
            .accountId("<account_ID>")
            .providerId("<provider_ID>")
            .noteId("<note_ID>")
            .build();
    
            Response<ApiListNoteOccurrencesResponse> resp = findingsApi.listNoteOccurrences(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func GetNoteOccurrences() {
      accountID := "<account_ID>"
      providerID := "<provider_ID>"
      noteID := "<note_ID>"
    
      listNoteOccurrencesOptions := service.NewListNoteOccurrencesOptions(accountID, providerID, noteID)
      listNoteOccurrencesOptions.SetPageSize(2)
      res, detailedResponse, err := service.ListNoteOccurrences(listNoteOccurrencesOptions)
      if err != nil {
        fmt.Println(err)
        fmt.Println(detailedResponse.Result)
      }
    
      fmt.Println(len(res.Occurrences))
      fmt.Println(*res.Occurrences[0].ID)
      fmt.Println(*res.Occurrences[1].ID)
      // fmt.Println(*res.NextPageToken)
      fmt.Println(detailedResponse.StatusCode)
    
    }  
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      noteId: "<note_ID>"
    };
    
    findingsAPIClient
      .listNoteOccurrences(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.list_note_occurrences(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      note_id="<note_ID>"
    )
    
    print(response)

Response

Response including listed occurrences for a note.

Status Code

  • The note occurrences were retrieved successfully.

Example responses
  • {
      "next_page_token": null,
      "occurrences": [
        {
          "author": {
            "account_id": "<account_ID>",
            "email": "user@ibm.com",
            "id": "IBMid-8880003AMTP",
            "kind": "user"
          },
          "note_name": "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
          "kind": "FINDING",
          "create_time": "2020-09-03T12:18:38.325Z",
          "create_timestamp": "2020-09-03T12:18:38.325Z",
          "update_time": "2020-09-03T12:18:38.325Z",
          "id": "finding_note_occurrence",
          "context": {
            "region": "us-south",
            "resource_crn": "resource_crn",
            "resource_id": "372e62838e57e8e918788c49cfd94e52",
            "resource_name": "LogDNAScanner",
            "resource_type": "type",
            "service_crn": "crn",
            "service_name": "LogDNA"
          },
          "finding": {
            "severity": "LOW",
            "certainty": "LOW",
            "next_steps": [
              {
                "title": "Remediation title",
                "url": "https://example.com"
              }
            ]
          },
          "insertion_timestamp": 1596803278031,
          "long_description": "We found errors in LogDNA logs, indicating possible security problems",
          "short_description": "LogDNA errors",
          "name": "<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>",
          "provider_id": "<provider_ID>",
          "reported_by": {
            "id": "my-custom-logdna-scanner",
            "title": "LogDNAScanner",
            "url": "https://example.com"
          },
          "resource_url": "https://example.com",
          "update_timestamp": 1596803278031,
          "update_week_date": "2020-W32-5"
        }
      ]
    }

Get an occurrence

Get the details of an occurrence with the ID and provider ID that you specify.

GET /v1/{account_id}/providers/{provider_id}/occurrences/{occurrence_id}

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

  • The ID that uniquely identifies the occurrence.

  • curl -X GET "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public final class GetOccurrence {
    
        private GetOccurrence() { }
    
        public static void main(String[] args) {
            GetOccurrenceOptions opts = new GetOccurrenceOptions.Builder()
            .accountId("<account_ID>")
            .providerId("<provider_ID>")
            .occurrenceId("<occurrence_ID>")
            .build();
    
            Response<GetOccurrenceResponse> resp = findingsApi.getOccurrence(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func GetOccurrence() {
      accountID := "<account_ID>"
      providerID := "<provider_ID>"
      occID := "<occurrence_ID>"
    
      getOccurrenceOptions := service.NewGetOccurrenceOptions(accountID, providerID, occID)
      res, detailedResponse, err := service.GetOccurrence(getOccurrenceOptions)
      if err != nil {
        fmt.Println(err)
        fmt.Println(detailedResponse.Result)
      }
    
      fmt.Println(res)
      fmt.Println(detailedResponse.Result) //type interface {}
      fmt.Println(*res.ID)
    }   
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      occurrenceId: "<occurrence_ID>"
    };
    
    findingsAPIClient
      .getOccurrence(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.get_occurrence(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      occurrence_id="<occurrence_ID>",
    )
    
    print(response)

Response

Information about analysis occurrences for an image.

Status Code

  • The occurrence was retrieved successfully.

Example responses
  • {
      "author": {
        "account_id": "<account_ID>",
        "email": "user@ibm.com",
        "id": "IBMid-8880003AMTP",
        "kind": "user"
      },
      "note_name": "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
      "kind": "FINDING",
      "create_time": "2020-09-03T12:18:38.325Z",
      "create_timestamp": "2020-09-03T12:18:38.325Z",
      "update_time": "2020-09-03T12:18:38.325Z",
      "id": "finding_note_occurrence",
      "context": {
        "region": "us-south",
        "resource_crn": "resource_crn",
        "resource_id": "372e62838e57e8e918788c49cfd94e52",
        "resource_name": "LogDNAScanner",
        "resource_type": "type",
        "service_crn": "crn",
        "service_name": "LogDNA"
      },
      "finding": {
        "severity": "LOW",
        "certainty": "LOW",
        "next_steps": [
          {
            "title": "Remediation title",
            "url": "https://example.com"
          }
        ]
      },
      "insertion_timestamp": 1596803278031,
      "long_description": "We found errors in LogDNA logs, indicating possible security problems",
      "short_description": "LogDNA errors",
      "name": "<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>",
      "provider_id": "<provider_ID>",
      "reported_by": {
        "id": "my-custom-logdna-scanner",
        "title": "LogDNAScanner",
        "url": "https://example.com"
      },
      "resource_url": "https://example.com",
      "update_timestamp": 1596803278031,
      "update_week_date": "2020-W32-5"
    }

Update an occurrence

Update an occurrence.

PUT /v1/{account_id}/providers/{provider_id}/occurrences/{occurrence_id}

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • The ID that uniquely identifies the provider.

  • The ID that uniquely identifies the occurrence.

Body for updating an occurence.

  • curl -X PUT "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'   -H 'Accept: application/json'
      -d '{
            "note_name": "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
            "kind": "FINDING",
            "id": "<occurrence_ID>",
            "finding": {
              "severity": "LOW",
              "next_steps": [
                {
                  "title": "Updated remediation title",
                  "url": "https://example.com"
                }
              ]
            } 
          }'
  • public class UpdateOccurrence {
    
        private UpdateOccurrence() { }
    
        public static void main(String[] args) {
    
            RemediationStep remediationStepModel = new RemediationStep.Builder()
                .title("Updated remediation title")
                .url("https://example.com")
                .build();
    
            Finding findingModel = new Finding.Builder()
                .severity("MEDIUM")
                .certainty("LOW")
                .nextSteps(new java.util.ArrayList<RemediationStep>(java.util.Arrays.asList(remediationStepModel)))
                .build();
    
            CreateOccurrenceOptions createOccurrenceOptionsModel = new CreateOccurrenceOptions.Builder()
                .accountId("<account_ID>")
                .providerId("<provider_ID")
                .noteName("<account_ID>" + "/providers" + "/<provider_ID>/notes/" + "custom-name")
                .kind("FINDING")
                .id("test-finding")
                .resourceUrl("https://cloud.ibm.com")
                .remediation(remediationStepModel)
                .finding(findingModel)
                .replaceIfExists(true)
                .build();
    
            Response<ApiOccurrence> resp = findingsApi.updateOccurrence(updateOccurrenceOptionsModel).execute();
            System.out.println(resp.getResult());
        }
    }
  • func UpdateOccurrence() {
      headers := make(map[string]string)
      headers["Content-Type"] = "application/json"
    
      accountID := "<account_ID>"
      providerID := "<provider-ID>"
      ID := "test-KPI"
      occID := accountID + "/providers/custom-provider/occurrences/test-KPI"
      noteName := accountID + "/providers/custom-provider/notes/custom-note-kpi"
      kind := "KPI"
      kpiValue := 3.0
      kpiTotal := 3.0
      kpi := findingsapiv1.Kpi{Value: &kpiValue, Total: &kpiTotal}
    
      var updateOccurrenceOptions = service.NewUpdateOccurrenceOptions(accountID, providerID, occID, noteName, kind, ID)
      updateOccurrenceOptions.SetHeaders(headers)
      updateOccurrenceOptions.SetKpi(&kpi)
    
      result, response, operationErr := service.UpdateOccurrence(updateOccurrenceOptions)
      if operationErr != nil {
        fmt.Println("Failed to edit occurrence: ", operationErr)
        fmt.Println(response.Result)
      }
      fmt.Println(response.StatusCode)
      fmt.Println(*result.Kpi.Value)
    }   
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      occurrenceId: "<occurrence_ID>",
      newId: "<occurrence_ID>"
      newKind: "FINDING",
      newNoteName: "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
      newFinding: {
        severity: "LOW",
        next_steps": [{
          title: "Updated remediation title",
          url: "https://example.com"
          }
        }]
      }
    };
    
    findingsAPIClient
      .updateOccurrence(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.update_occurrence(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      note_name="<account_ID>/providers/<provider_ID>/notes/<note_ID>",
      kind="FINDING",
      id="<occurrence_ID>",
      finding={
          "severity": "LOW",
          "next_steps": [
            {
              "title": "Remediation title",
              "url": "https://example.com"
            }
          ]
      }
    )
    
    print(response)

Response

Information about analysis occurrences for an image.

Status Code

  • The occurrence was updated successfully.

Example responses
  • {
      "author": {
        "account_id": "<account_ID>",
        "email": "user@ibm.com",
        "id": "IBMid-8880003AMTP",
        "kind": "user"
      },
      "note_name": "<account_ID>/providers/<provider_ID>/notes/<note_ID>",
      "kind": "FINDING",
      "create_time": "2020-09-03T12:18:38.325Z",
      "create_timestamp": "2020-09-03T12:18:38.325Z",
      "update_time": "2020-09-03T12:18:38.325Z",
      "id": "finding_note_occurrence",
      "context": {
        "region": "us-south",
        "resource_crn": "resource_crn",
        "resource_id": "372e62838e57e8e918788c49cfd94e52",
        "resource_name": "LogDNAScanner",
        "resource_type": "type",
        "service_crn": "crn",
        "service_name": "LogDNA"
      },
      "finding": {
        "severity": "LOW",
        "certainty": "LOW",
        "next_steps": [
          {
            "title": "Remediation title",
            "url": "https://example.com"
          }
        ]
      },
      "insertion_timestamp": 1596803278031,
      "long_description": "We found errors in LogDNA logs, indicating possible security problems",
      "short_description": "LogDNA errors",
      "name": "<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>",
      "provider_id": "<provider_ID>",
      "reported_by": {
        "id": "my-custom-logdna-scanner",
        "title": "LogDNAScanner",
        "url": "https://example.com"
      },
      "resource_url": "https://example.com",
      "update_timestamp": 1596803278031,
      "update_week_date": "2020-W32-5"
    }

Delete an occurrence

Delete an occurrence with the ID and provider ID that you specify.

DELETE /v1/{account_id}/providers/{provider_id}/occurrences/{occurrence_id}

Request

Custom Headers

  • Your Identity and Access Management (IAM) bearer token.

Path Parameters

  • Your IBM Cloud account ID.

  • First part of occurrence name: providers/{provider_id}/notes/{occurrence_id}

  • Second part of occurrence name: providers/{provider_id}/notes/{occurrence_id}

  • curl -X DELETE "https://<region>.secadvisor.cloud.ibm.com/findings/v1/<account_ID>/providers/<provider_ID>/occurrences/<occurrence_ID>"   -H 'Authorization: Bearer <IAM_token>'   -H 'Content-Type: application/json'
  • public class DeleteOccurrence {
    
        private DeleteOccurrence() { }
    
        public static void main(String[] args) {
            DeleteOccurrenceOptions opts = new DeleteOccurrenceOptions.Builder()
                .accountId("<account_ID>")
                .providerId("<provider_ID>")
                .occurrenceId("<occurrence_ID>")
                .build();
    
            Response<Void> resp = findingsApi.deleteOccurrence(opts).execute();
            System.out.println(resp.getResult());
        }
    }
  • func DeleteOccurrence() {
    
      accountID := "<account_ID>"
      providerID := "<provider_ID>"
      occID := "test-KPI"
    
      var deleteOptions = service.NewDeleteOccurrenceOptions(accountID, providerID, occID)
      response, err := service.DeleteOccurrence(deleteOptions)
      if err != nil || response.StatusCode != 200 {
        fmt.Println("Failed to delete occurrence with error: ", err)
        fmt.Println(response.Result)
      }
    
      fmt.Println(response.StatusCode)
    }   
  • const params = {
      accountId: "<account_ID>",
      providerId: "<provider_ID>",
      occurrenceId: "<occurrence_ID>"
    };
    
    findingsAPIClient
      .deleteOccurrence(params)
      .then(response => {
        console.log(JSON.stringify(response.result, null, 2));
      })
      .catch(err => {
        console.log('error: ', err);
      });
  • response = ibm_cloud_security_advisor.delete_occurrence(
      account_id="<account_ID>",
      provider_id="<provider_ID>",
      occurrence_id="<occurrence_ID>",
    )
    
    print(response)

Response

Status Code

  • The occurrence was deleted successfully.

Example responses
  • {}