Repository: aws-cloudformation/cfn-lint

Issue:
CloudFront OAI ARN incorrectly fails I3042:accountId check
### CloudFormation Lint Version

1.18.4

### What operating system are you using?

Mac, Ubuntu

### Describe the bug

cfn-lint expects the `:cloudfront:` segment of the CloudFront OAI ARN to not be a hardcoded account ID, when the `:cloudfront:` segment should be hardcoded to `cloudfront`.

```
$ cfn-lint --format pretty --regions us-east-2 --include-checks I --configure-rule E3012:strict=True I3042:region=True I3042:accountId=True -- template.yaml
template.yaml
12:15:              I3042     ARN in Resource Resource contains hardcoded AccountId in ARN or incorrectly placed Pseudo Parameters
```

Related to #3683, #3716

### Expected behavior

CloudFront OAI ARN doesn't fail I3042:accountId check

### Reproduction template

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  Resource:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: bucket
      PolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Sub arn:${AWS::Partition}:iam::cloudfront:user/CloudFront Origin Access Identity E15MNIMTCFKK4C
            Action: s3:GetObject
            Resource: arn:aws:s3:::bucket/*
```


Discussion:

Patch:
diff --git a/src/cfnlint/rules/resources/HardCodedArnProperties.py b/src/cfnlint/rules/resources/HardCodedArnProperties.py
index a88329e9a8..10dbd80da5 100644
--- a/src/cfnlint/rules/resources/HardCodedArnProperties.py
+++ b/src/cfnlint/rules/resources/HardCodedArnProperties.py
@@ -125,10 +125,11 @@ def match(self, cfn: Template) -> RuleMatches:
             if self.config["accountId"] and not re.match(
                 r"^\$\{\w+}|\$\{AWS::AccountId}|aws|lambda|$", candidate[2]
             ):
-                message = (
-                    "ARN in Resource {0} contains hardcoded AccountId in ARN or"
-                    " incorrectly placed Pseudo Parameters"
-                )
-                matches.append(RuleMatch(path, message.format(path[1])))
+                if candidate[2] not in ["cloudfront"]:
+                    message = (
+                        "ARN in Resource {0} contains hardcoded AccountId in ARN or"
+                        " incorrectly placed Pseudo Parameters"
+                    )
+                    matches.append(RuleMatch(path, message.format(path[1])))
 
         return matches


Test patch:
diff --git a/test/fixtures/templates/good/resources/properties/hard_coded_arn_properties.yaml b/test/fixtures/templates/good/resources/properties/hard_coded_arn_properties.yaml
index 0250c3225b..8e8add11fb 100644
--- a/test/fixtures/templates/good/resources/properties/hard_coded_arn_properties.yaml
+++ b/test/fixtures/templates/good/resources/properties/hard_coded_arn_properties.yaml
@@ -14,3 +14,15 @@ Resources:
       TemplateURL: !Sub https://s3_bucket_name.s3.${AWS::Region}.amazonaws.com/template.yaml
       Parameters:
         AuthorizerUri: !Sub arn:${AWS::Partition}:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:${AWS::Partition}:lambda:${AWS::Region}:${AWS::AccountId}:function:FunctionName/invocations
+  Bucket:
+    Type: AWS::S3::BucketPolicy
+    Properties:
+      Bucket: bucket
+      PolicyDocument:
+        Version: 2012-10-17
+        Statement:
+          - Effect: Allow
+            Principal:
+              AWS: !Sub arn:${AWS::Partition}:iam::cloudfront:user/CloudFront Origin Access Identity E15MNIMTCFKK4C
+            Action: s3:GetObject
+            Resource: arn:aws:s3:::bucket/*
diff --git a/test/unit/rules/resources/test_hardcodedarnproperties.py b/test/unit/rules/resources/test_hardcodedarnproperties.py
index bee996d3e7..2e2663d347 100644
--- a/test/unit/rules/resources/test_hardcodedarnproperties.py
+++ b/test/unit/rules/resources/test_hardcodedarnproperties.py
@@ -28,6 +28,26 @@ def test_file_positive(self):
         # By default, a set of "correct" templates are checked
         self.helper_file_positive()
 
+    def test_file_positive_with_config(self):
+        self.helper_file_negative(
+            "test/fixtures/templates/good/resources/properties/hard_coded_arn_properties.yaml",
+            0,
+            ConfigMixIn(
+                [],
+                include_experimental=True,
+                include_checks=[
+                    "I",
+                ],
+                configure_rules={
+                    "I3042": {
+                        "partition": True,
+                        "region": True,
+                        "accountId": True,
+                    }
+                },
+            ),
+        )
+
     def test_file_negative_partition(self):
         self.helper_file_negative(
             "test/fixtures/templates/bad/hard_coded_arn_properties.yaml",