Data Posture API Tutorial: Difference between revisions

From BigID Developer Portal
 
(4 intermediate revisions by the same user not shown)
Line 72: Line 72:
| '''dataSourceName''' || Affected resource
| '''dataSourceName''' || Affected resource
|}
|}
[ maybe more on this? ]


== 4. Mark Issues as Resolved ==
== 4. Mark Issues as Resolved ==
Line 163: Line 161:


== Code Samples ==
== Code Samples ==
<tabs>
<tab name="Python"><syntaxhighlight lang="python" line>
# Data Posture API Tutorial
import requests
import json
# --- 1. Setup and Authentication ---
# Base URL of the BigID API (training sandbox)
base_url = "https://developer.bigid.com/api/v1"
# Session token (replace SAMPLE with actual session token)
AUTH_TOKEN = "SAMPLE"
headers = {
    "Authorization": f"Bearer {AUTH_TOKEN}",
    "Content-Type": "application/json"
}
def get_issues(filters=None):
    """
    Fetches security cases from the actionable-insights endpoint.
   
    Args:
        filters (dict): A dictionary of query parameters like {'limit': 10, 'filter': '...'}.
   
    Returns:
        list: A list of case objects, or an empty list if none are found.
    """
    cases_url = f"{base_url}/actionable-insights/all-cases"
   
    try:
        response = requests.get(cases_url, headers=headers, params=filters)
        response.raise_for_status()
        issues = response.json()
        print(f"  -> Found {len(issues)} issues.")
        return issues
    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error occurred while fetching issues: {http_err}")
        return []
def move_issues_to_system(issues):
    """
    A placeholder function to simulate exporting issues to a third-party system.
   
    Args:
        issues (list): A list of case objects.
       
    Returns:
        list: A list of case IDs that were "exported".
    """
    exported_ids = []
    for issue in issues:
        case_id = issue.get("caseId")
        # Example mapping
        ticket_data = {
            "title": issue.get("caseLabel"),
            "priority": issue.get("severityLevel"),
            "description": f"Policy: {issue.get('policyName')}, Source: {issue.get('dataSourceName')}",
            "assignee": issue.get("assignee")
        }
        print(f"  -> Creating ticket for Case ID {case_id}: {ticket_data['title']}")
        exported_ids.append(case_id)
       
    print("  -> Simulation complete.")
    return exported_ids
def resolve_single_issue(case_id):
    """
    Marks a single case as resolved.
    """
    resolve_url = f"{base_url}/actionable-insights/case-status/{case_id}"
    payload = {
        "caseStatus": "resolved",
        "auditReason": f"Remediated and moved on {json.dumps(requests.get('http://worldtimeapi.org/api/ip').json()['datetime'])}"
    }
    try:
        response = requests.patch(resolve_url, headers=headers, json=payload)
        response.raise_for_status()
        print(f"  -> Successfully marked case {case_id} as resolved.")
        return True
    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error occurred while resolving case {case_id}: {http_err}")
        return False
def resolve_issues_in_bulk(policy_name):
    """
    Marks all open cases for a given policy name as resolved.
    """
    bulk_resolve_url = f"{base_url}/actionable-insights/cases:update" # Assuming 'update' is the actionType
    payload = {
      "type": "CasesDB",
      "subType": "updateCases",
      "additionalProperties": {
        "field": "caseStatus", # Field to update
        "newValue": "resolved", # New value
        "casesFilters": [
          {
            "filterField": "policyName",
            "filterValues": [ policy_name ]
          },
          {
            "filterField": "caseStatus",
            "filterValues": [ "open" ] # Only target open cases
          }
        ]
      }
    }
    try:
        response = requests.patch(bulk_resolve_url, headers=headers, json=payload)
        response.raise_for_status()
        updated_cases = response.json()
        print(f"  -> Successfully resolved {len(updated_cases.get('caseIds', []))} cases in bulk.")
        return updated_cases
    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error occurred during bulk resolve: {http_err}")
        return None
# --- Main Workflow ---
if __name__ == "__main__":
    # 2. Retrieve the first 5 open issues for demonstration
    open_issues = get_issues(filters={'limit': 5, 'filter': '{"caseStatus": "open"}'})
    if open_issues:
        # 3. Simulate exporting these issues
        exported_case_ids = export_issues_to_system(open_issues)
       
        # 4. Mark issues as resolved
        if exported_case_ids:
            # Option A: Resolve the first exported issue individually
            resolve_single_issue(exported_case_ids[0])
           
            # Option B: Resolve all issues for a specific policy in bulk
            # We'll use the policy from the second issue as an example
            if len(open_issues) > 1:
                example_policy = open_issues[1].get("policyName")
                if example_policy:
                    resolve_issues_in_bulk(example_policy)
</syntaxhighlight></tab>
<tab name="JavaScript"><syntaxhighlight lang="javascript" line>
// Data Posture API Tutorial
// --- 1. Setup and Authentication ---
// Base URL of the BigID API (training sandbox)
const base_url = "https://developer.bigid.com/api/v1";
// Session token (replace SAMPLE with actual session token)
const AUTH_TOKEN = "SAMPLE";
const headers = {
    "Authorization": `Bearer ${AUTH_TOKEN}`,
    "Content-Type": "application/json"
};
/**
* Fetches security cases from the actionable-insights endpoint.
* @param {URLSearchParams} params - Query parameters for the request.
* @returns {Promise<Array>} A list of case objects, or an empty list if none are found.
*/
async function get_issues(params) {
    const cases_url = `${base_url}/actionable-insights/all-cases?${params}`;
    try {
        const response = await fetch(cases_url, { headers });
        if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
        const issues = await response.json();
        console.log(`  -> Found ${issues.length} issues.`);
        return issues;
    } catch (error) {
        console.error("HTTP error occurred while fetching issues:", error.message);
        return [];
    }
}
/**
* A placeholder function to simulate exporting issues to a third-party system.
* @param {Array} issues - A list of case objects.
* @returns {Array} A list of case IDs that were "exported".
*/
function move_issues_to_system(issues) {
    const exported_ids = issues.map(issue => {
        const case_id = issue.caseId;
        // Example mapping
        const ticket_data = {
            title: issue.caseLabel,
            priority: issue.severityLevel,
            description: `Policy: ${issue.policyName}, Source: ${issue.dataSourceName}`,
            assignee: issue.assignee
        };
        console.log(`  -> Creating ticket for Case ID ${case_id}: ${ticket_data.title}`);
        return case_id;
    });
    console.log("  -> Simulation complete.");
    return exported_ids;
}
/**
* Marks a single case as resolved.
* @param {string} case_id - The ID of the case to resolve.
*/
async function resolve_single_issue(case_id) {
    const resolve_url = `${base_url}/actionable-insights/case-status/${case_id}`;
    const timeResponse = await fetch('http://worldtimeapi.org/api/ip');
    const timeData = await timeResponse.json();
    const payload = {
        caseStatus: "resolved",
        auditReason: `Remediated and moved on ${timeData.datetime}`
    };
    try {
        const response = await fetch(resolve_url, { method: 'PATCH', headers, body: JSON.stringify(payload) });
        if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
        console.log(`  -> Successfully marked case ${case_id} as resolved.`);
        return true;
    } catch (error) {
        console.error(`HTTP error occurred while resolving case ${case_id}:`, error.message);
        return false;
    }
}
/**
* Marks all open cases for a given policy name as resolved.
* @param {string} policy_name - The name of the policy to filter by.
*/
async function resolve_issues_in_bulk(policy_name) {
    const bulk_resolve_url = `${base_url}/actionable-insights/cases:update`; // Assuming 'update' is the actionType
    const payload = {
      "type": "CasesDB",
      "subType": "updateCases",
      "additionalProperties": {
        "field": "caseStatus", // Field to update
        "newValue": "resolved", // New value
        "casesFilters": [
          { "filterField": "policyName", "filterValues": [policy_name] },
          { "filterField": "caseStatus", "filterValues": ["open"] } // Only target open cases
        ]
      }
    };
    try {
        const response = await fetch(bulk_resolve_url, { method: 'PATCH', headers, body: JSON.stringify(payload) });
        if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
        const updated_cases = await response.json();
        console.log(`  -> Successfully resolved ${updated_cases.caseIds?.length || 0} cases in bulk.`);
        return updated_cases;
    } catch (error) {
        console.error("HTTP error occurred during bulk resolve:", error.message);
        return null;
    }
}
// --- Main Workflow ---
async function runWorkflow() {
    // 2. Retrieve the first 5 open issues for demonstration
    const params = new URLSearchParams({
        limit: 5,
        filter: JSON.stringify({ "caseStatus": "open" })
    });
    const open_issues = await get_issues(params);
    if (open_issues.length > 0) {
        // 3. Simulate exporting these issues
        const exported_case_ids = move_issues_to_system(open_issues);
        // 4. Mark issues as resolved
        if (exported_case_ids.length > 0) {
            // Option A: Resolve the first exported issue individually
            await resolve_single_issue(exported_case_ids[0]);
            // Option B: Resolve all issues for a specific policy in bulk
            // We'll use the policy from the second issue as an example
            const example_policy = open_issues[1]?.policyName;
            if (example_policy) {
                await resolve_issues_in_bulk(example_policy);
            }
        }
    }
}
runWorkflow();
</syntaxhighlight>
</tab>
</tabs>
<html>
<style>
.tabs-tabbox > .tabs-container {
  margin-top: -1px;
  padding:
2px 6px;
  border-radius:
8px;
  position: relative;
  border:
2px solid #848484;
  width: inherit;
  max-width: inherit;
  min-width: inherit;
  box-shadow:
0px 4px 6px 1px rgba(0, 0, 0, 0.1);
  z-index: 1;
}
.tabs-tabbox > .tabs-label {
  margin:
0 3px;
  border-bottom:
none;
  border-radius:
4px 4px 0 0;
  position: relative;
  display: inline-block;
  vertical-align: bottom;
  padding-left: 10px;
  padding-right: 10px;
  padding-bottom: 3px;
  padding-top: 3px;
}
.tabs-tabbox > .tabs-input:checked + .tabs-label, .tabs-input-0:checked + .tabs-input-1 + .tabs-label {
  background-color: #0e69b2 !important;
  border-color:
#848484;
  z-index: 0;
  color: white;
}
.tabs-label {
  cursor: pointer;
  border:
2px solid #848484;
}
.mw-body .tabs-label {
  background-color: #ffffff26;
}
</style>
</html>


== Summary ==
== Summary ==
Congratulations! In this tutorial, you have learned how to retrieve open security issues from BigID, export those issues to a third-party system for remediation, and mark the issues as resolved in BigID to keep your backlog clean and accurate. By following these steps, you can streamline your remediation process, reduce manual effort, and maintain a clear, up-to-date view of your organization’s security posture.
Congratulations! In this tutorial, you have learned how to retrieve open security issues from BigID, export those issues to a third-party system for remediation, and mark the issues as resolved in BigID to keep your backlog clean and accurate. By following these steps, you can streamline your remediation process, reduce manual effort, and maintain a clear, up-to-date view of your organization’s security posture.

Latest revision as of 14:12, 5 August 2025

In this article, you'll learn:

  • How to retrieve security issues from the Data Posture API.
  • How to export relevant issues to a third-party system.
  • How to use the Apply Action API to update multiple issues at once.
  • How to mark issues as resolved after export to keep BigID in sync.


scenarioYou’re part of the security team managing your organization’s data security posture. Each week, BigID identifies new issues like exposed sensitive data or misconfigurations. Your team handles remediation in a third-party system like Jira or ServiceNow, so you need a way to export these issues from BigID, assign them for follow-up, and mark them as resolved to keep your backlog clean and accurate.

In this tutorial, we'll use SAMPLE as our session token. This is unique to the training sandbox and will not work in other environments. See BigID API/Tutorial for information on authenticating with BigID.

To view the complete code for all steps, see the section labelled Code Samples.

For more information on the API capabilities used in this tutorial, check out the Data Posture API Docs.

1. Authenticate Using Your API Key

All API requests require authentication using a valid API key. Refer to BigID Documentation to obtain your token. Then, define the Authorization header using the format Authorization: Bearer YOUR_API_KEY. This header must be included in every request to ensure proper authentication and access to BigID’s API endpoints. Throughout the tutorial, we will be using SAMPLE as our token.

2. Retrieve Security Issues

There are multiple endpoints available for fetching security cases, but because our goal is to export these issues to a third party system, we want to use the GET /api/v1/actionable-insights/all-cases. This will allow us to fetch all existing security issues, as well as limit the selection based on various parameters if necessary.

In the case that you do not want to fetch all cases, you can filter the response based on several parameters, all of which are outlined in the following table:

Parameter Type Description
skip integer Number of records to skip (for pagination)
limit integer Number of records to return
filter string BigID Query Language filter to narrow results
fields string Comma-separated list of fields to return
sort string Field to sort by, plus optional ASC/DESC
requireTotalCount boolean Whether to include totalCount in response

Once you have fetched the details for all of the security cases you are interested in, you can proceed to the next step.

3. Export Issues to Your Third-Party System

Once you retrieve the list of open security issues, the next step is to export them to your third-party system for remediation. This could be a ticketing platform like Jira, ServiceNow, or a SOAR tool for automated workflows.

For each issue, map the relevant fields to your third-party system’s API. Common mappings might include:

BigID Field Third-Party Field
caseLabel Ticket title
policyName Category or label
severityLevel Priority
assignee Assigned owner
dataSourceName Affected resource

4. Mark Issues as Resolved

After successfully exporting the issues, you’ll want to mark them as resolved in BigID to avoid duplicate work and keep the backlog clean. You have two options for marking issues as resolved using the API.

First, you can do so in bulk using the PATCH /api/v1/actionable-insights/cases:{actionType} endpoint. In order to use this endpoint, you should:

  1. In the request, tell BigID which field to update (in this case, caseStatus) and what the new value should be (set it to resolved).
  2. Add filters to select the cases you want to update, like policyName or caseStatus:open.
  3. Run the request. BigID will return the list of case IDs that were successfully updated.

For example, your request may be structured like the following:

{
  "type": "CasesDB",
  "subType": "updateCases",
  "additionalProperties": {
    "field": "assignee",
    "newValue": "[email protected]",
    "casesFilters": [
      {
        "filterField": "policyName",
        "filterValues": [
          "policy1234"
        ]
      },
      {
        "filterField": "caseStatus",
        "filterValues": [
          "remediated"
        ]
      }
    ]
  }
}

The following request uses the example request body above. To actually test this endpoint, replace the fields with real values based on the previous steps.

If you only need to update the status of specific cases, this can be done using the PATCH /api/v1/actionable-insights/case-status/{caseId} endpoint. To do so:

  1. Replace {caseId} with the actual ID of the case you want to update.
  2. In the request body, set caseStatus to resolved.
  3. Add an auditReason so your team knows why the change was made (for example, “Exported to Jira on July 14th”).

For example, your request may be structured like the following:

{
  "caseStatus": "resolved",
  "auditReason": "Exported to Jira on July 14th"
}

In the request below, the {caseId} is currently represented by a fake ID, 123abc. In order to test the endpoint, replace it with a case ID you have addressed in the previous steps.

5. Troubleshooting

If your request fails, here’s what the server might tell you, and how to fix it:

Status Code Example Response What It Means How to Fix It
200 Successful response with scan data Everything’s looking good! Keep cruising.
400 { "error": "Scan ID is invalid" } Bad or malformed scan ID provided Double-check the scan ID you’re using.
404 { "error": "Scan 1234 was not found" } Scan ID doesn’t exist Make sure the ID is valid and fetched from the parent scans endpoint.
401 Unauthorized API key missing or invalid Verify your API key and authorization header.
500 { "status": "error", "message": "Server error", "errors": [{}] } BigID server hit a snag (internal error) Wait a moment and retry. If it persists, reach out to support.

Code Samples

# Data Posture API Tutorial
import requests
import json

# --- 1. Setup and Authentication ---
# Base URL of the BigID API (training sandbox)
base_url = "https://developer.bigid.com/api/v1"
# Session token (replace SAMPLE with actual session token)
AUTH_TOKEN = "SAMPLE" 
headers = {
    "Authorization": f"Bearer {AUTH_TOKEN}",
    "Content-Type": "application/json"
}

def get_issues(filters=None):
    """
    Fetches security cases from the actionable-insights endpoint.
    
    Args:
        filters (dict): A dictionary of query parameters like {'limit': 10, 'filter': '...'}.
    
    Returns:
        list: A list of case objects, or an empty list if none are found.
    """
    cases_url = f"{base_url}/actionable-insights/all-cases"
    
    try:
        response = requests.get(cases_url, headers=headers, params=filters)
        response.raise_for_status()
        issues = response.json()
        print(f"  -> Found {len(issues)} issues.")
        return issues
    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error occurred while fetching issues: {http_err}")
        return []

def move_issues_to_system(issues):
    """
    A placeholder function to simulate exporting issues to a third-party system.
    
    Args:
        issues (list): A list of case objects.
        
    Returns:
        list: A list of case IDs that were "exported".
    """
    exported_ids = []
    for issue in issues:
        case_id = issue.get("caseId")
        # Example mapping
        ticket_data = {
            "title": issue.get("caseLabel"),
            "priority": issue.get("severityLevel"),
            "description": f"Policy: {issue.get('policyName')}, Source: {issue.get('dataSourceName')}",
            "assignee": issue.get("assignee")
        }
        print(f"  -> Creating ticket for Case ID {case_id}: {ticket_data['title']}")
        exported_ids.append(case_id)
        
    print("  -> Simulation complete.")
    return exported_ids

def resolve_single_issue(case_id):
    """
    Marks a single case as resolved.
    """
    resolve_url = f"{base_url}/actionable-insights/case-status/{case_id}"
    payload = {
        "caseStatus": "resolved",
        "auditReason": f"Remediated and moved on {json.dumps(requests.get('http://worldtimeapi.org/api/ip').json()['datetime'])}"
    }
    try:
        response = requests.patch(resolve_url, headers=headers, json=payload)
        response.raise_for_status()
        print(f"  -> Successfully marked case {case_id} as resolved.")
        return True
    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error occurred while resolving case {case_id}: {http_err}")
        return False

def resolve_issues_in_bulk(policy_name):
    """
    Marks all open cases for a given policy name as resolved.
    """
    bulk_resolve_url = f"{base_url}/actionable-insights/cases:update" # Assuming 'update' is the actionType
    payload = {
      "type": "CasesDB",
      "subType": "updateCases",
      "additionalProperties": {
        "field": "caseStatus", # Field to update
        "newValue": "resolved", # New value
        "casesFilters": [
          {
            "filterField": "policyName",
            "filterValues": [ policy_name ]
          },
          {
            "filterField": "caseStatus",
            "filterValues": [ "open" ] # Only target open cases
          }
        ]
      }
    }
    try:
        response = requests.patch(bulk_resolve_url, headers=headers, json=payload)
        response.raise_for_status()
        updated_cases = response.json()
        print(f"  -> Successfully resolved {len(updated_cases.get('caseIds', []))} cases in bulk.")
        return updated_cases
    except requests.exceptions.HTTPError as http_err:
        print(f"HTTP error occurred during bulk resolve: {http_err}")
        return None

# --- Main Workflow ---
if __name__ == "__main__":
    # 2. Retrieve the first 5 open issues for demonstration
    open_issues = get_issues(filters={'limit': 5, 'filter': '{"caseStatus": "open"}'})

    if open_issues:
        # 3. Simulate exporting these issues
        exported_case_ids = export_issues_to_system(open_issues)
        
        # 4. Mark issues as resolved
        if exported_case_ids:
            # Option A: Resolve the first exported issue individually
            resolve_single_issue(exported_case_ids[0])
            
            # Option B: Resolve all issues for a specific policy in bulk
            # We'll use the policy from the second issue as an example
            if len(open_issues) > 1:
                example_policy = open_issues[1].get("policyName")
                if example_policy:
                    resolve_issues_in_bulk(example_policy)
// Data Posture API Tutorial

// --- 1. Setup and Authentication ---
// Base URL of the BigID API (training sandbox)
const base_url = "https://developer.bigid.com/api/v1";
// Session token (replace SAMPLE with actual session token)
const AUTH_TOKEN = "SAMPLE";
const headers = {
    "Authorization": `Bearer ${AUTH_TOKEN}`,
    "Content-Type": "application/json"
};

/**
 * Fetches security cases from the actionable-insights endpoint.
 * @param {URLSearchParams} params - Query parameters for the request.
 * @returns {Promise<Array>} A list of case objects, or an empty list if none are found.
 */
async function get_issues(params) {
    const cases_url = `${base_url}/actionable-insights/all-cases?${params}`;
    try {
        const response = await fetch(cases_url, { headers });
        if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
        const issues = await response.json();
        console.log(`  -> Found ${issues.length} issues.`);
        return issues;
    } catch (error) {
        console.error("HTTP error occurred while fetching issues:", error.message);
        return [];
    }
}

/**
 * A placeholder function to simulate exporting issues to a third-party system.
 * @param {Array} issues - A list of case objects.
 * @returns {Array} A list of case IDs that were "exported".
 */
function move_issues_to_system(issues) {
    const exported_ids = issues.map(issue => {
        const case_id = issue.caseId;
        // Example mapping
        const ticket_data = {
            title: issue.caseLabel,
            priority: issue.severityLevel,
            description: `Policy: ${issue.policyName}, Source: ${issue.dataSourceName}`,
            assignee: issue.assignee
        };
        console.log(`  -> Creating ticket for Case ID ${case_id}: ${ticket_data.title}`);
        return case_id;
    });
    console.log("  -> Simulation complete.");
    return exported_ids;
}

/**
 * Marks a single case as resolved.
 * @param {string} case_id - The ID of the case to resolve.
 */
async function resolve_single_issue(case_id) {
    const resolve_url = `${base_url}/actionable-insights/case-status/${case_id}`;
    const timeResponse = await fetch('http://worldtimeapi.org/api/ip');
    const timeData = await timeResponse.json();
    const payload = {
        caseStatus: "resolved",
        auditReason: `Remediated and moved on ${timeData.datetime}`
    };
    try {
        const response = await fetch(resolve_url, { method: 'PATCH', headers, body: JSON.stringify(payload) });
        if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
        console.log(`  -> Successfully marked case ${case_id} as resolved.`);
        return true;
    } catch (error) {
        console.error(`HTTP error occurred while resolving case ${case_id}:`, error.message);
        return false;
    }
}

/**
 * Marks all open cases for a given policy name as resolved.
 * @param {string} policy_name - The name of the policy to filter by.
 */
async function resolve_issues_in_bulk(policy_name) {
    const bulk_resolve_url = `${base_url}/actionable-insights/cases:update`; // Assuming 'update' is the actionType
    const payload = {
      "type": "CasesDB",
      "subType": "updateCases",
      "additionalProperties": {
        "field": "caseStatus", // Field to update
        "newValue": "resolved", // New value
        "casesFilters": [
          { "filterField": "policyName", "filterValues": [policy_name] },
          { "filterField": "caseStatus", "filterValues": ["open"] } // Only target open cases
        ]
      }
    };
    try {
        const response = await fetch(bulk_resolve_url, { method: 'PATCH', headers, body: JSON.stringify(payload) });
        if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
        const updated_cases = await response.json();
        console.log(`  -> Successfully resolved ${updated_cases.caseIds?.length || 0} cases in bulk.`);
        return updated_cases;
    } catch (error) {
        console.error("HTTP error occurred during bulk resolve:", error.message);
        return null;
    }
}

// --- Main Workflow ---
async function runWorkflow() {
    // 2. Retrieve the first 5 open issues for demonstration
    const params = new URLSearchParams({
        limit: 5,
        filter: JSON.stringify({ "caseStatus": "open" })
    });
    const open_issues = await get_issues(params);

    if (open_issues.length > 0) {
        // 3. Simulate exporting these issues
        const exported_case_ids = move_issues_to_system(open_issues);

        // 4. Mark issues as resolved
        if (exported_case_ids.length > 0) {
            // Option A: Resolve the first exported issue individually
            await resolve_single_issue(exported_case_ids[0]);

            // Option B: Resolve all issues for a specific policy in bulk
            // We'll use the policy from the second issue as an example
            const example_policy = open_issues[1]?.policyName;
            if (example_policy) {
                await resolve_issues_in_bulk(example_policy);
            }
        }
    }
}

runWorkflow();

Summary

Congratulations! In this tutorial, you have learned how to retrieve open security issues from BigID, export those issues to a third-party system for remediation, and mark the issues as resolved in BigID to keep your backlog clean and accurate. By following these steps, you can streamline your remediation process, reduce manual effort, and maintain a clear, up-to-date view of your organization’s security posture.