Integrate using webhooks

You can use webhooks to integrate with systems for remediation, reporting, and other functions.

Sophos Cloud Optix provides native integration for a variety of systems, for example Jira, Slack, Teams, and so on. If you're using a system for which there is no native integration, you can use a webhook to send alerts to it.

You must create an HTTP endpoint and authentication header values for the system you want to integrate. Sophos Cloud Optix uses these to send a webhook payload to your system.

To set up Sophos Cloud Optix to use your webhook, under Settings click Integrations > Webhooks and enter your webhook's details.

You can set up webhooks for each of your environments, for different alerts, and different severity levels.

You can change existing webhook endpoints. But if you change a webhook's Authentication Key or Authentication Value, you must delete the webhook and create a new one.

Data provided by the webhook

The Sophos Cloud Optix webhook payload format is standardized and contains an event type and the data associated with that event type. Currently the event type is always ALERT. You can write code, or configure your application, to interpret and act on the data in the payload.

The payload data for the ALERT event type is in JSON. The format is defined in the following table.

Key

Type

Description

Values

accountId

String

ID of the environment, or URL for the repo, for which the alert is raised

Example:

44412345678075

alertId

String

Unique alert identifier.

Example:

A-000001

score

Integer

Alert severity. The values correspond to the following severity categories in Sophos Cloud Optix:

  • Critical: score >= 90
  • High: score >= 80 and < 90
  • Medium: score >= 50 and < 80
  • Low: score < 50

0 - 100

alertSummary

String

Brief description of the alert

Example:

Ensure S3 buckets do not allow public read/list permission

alertType

String

Type of alert:

  • IaC: IaC Alerts
  • Policy: cloud environments alerts
  • Spend: Spend Monitoring alerts
  • Anomaly: AI system alerts
  • GuardDuty: AWS GuardDuty alerts

Choose from:

IaC

Policy

Spend

Anomaly

GuardDuty

lastSeen

DateTime

Timestamp of alert creation or last modification

Example:

Nov 2, 2020 3:56:18 PM

provider

String

Alert account type:

  • AWS: AWS account
  • Azure: Microsoft Azure subscription
  • IaC: IaC code repository
  • GCP: GCP project
  • Kubernetes: Native Kubernetes Cluster

Choose from:

AWS

Azure

IaC

GCP

Kubernetes

alertDetails

String

Additional details regarding the alert, for example the cloud resources affected

Example:

AWS

policyLabel

String

Comma-separated list of compliance tags assigned to the policies corresponding to the alert. Only available for Policy alert type.

Example:

FEDRAMP-HIGH,GDPR,ISO 27001,PCI,SOC2,SOC2-TSP,Sophos

ruleNumber

String

ID of violated rule in Sophos Cloud Optix. Only available for Policy alert type.

Example:

AR-251

affectedResources

JSONArray

Contains one or more instances of information about the entities affected by the alert.

Each instance of affectedResources is composed of a resourceInfo key and a state key.

These are documented below.

{
"resourceInfo": "demo-bucket-1",
"state": "OPEN"
}

resourceInfo

String

Contained by affectedResources.

Identifying information about a resource, for example type or name

Example:

demo-bucket-1

state

String

Contained by affectedResources.

Gives the state of the resource for which the alert is raised.

OPEN

SUPPRESS

The following is an example webhook payload for an AWS environment, caused by a violation of an S3 bucket permissions policy.

{
  "eventType": "ALERT",
  "payloadData": {
    "accountId": "44412345678075",
    "alertId": "A-000001",
    "score": 80,
    "alertSummary": "Ensure S3 buckets do not allow public read/list permission",
    "alertType": "Policy",
    "lastSeen": "Nov 2, 2020 3:56:18 PM",
    "provider": "AWS",
    "alertDetails": "demo-bucket-1\ndemo-bucket-2",
    "policyLabel": "FEDRAMP-HIGH,FEDRAMP-LOW,FEDRAMP-MODERATE,FEDRAMP/NIST800-53-LOW,FFIEC,GDPR,ISO 27001,PCI,SOC2,SOC2-TSP,Sophos",
    "ruleNumber": "AR-251",
    "affectedResources": [
      {
        "resourceInfo": "demo-bucket-1",
        "state": "OPEN"
      },
      {
        "resourceInfo": "demo-bucket-2",
        "state": "OPEN"
      }
    ]
  }
}

How to use the data provided by the webhook

This diagram and code snippet show an example of user-defined remediation for an alert in an AWS environment.


AWS webhook remediation environment diagram

The JavaScript snippet shows interpretation of the webhook payload generated when an S3 ACL alert is triggered, and the actions taken.

import boto3
 
s3 = boto3.client('s3')
 
def lambda_handler(event, context):
    if event['eventType'] == 'ALERT' and event['payloadData']['alertType'] == 'Policy':
        s3_acl_rule_ids = ['AR-251', 'AR-252', 'AR-267', 'AR-268']
        payload_data = event['payloadData']
        rule_id = payload_data['ruleNumber']
        if rule_id in s3_acl_rule_ids:
            all_users_grantee = 'http://acs.amazonaws.com/groups/global/AllUsers'
            update_acls = False
            affected_resources = payload_data['affectedResources']
            for affected_resource in affected_resources:
                if affected_resource['state'] == "OPEN":
                    try:
                        bucket = affected_resource['resourceInfo']
                        acls = s3.get_bucket_acl(Bucket = bucket)
                        grants = acls['Grants']
                        owner = acls['Owner']
                        for grant in grants:
                            permission = grant['Permission']
                            grantee = grant['Grantee']
                            if rule_id == 'AR-251' and permission in ['READ', 'FULL_CONTROL'] and grantee['Type'] == 'Group' and grantee['URI'] == all_users_grantee:
                                grants.remove(grant)
                                update_acls = True
                            elif rule_id == 'AR-252' and permission in ['READ_ACP', 'FULL_CONTROL'] and grantee['Type'] == 'Group' and grantee['URI'] == all_users_grantee:
                                grants.remove(grant)
                                update_acls = True
                            elif rule_id == 'AR-267' and permission in ['WRITE', 'FULL_CONTROL'] and grantee['Type'] == 'Group' and grantee['URI'] == all_users_grantee:
                                grants.remove(grant)
                                update_acls = True
                            elif rule_id == 'AR-268' and permission in ['WRITE_ACP', 'FULL_CONTROL'] and grantee['Type'] == 'Group' and grantee['URI'] == all_users_grantee:
                                grants.remove(grant)
                                update_acls = True
                         
                        if update_acls:
                            new_acls = {'Grants' : grants, 'Owner' : owner}
                            response = s3.put_bucket_acl(
                                Bucket = bucket,
                                AccessControlPolicy = new_acls
                            )
                    except Exception as e:
                        print(e)
                        raise e
                     
         
        return "Remediation successful"
Note You must ensure that the lambda has sufficient permissions over the resource types to run the remediation snippet.