Skip to content

Webhooks integration

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, 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.
    <br>{"resourceInfo": "demo-bucket-1", <br>"state": "OPEN"} <br>
    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

    Examples

    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"
            }
            ]
        }
    }
    

    The following is an example webhook payload for an AWS Storage Protection alert.

    {
      "eventType": "ALERT",
      "payloadData": {
        "accountId": "421146157129",
        "alertId": "A-1201196",
        "score": 80,
        "alertSummary": "High severity malware files have been detected in AWS S3 buckets",
        "alertType": "Serverless Storage",
        "lastSeen": "Sep 13, 2022 5:26:27 PM",
        "provider": "AWS",
        "alertDetails": "Following files have been detected as high severity malware : malware.txt"
        "affectedResources": [
          {
            "resourceInfo": "tests3malwarewebhookdata",
            "state": "OPEN",
            "affectedResourceJSON": "{\"affectedFiles\":[{\"fileName\":\"malware.txt\",\"objectKey\":\"malware.txt\",\"detectionStatus\":\"KNOWN\",\"identityName\":\"EICAR-AV-Test\"}]}"
          }
        ]
      }
    }
    

    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.