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:
| 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:
| 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:
| 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.
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.