{"build_date_unix":"unknown","canonical_issues_count":1,"context_aware_rules":["AWS_DDB_001","AWS_EC2_006","AWS_ECS_004","AWS_EVENTBRIDGE_001","AWS_IAM_023","AWS_LAMBDA_004","AWS_OPS_001","AWS_OPS_018","AWS_OPS_026","AWS_OPS_030","AWS_OPS_035","AWS_OPS_037","AWS_SM_001","AWS_SQS_001","AWS_SQS_002","AWS_VPC_006"],"context_reasoning_axes":[{"catch_all":false,"consulted_by":["AWS_LAMBDA_004","AWS_OPS_001"],"description":"Sync (API GW, Function URL) vs async-push (SNS / S3 / EventBridge) vs polled-async (SQS / Kinesis event source mapping). Lambda DLQ only helps async-push.","name":"lambda_invocation_graph"},{"catch_all":false,"consulted_by":["AWS_SQS_001","AWS_SQS_002"],"description":"Which SQS queues are themselves a dead-letter queue (target of another queue's redrive_policy). DLQs do not need their own DLQ; their encryption-at-rest needs are different.","name":"sqs_dlq_identity"},{"catch_all":false,"consulted_by":["AWS_SQS_001"],"description":"KMS-CMK vs AWS-managed vs service-managed (e.g. sqs_managed_sse_enabled = true). Real encryption from any of these — the strict-CMK ask is a separate rule.","name":"encryption_variants"},{"catch_all":false,"consulted_by":["AWS_DDB_001","AWS_OPS_030"],"description":"Whether a resource actively expires its own data (DynamoDB TTL, S3 lifecycle, CloudWatch Logs retention). Ephemeral storage doesn't need PITR / long retention.","name":"data_lifetime"},{"catch_all":false,"consulted_by":["AWS_OPS_026"],"description":"Whether a resource is reachable from the public internet vs internal-only (aws_lb.internal flag, aws_apigateway_rest_api endpoint type, etc.). Public-facing rules (third-party DNS protection, public WAF) can suppress on internal-only resources.","name":"network_exposure"},{"catch_all":false,"consulted_by":["AWS_OPS_035","AWS_OPS_037"],"description":"Whether an IAM principal (role or user) actually holds dangerous grants (Allow + Resource:\"*\" + no Condition, or an attached access key). Shape-based IAM rules that fire on every role/user are suppressed when the principal carries no exploitable permissions.","name":"iam_policy_risk"},{"catch_all":false,"consulted_by":["AWS_OPS_035"],"description":"Whether an IAM role's trust policy is tightly scoped to a non-compute managed-service principal (no EC2/ECS/Lambda/EKS trust, no wildcard, no cross-account ARN). A permissions_boundary provides no meaningful security ceiling for a role that cannot be assumed by an IAM principal or compromised workload — only AWS-internal service calls can reach it.","name":"iam_trust_graph"},{"catch_all":true,"consulted_by":[],"description":"Whether a resource is disabled via `count = 0` (literal, or a var.X that resolves to 0). A disabled resource is not instantiated, so any finding on it is suppressed as a non-operational concern.","name":"disabled_resource_count"},{"catch_all":true,"consulted_by":[],"description":"For synthesized registry-module pseudo-resources (Phase 6 M3): audytx asserts only on attributes set by an EXPLICIT module input. A finding on a module default, an absent attribute, or an existence-only rule is suppressed — module internals/defaults drift across versions.","name":"module_synthesized_input"},{"catch_all":true,"consulted_by":[],"description":"Whether a resource is tagged as non-production (Environment = dev/staging/test/sandbox/qa/uat/preview/local/nonprod). Medium and Low findings are suppressed on non-prod resources — dev/staging infrastructure legitimately has more relaxed security controls and suppression reduces noise without hiding Critical or High findings.","name":"tag_environment"},{"catch_all":false,"consulted_by":["AWS_EC2_006","AWS_IAM_023"],"description":"Whether IMDSv2 (http_tokens = \"required\") is enforced on an EC2 instance via a launch template or account-level aws_ec2_instance_metadata_defaults, even when the aws_instance resource has no direct metadata_options block. Suppresses AWS_EC2_006 (\"no metadata_options block\") and AWS_IAM_023 (\"IMDSv1 + privileged role → SSRF credential theft\") when the SSRF→IMDS chain is already broken by inherited enforcement.","name":"imdsv2_enforcement"},{"catch_all":false,"consulted_by":["AWS_VPC_006"],"description":"Whether an aws_security_group is an EKS node-group or cluster SG — detected via `description`, `name`, or `name_prefix` containing \"eks\" (case-insensitive). EKS node SGs legitimately require all-ports intra-cluster rules (from_port = 0, protocol = -1) sourced from self / another SG for pod-to-pod and control-plane communication within the VPC. AWS_VPC_006 (all-ports-open SG) is suppressed on EKS-identified SGs ONLY when the all-ports rule is intra-cluster — an EKS-named SG that is actually open to 0.0.0.0/0 on all ports is a real finding and still fires.","name":"sg_eks_identity"},{"catch_all":false,"consulted_by":["AWS_ECS_004"],"description":"Whether an aws_ecs_task_definition is a reusable module template rather than a concrete resource — detected when both `family` and `container_definitions` are variable references (stored value starts with \"var.\"). Module templates deliberately omit `task_role_arn` because the caller is expected to supply it via variable. AWS_ECS_004 (missing task_role_arn) is suppressed on module templates to avoid flagging intentionally parameterized module definitions in production module repos.","name":"ecs_module_template"},{"catch_all":false,"consulted_by":["AWS_LAMBDA_004","AWS_OPS_001"],"description":"Whether an aws_lambda_function is a reusable module template — detected when both `function_name` and `handler` are variable references. Module templates leave these to the caller; the Lambda is not yet wired to any invocation source within the module scope. AWS_LAMBDA_004 and AWS_OPS_001 (missing DLQ) are suppressed because the invocation source is external and the DLQ requirement cannot be determined at module definition time.","name":"lambda_module_template"},{"catch_all":false,"consulted_by":["AWS_OPS_018","AWS_SQS_002"],"description":"Whether an aws_sqs_queue is a reusable module template — detected when `visibility_timeout_seconds`, `message_retention_seconds`, and `max_message_size` are all variable references. Root-module queues almost always hard-code at least one of these; module definitions delegate all three to the caller. AWS_OPS_018 (missing CloudWatch alarm) is suppressed because modules are templates and callers own monitoring. AWS_SQS_002 (missing DLQ) is suppressed because the DLQ decision belongs to the caller (e.g. terraform-aws-sqs exposes create_dlq as a caller variable).","name":"sqs_module_template"},{"catch_all":false,"consulted_by":["AWS_EVENTBRIDGE_001"],"description":"Whether an aws_cloudwatch_event_rule should be exempt from the Lambda permission companion check because the Lambda target is defined outside this plan. Detected when no aws_lambda_function resources exist in the plan — the Lambda (and therefore its aws_lambda_permission) belongs to the caller or a separate module, not the one being scanned. AWS_EVENTBRIDGE_001 (missing aws_lambda_permission companion) is suppressed to avoid false positives on EventBridge module repos that provide rules without defining the Lambda target.","name":"eventbridge_external_lambda"},{"catch_all":false,"consulted_by":["AWS_SM_001"],"description":"Whether an aws_secretsmanager_secret has automatic rotation configured by a sibling aws_secretsmanager_secret_rotation resource (resolved from that resource's secret_id reference). AWS_SM_001 fires per-secret and cannot see cross-resource rotation, so without this it is a false positive on every secret whose rotation is managed in a separate resource (the common, recommended pattern). AWS_SM_001 is suppressed when a rotation resource references the secret.","name":"secret_rotation"}],"engine_version":"0.19.9","mcp":{"endpoint":"/mcp","tools":["scan_terraform","autofix_terraform","dry_run_autofix","explain_finding","get_context_graph"],"transport":"streamable-http (stateless JSON-RPC over POST)"},"module_models":10,"output_formats":["pr_comment","sarif_v2.1.0"],"rules_count":247,"service":"audytx-backend","supported_cloud":"aws","supported_event_types":["pull_request","ping"],"supported_iac":["terraform"]}