AWS Security Hub · CodeBuild
CodeBuild.4: Projects should have a logging configuration
Written and reviewed by Emnode · Last reviewed
What does AWS Security Hub CodeBuild.4 check?
CodeBuild.4 fails any project whose logsConfig leaves both destinations disabled. It passes if at least one of cloudWatchLogs or s3Logs has status ENABLED, mapped to the AWS Config rule codebuild-project-logging-enabled. It evaluates configuration, not whether any build actually wrote output.
Why does CodeBuild.4 matter?
A CodeBuild project sits at one of the most privileged junctions in an org — it can deploy infrastructure, push images, read secrets, and runs whatever code lands in a source branch. When something goes wrong (a leaked credential, a malicious dependency, an unexpected deploy), the build log is frequently the only place the story is written down. Logging off means that story was never recorded.
How do I fix CodeBuild.4?
- Inventory each project's cloudWatchLogs.status and s3Logs.status across regions; any project with both DISABLED fails.
- Enable a destination with update-project --logs-config, setting a cloudWatchLogs block to ENABLED with a sensible groupName.
- Verify the service role holds logs:CreateLogStream and logs:PutLogEvents (or s3:PutObject) so logs actually get written.
- Bake the logsConfig block into the CloudFormation/Terraform module and back it with the Config rule.
Remediation script · bash
# Verify the prerequisite first: API Gateway's account-level CloudWatch role.
# Without it, the logging setting saves but no logs ever flow.
aws apigateway get-account --query 'cloudwatchRoleArn' --output text
# Enable ERROR-level execution logging on every stage of a REST API.
REST_API=a1b2c3d4e5
for STAGE in $(aws apigateway get-stages --rest-api-id $REST_API \
--query 'item[].stageName' --output text); do
aws apigateway update-stage --rest-api-id $REST_API --stage-name $STAGE \
--patch-operations op=replace,path=/*/*/logging/loglevel,value=ERROR
done
# Cap retention on the log group so storage stays bounded (do this every time you enable logging).
aws logs put-retention-policy \
--log-group-name "API-Gateway-Execution-Logs_${REST_API}/prod" \
--retention-in-days 90
# Example for a managed database: publish engine logs to CloudWatch (no per-event charge).
aws rds modify-db-instance --db-instance-identifier prod-db \
--cloudwatch-logs-export-configuration 'EnableLogTypes=["error","audit"]' --apply-immediately Full walkthrough (console steps, edge cases and verification) in the lesson Enable application and API logging.
Is CodeBuild.4 a false positive?
Projects created in the console default CloudWatch logging on, but projects created via API, SDK, CloudFormation, or Terraform without an explicit logsConfig can end up with both destinations disabled — the usual root cause. The control passes on configuration alone, so a missing service-role permission can leave you passing with empty logs.
More CodeBuild controls
- CodeBuild.1 A CodeBuild Bitbucket URL contains embedded credentials
- CodeBuild.2 CodeBuild env vars contain clear-text credentials
- CodeBuild.3 CodeBuild S3 logs should be encrypted
- CodeBuild.7 Report group exports should be encrypted at rest