
AWS Security Hub OpenVEX Integration: Technical Guide
Integrating OpenVEX with AWS Security Hub enables smarter vulnerability management by reducing false positives and automating risk prioritization. This guide explores how to streamline security operations and enhance compliance with industry standards. Ready to optimize your security workflow?
vexctl
is used to manage OpenVEX documents:1
2
3
# Installation for Linux x86_64
curl -sSfL https://github.com/openvex/vexctl/releases/latest/download/vexctl_linux_amd64.tar.gz | tar xz
sudo mv vexctl /usr/local/bin/
1
2
3
4
5
6
7
vexctl create \
--product="pkg:docker/example/app@v1.0.0" \
--subcomponents="pkg:npm/express@4.17.1" \
--vuln="CVE-2022-24999" \
--status="not_affected" \
--justification="vulnerable_code_not_in_execute_path" \
output.vex.json
--product
: Main product identifier in SWID or PURL format--subcomponents
: Affected subcomponents--status
: One ofnot_affected
,affected
,fixed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
name: VEX Generation
on: [push]
jobs:
vex-generation:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install vexctl
run: |
curl -sSfL https://github.com/openvex/vexctl/releases/download/v0.5.2/vexctl_linux_amd64 > vexctl
chmod +x vexctl
- name: Generate VEX
run: |
./vexctl create \
--product="pkg:docker/${{ github.repository }}@${{ github.sha }}" \
--vuln="CVE-2023-12345" \
--status="not_affected" \
--justification="compiler_mitigations" \
vex_output.json
- name: Upload Artifact
uses: actions/upload-artifact@v3
with:
name: vex-document
path: vex_output.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def vex_to_asff(vex_doc):
findings = []
for statement in vex_doc['statements']:
finding = {
"SchemaVersion": "2018-10-08",
"Id": f"{statement['vulnerability']}-{statement['timestamp']}",
"ProductArn": "arn:aws:securityhub:region:account-id:product/account-id/default",
"GeneratorId": "OpenVEX",
"AwsAccountId": "123456789012",
"Types": ["Software and Configuration Checks/Vulnerabilities"],
"CreatedAt": statement['timestamp'],
"UpdatedAt": datetime.now().isoformat(),
"Severity": {
"Label": "INFORMATIONAL" if statement['status'] == 'not_affected' else "HIGH"
},
"Resources": [{
"Type": "Container",
"Id": statement['product']['@id']
}],
"Remediation": {
"Recommendation": {
"Text": f"VEX Status: {statement['status']} - {statement['justification']}"
}
}
}
findings.append(finding)
return findings
securityhub-vex-integration.yml
:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Resources:
VEXParserFunction:
Type: AWS::Lambda::Function
Properties:
Code:
ZipFile: |
import json
def lambda_handler(event, context):
# VEX to ASFF conversion logic
Runtime: python3.12
Handler: index.lambda_handler
MemorySize: 256
Timeout: 300
VEXEventRule:
Type: AWS::Events::Rule
Properties:
EventPattern:
source: ["aws.s3"]
detail-type: ["Object Created"]
detail:
bucket:
name: ["vex-documents-bucket"]
Targets:
- Arn: !GetAtt VEXParserFunction.Arn
1
2
3
4
5
6
7
8
9
# Create the stack
aws cloudformation create-stack \
--stack-name vex-securityhub \
--template-body file://securityhub-vex-integration.yml \
--capabilities CAPABILITY_IAM
# Test integration
aws s3 cp example.vex.json s3://vex-documents-bucket/
aws securityhub get-findings --filters '{"ProductName": [{"Value": "OpenVEX", "Comparison": "EQUALS"}]}'
1
2
3
4
5
vexctl merge \
--product="pkg:docker/example/app@1.2.0" \
build-time.vex.json \
deployment.vex.json \
merged.vex.json
1
2
3
FROM alpine:3.18
COPY *.vex.json /var/lib/vex/
RUN apk add --no-cache vexctl
1
docker scout cves myimage:latest --vex-location /var/lib/vex/
- Batch Processing: Processing batches every 5 minutes instead of per S3 event
- Caching Mechanism: DynamoDB-based caching for VEX documents
- Parallel Processing: Increasing Lambda concurrency limits
1
2
3
4
5
6
from concurrent.futures import ThreadPoolExecutor
def process_vex_chunk(chunk):
with ThreadPoolExecutor(max_workers=8) as executor:
results = list(executor.map(convert_to_asff, chunk))
return results
- IAM Role Policies:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "securityhub:BatchImportFindings",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "securityhub:*",
"Condition": {
"StringNotEquals": {
"aws:PrincipalOrgID": "o-xxxxxxxxxx"
}
}
}
]
}
- VEX Document Validation:
1
vexctl validate --schema https://openvex.dev/schema/vex-1.0.0.json document.vex.json
- CloudWatch Metrics:
VEXDocumentsProcessed
FindingsImported
ConversionErrors
- Error Scenarios:
1
2
3
4
5
try:
process_vex_document(content)
except VEXSchemaError as e:
logger.error(f"Schema validation failed: {e}")
raise VEXProcessingError("Invalid VEX format") from e
- Reduction of False Positives: Up to 70% alarm reduction
- Automated Risk Management: Prioritization based on MITRE ATT&CK tactics
- Ease of Compliance: Meets NIST SSDF, ISO 27001 requirements
- Sign VEX documents with AWS KMS
- Enable natural language querying using Amazon Q
- Add multi-cloud support via Azure Security Center and GCP SCC connectors