AWS Config rules evaluate resources against compliance requirements continuously, and every mature AWS environment eventually needs exceptions — a specific S3 bucket that legitimately needs public access for a static website, a security group that needs a broader ingress rule for a specific integration. The problem isn't having exceptions; it's exceptions that never expire and are never revisited, which is precisely what an auditor flags when they find a suppressed Config finding with no documented justification or end date.
Why Undocumented Exceptions Are a Real Finding
A resource marked "compliant" through a manually adjusted rule scope, or a finding silently suppressed without record, looks identical to genuine compliance from inside the AWS Console. The difference only shows up when someone asks "why is this allowed" and there's no answer beyond "someone probably needed it for something at some point." That's the exact scenario auditors are trained to probe for.
Building a Time-Boxed Exception Register
Instead of silently adjusting Config rule scope or suppressing findings ad hoc, we build a structured exception register that requires a ticket ID and expiration date for every exception:
import boto3
from datetime import datetime, timedelta
config = boto3.client("config")
dynamodb = boto3.resource("dynamodb")
exception_table = dynamodb.Table("config-rule-exceptions")
def register_exception(rule_name, resource_id, ticket_id, justification, duration_days=90):
"""Records a time-boxed exception with mandatory justification,
rather than silently adjusting rule scope."""
exception_table.put_item(Item={
"rule_name": rule_name,
"resource_id": resource_id,
"ticket_id": ticket_id,
"justification": justification,
"created_at": datetime.utcnow().isoformat(),
"expires_at": (datetime.utcnow() + timedelta(days=duration_days)).isoformat(),
"status": "active",
})
def check_expired_exceptions():
"""Scheduled job — flags exceptions past their expiration for
re-justification or removal, rather than letting them persist silently."""
response = exception_table.scan(
FilterExpression="expires_at < :now AND #s = :active",
ExpressionAttributeNames={"#s": "status"},
ExpressionAttributeValues={":now": datetime.utcnow().isoformat(), ":active": "active"},
)
for item in response["Items"]:
create_review_ticket(item) # forces a human decision: renew with new justification, or fix the resource
return response["Items"]
The check_expired_exceptions job runs on a schedule (weekly is typical) and forces every exception through a renewal decision rather than letting it persist indefinitely by default. Renewal requires a fresh justification, not an automatic rollover — which is what prevents this register from becoming just as stale as the ad hoc suppression it replaces.
What This Looks Like in an Audit
Instead of an auditor finding an unexplained gap between a Config rule's intended scope and actual enforcement, the exception register produces a clean, exportable list: every deviation from standard compliance rules, why it exists, who approved it, and when it's due for re-review. That's a materially stronger answer than either "we don't have exceptions" (rarely true in a real environment) or a silent gap with no documentation at all.
Integrating With Existing Config Remediation
For rules with automated remediation (AWS Config's auto-remediation actions), the exception register should suppress the remediation action specifically for registered exceptions, not disable the rule or remediation broadly — keeping enforcement active for every resource that isn't a documented, time-boxed exception.
Frequently Asked Questions
How is this different from just adjusting the Config rule's scope directly?
Adjusting rule scope changes what's evaluated at all, silently, for every resource matching that scope going forward. The exception register keeps the rule fully active and evaluating everything, while tracking specific, individually justified deviations with an expiration — a meaningfully different audit posture.
What's a reasonable default expiration period for an exception?
90 days is a common default that forces regular re-justification without creating excessive renewal overhead, though genuinely permanent architectural exceptions (rare) might warrant a longer cycle with a correspondingly higher-level approval requirement.
Does this require custom tooling, or can it use native AWS Config features?
AWS Config doesn't natively support time-boxed exceptions with mandatory justification — this requires the custom register pattern layered on top, though it integrates with native Config rules and remediation actions rather than replacing them.
Who should be able to approve a new exception?
This varies by organization, but requiring approval from someone with both technical context and compliance accountability (not just the requesting engineer) is a common and defensible pattern.
See what an AWS cost and compliance audit finds in your Config setup → rutagon.com/contact or call 907-841-8407.