Skip to main content
emnode
Compliance Medium severity

AWS Security Hub · RDS

RDS.42: RDS MariaDB should export logs to CW

Written and reviewed by Emnode · Last reviewed

What does AWS Security Hub RDS.42 check?

RDS.42 checks whether an RDS for MariaDB instance (AWS::RDS::DBInstance) publishes its logs to CloudWatch Logs. It knows four log types (audit, error, general, and slowquery) and by default expects at least audit and error to be exported, failing the instance otherwise. It is evaluated periodically.

Why does RDS.42 matter?

A MariaDB instance writes its error, general, slow-query, and audit logs to the managed database host by default. You can view recent slices in the console or pull them with an API call, but they rotate, are size-capped, and vanish the moment the instance is replaced, scaled, or fails over. Logs you can't reach are logs you can't use: the difference between "the evidence rotated away" and "here is exactly who connected, what ran, and when."

How do I fix RDS.42?

  1. Enable the export with modify-db-instance --cloudwatch-logs-exports-configuration 'EnableLogTypes=["audit","error"]' (add slowquery as useful; avoid general in production for cost).
  2. Set a retention policy on the resulting log groups.
  3. Build metric filters and alarms on the exported streams.
  4. Standardise the export across MariaDB instances in IaC.

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 RDS.42 a false positive?

The control defaults to expecting both audit and error exports, so a MariaDB instance that deliberately ships only its error log (a common, cost-conscious choice where the audit log is high-volume and the workload doesn't warrant connection-level auditing) fails even though the configuration is intentional. The logTypes parameter is customisable: if you genuinely only require, say, error and slowquery, retune the parameter to match your real logging standard so the control measures the right thing rather than suppressing a finding against the default. Suppression is the right move instead only when a specific instance is a documented exception to an otherwise-standard export set (for example a throwaway sandbox), recorded with an owner and a review date rather than left as a silent miss.

Part of the learning path See what's happening
  • RDS.1 An RDS snapshot is shared publicly
  • RDS.2 An RDS instance is publicly accessible from the internet
  • RDS.3 RDS DB instances should be encrypted at rest
  • RDS.4 RDS snapshots should be encrypted at rest
  • RDS.5 RDS DB instances should use multiple AZs
  • RDS.6 RDS lacks enhanced monitoring
  • RDS.7 RDS clusters should have deletion protection
  • RDS.8 RDS DB instances should have deletion protection
  • RDS.9 RDS engine logs are not shipped to CloudWatch
  • RDS.10 RDS relies on long-lived database passwords
  • RDS.11 RDS instances should have automatic backups
  • RDS.12 IAM auth should be configured for RDS clusters