Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions config/v1/tests/infrastructures.config.openshift.io/AAA_ungated.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1837,3 +1837,196 @@ tests:
value: value*
type: AWS
expectedStatusError: "invalid AWS resource tag value. The string can contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', '@'"
- name: Should not be able to create an aws resourcetag with aws prefix in key
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also add a ratcheting test (see readme in the tests dir) to prove that existing values are not affected by this change. You should show that

  • Existing entries persist when a new item is added to the list
  • Additional bad entries are not allowed when there is an existing bad entry
  • The bad entry can be updated to a valid entry

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I added the ratcheting validation tests, but am stuck on the first one (the other two work ok). In order to allow existing bad values, I updated the validation in 34f8d72 but apparently this is invalid, as the tests fail with:

Invalid value: "self == oldSelf || !self.startsWith('aws:')": oldSelf cannot be used on the uncorrelatable portion of the schema within spec.validation.openAPIV3Schema.properties[status].properties[platformStatus].properties[aws].properties[resourceTags]

I see in these k8s docs that this means the rule cannot be applied:

Errors will be generated on CRD writes if a schema node contains a transition rule that can never be applied, e.g. "oldSelf cannot be used on the uncorrelatable portion of the schema within path".

I'm not sure how to resolve this issue. Any insight?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoelSpeed claude helped me figure out that I needed to change ResourceTags to listType=map, but now the actual validation of the aws: prefix does not seem to be working

 [config.openshift.io/v1, Resource=infrastructures][ClusterProfiles=Hypershift,SelfManagedHA][FeatureSet="Default"][FeatureGate=-AWSClusterHostedDNSInstall][File=0000_10_config-operator_01_infrastructures-Default.crd.yaml] Infrastructure On Update [It] Should not be able to create an aws resourcetag with aws prefix in key
/Users/padillon/go/src/github.com/openshift/api/tests/generator.go:345

  [FAILED] Expected an error, got nil
  In [It] at: /Users/padillon/go/src/github.com/openshift/api/tests/generator.go:321 @ 10/14/25 22:00:52.111

Stuck on this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went ahead and side-stepped the issue by validating for immutability. IMHO that makes more sense, as post-install updates are not supported. On the other hand, I'm not sure if there are issues with making a field immutable post-GA; the intention was always for these fields to be immutable, it just wasn't validated.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We still need a ratcheting test to show that anyone who already has a value with aws: in the prefix won't be broken by this change

Copy link
Copy Markdown
Contributor Author

@patrickdillon patrickdillon Oct 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right, that makes sense: so we don't brick the rest of the aws platform status from being updated. Because I made resourceTags immutable, we can't cover the three expected cases in your original message. Does the check added in d582954 look good/sufficient? Or what else would you have in mind.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, that covers it, thanks

initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec:
platformSpec:
aws: {}
type: AWS
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec:
platformSpec:
aws: {}
type: AWS
status:
controlPlaneTopology: HighlyAvailable
cpuPartitioning: None
infrastructureTopology: HighlyAvailable
platform: AWS
platformStatus:
aws:
region: us-east-1
resourceTags:
- key: aws:key
value: value with space
type: AWS
expectedStatusError: "the prefix 'aws:' is reserved for AWS system usage and cannot be used at the beginning of a key"
- name: Should not be able to modify an existing AWS ResourceTags Tag
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
controlPlaneTopology: "HighlyAvailable"
infrastructureTopology: "HighlyAvailable"
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "key", value: "changed"}
expectedStatusError: "status.platformStatus.aws.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
- name: Should not be able to add a Tag to an existing AWS ResourceTags
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
controlPlaneTopology: "HighlyAvailable"
infrastructureTopology: "HighlyAvailable"
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "key", value: "value"}
- {key: "new", value: "entry"}
expectedStatusError: "status.platformStatus.aws.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
- name: Should not be able to remove a Tag from an existing AWS ResourceTags
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "key", value: "value"}
- {key: "new", value: "entry"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "key", value: "value"}
expectedStatusError: "status.platformStatus.aws.resourceTags: Invalid value: \"array\": resourceTags are immutable and may only be configured during installation"
- name: Should not be able to add AWS ResourceTags to an empty platformStatus.aws
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws: {}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
aws:
resourceTags:
- {key: "key", value: "value"}
expectedStatusError: "status.platformStatus.aws: Invalid value: \"object\": resourceTags may only be configured during installation"
- name: Should not be able to remove AWS ResourceTags from platformStatus.aws
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "key", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws: {}
expectedStatusError: "status.platformStatus.aws: Invalid value: \"object\": resourceTags may only be configured during installation"
- name: Ratcheting validation for AWS prefix ResourceTags should not break updates
initialCRDPatches:
- op: remove
path: /spec/versions/0/schema/openAPIV3Schema/properties/status/properties/platformStatus/properties/aws/properties/resourceTags/items/properties/key/x-kubernetes-validations
initial: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "aws:invalidKey", value: "value"}
updated: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "aws:invalidKey", value: "value"}
serviceEndpoints:
- {name: "newendpoint", url: "https://www.awsendpoint.com"}
expected: |
apiVersion: config.openshift.io/v1
kind: Infrastructure
spec: {}
status:
platform: AWS
controlPlaneTopology: HighlyAvailable
cpuPartitioning: None
infrastructureTopology: HighlyAvailable
platformStatus:
type: AWS
aws:
resourceTags:
- {key: "aws:invalidKey", value: "value"}
serviceEndpoints:
- {name: "newendpoint", url: "https://www.awsendpoint.com"}
4 changes: 4 additions & 0 deletions config/v1/types_infrastructure.go
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ type AWSPlatformSpec struct {
}

// AWSPlatformStatus holds the current status of the Amazon Web Services infrastructure provider.
// +kubebuilder:validation:XValidation:rule="has(oldSelf.resourceTags) == has(self.resourceTags)",message="resourceTags may only be configured during installation"
type AWSPlatformStatus struct {
// region holds the default AWS region for new AWS resources created by the cluster.
Region string `json:"region"`
Expand All @@ -545,6 +546,7 @@ type AWSPlatformStatus struct {
// AWS supports a maximum of 50 tags per resource. OpenShift reserves 25 tags for its use, leaving 25 tags
// available for the user.
// +kubebuilder:validation:MaxItems=25
// +kubebuilder:validation:XValidation:rule="self.all(x, x in oldSelf) && oldSelf.all(x, x in self)",message="resourceTags are immutable and may only be configured during installation"
// +listType=atomic
// +optional
ResourceTags []AWSResourceTag `json:"resourceTags,omitempty"`
Expand Down Expand Up @@ -581,9 +583,11 @@ type AWSResourceTag struct {
// key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag.
// Key should consist of between 1 and 128 characters, and may
// contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'.
// Key must not start with 'aws:'.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=128
// +kubebuilder:validation:XValidation:rule=`self.matches('^[0-9A-Za-z_.:/=+-@ ]+$')`,message="invalid AWS resource tag key. The string can contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', '@'"
// +kubebuilder:validation:XValidation:rule=`!self.startsWith('aws:')`,message="the prefix 'aws:' is reserved for AWS system usage and cannot be used at the beginning of a key"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to consider casing on the AWS prefix?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion: no. The docs say literally aws:. We could argue that it is inconclusive, and test whether casing is relevant, but I don't think it's worth the time or worth holding this up. If we do want to pursue it, it would be better to pursue it as an installer bug, as this API should be used by users.

// +required
Key string `json:"key"`
// value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,7 @@ spec:
key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag.
Key should consist of between 1 and 128 characters, and may
contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'.
Key must not start with 'aws:'.
maxLength: 128
minLength: 1
type: string
Expand All @@ -1396,6 +1397,9 @@ spec:
space (' '), '_', '.', '/', '=', '+', '-', ':',
'@'
rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$')
- message: the prefix 'aws:' is reserved for AWS system
usage and cannot be used at the beginning of a key
rule: '!self.startsWith(''aws:'')'
Comment on lines +1400 to +1402
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Kubernetes CRD CEL validation matches() function regex case insensitive

💡 Result:

Yes — CRD CEL uses RE2 regex, so you can make matches() case‑insensitive either by:

  • adding an inline RE2 flag like (?i) in the pattern:

    • e.g. rule: "self.name.matches('(?i)^foo-[0-9]+$')" [1][2]
  • or normalizing the input and matching a fixed-case pattern:

    • e.g. rule: "self.name.lowerAscii().matches('^foo-[0-9]+$')" [1]

References: Kubernetes CEL docs (regex/matches and regex library). [1] RE2 docs showing (?i) case‑insensitive flag. [2]

Sources
[1] Kubernetes CEL docs — Common Expression Language in Kubernetes.
[2] RE2 regular-expression syntax / manuals (shows (?i) inline flag).


🌐 Web query:

AWS tag key prefix aws: reserved case sensitivity uppercase

💡 Result:

Short answer:

  • The prefix "aws:" is reserved for AWS and you must not use it in tag keys (e.g., "aws:", "AWS:" or any upper/lowercase combination). Tags that begin with that prefix are created and managed by AWS and cannot be created, edited, or deleted by you. [1][2][3]

  • Tag keys are generally case‑sensitive across AWS services (so "CostCenter" and "costcenter" are treated as different keys). However, there are service/resource exceptions (for some IAM resource types tag keys are not case‑sensitive); follow the specific service docs when in doubt. [2][3]

Sources:

  1. Amazon ECS tag docs (reserved prefix and case sensitivity). [turn0search3].
  2. AWS Batch tag restrictions (explicitly warns “Don't use aws:, AWS:, or any upper or lowercase combination…” and notes case sensitivity). [turn0search1].
  3. IAM tagging rules (notes general reserved aws: prefix and details where tag key case sensitivity differs by IAM resource type). [turn0search2].

Harden reserved-prefix check to be case-insensitive.

Block all case variants like "AWS:", "Aws:", etc. The matches() function in Kubernetes CEL uses the RE2 regex engine, which supports the (?i) inline flag for case-insensitive matching. AWS documentation explicitly reserves all case combinations of the "aws:" prefix for AWS-managed tags.

Apply:

-                                rule: '!self.startsWith(''aws:'')'
+                                rule: '!self.matches(''(?i)^aws:'')'
🤖 Prompt for AI Agents
In
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml
around lines 1400-1402, the reserved-prefix check currently uses a
case-sensitive startsWith('aws:') which allows variants like "AWS:"; change the
rule to perform a case-insensitive match (use CEL's RE2 inline flag) so it
blocks all case variants—replace the current rule with a case-insensitive
matches expression that tests for the prefix `aws:` and negate it to preserve
the original logic.

value:
description: |-
value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag.
Expand All @@ -1419,6 +1423,10 @@ spec:
maxItems: 25
type: array
x-kubernetes-list-type: atomic
x-kubernetes-validations:
- message: resourceTags are immutable and may only be configured
during installation
rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
Comment on lines +1426 to +1429
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Array immutability can be bypassed via duplicates; add size equality

Current rule compares membership only; [a,b][a,a,b] passes. Include size check.

Apply this diff:

 x-kubernetes-validations:
 -  - message: resourceTags are immutable and may only be configured during installation
-    rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
+    rule: size(self) == size(oldSelf) &&
+          self.all(x, x in oldSelf) &&
+          oldSelf.all(x, x in self)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml
around lines 1426 to 1429, the x-kubernetes-validations rule only checks set
membership so arrays with duplicated entries can bypass immutability (e.g. [a,b]
→ [a,a,b]); update the rule to also require equal sizes between self and oldSelf
(for example add an additional condition like size(self) == size(oldSelf)
combined with the existing membership checks) so that duplicates cannot be added
while preserving the current membership validation.

serviceEndpoints:
description: |-
serviceEndpoints list contains custom endpoints which will override default
Expand Down Expand Up @@ -1447,6 +1455,9 @@ spec:
type: array
x-kubernetes-list-type: atomic
type: object
x-kubernetes-validations:
- message: resourceTags may only be configured during installation
rule: has(oldSelf.resourceTags) == has(self.resourceTags)
azure:
description: azure contains settings specific to the Azure infrastructure
provider.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,7 @@ spec:
key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag.
Key should consist of between 1 and 128 characters, and may
contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'.
Key must not start with 'aws:'.
maxLength: 128
minLength: 1
type: string
Expand All @@ -1199,6 +1200,9 @@ spec:
space (' '), '_', '.', '/', '=', '+', '-', ':',
'@'
rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$')
- message: the prefix 'aws:' is reserved for AWS system
usage and cannot be used at the beginning of a key
rule: '!self.startsWith(''aws:'')'
Comment on lines +1203 to +1205
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

AWS tag keys reserved prefix 'aws:' case sensitivity restrictions

💡 Result:

Short answer: You may not use the "aws:" prefix in any user-defined tag key or value in any case (e.g., "aws:", "AWS:", "Aws:", etc. are all reserved). In general tag keys and values are case‑sensitive (though some IAM resource tags have special case rules). [1][2]

Sources:

  • AWS tagging best practices / general reference (tags are case sensitive; the aws: prefix is reserved). [1]
  • Multiple AWS service docs (explicitly note “Do not use aws:, AWS:, or any upper or lowercase combination…” and that tag keys/values are case sensitive). [2]

🌐 Web query:

AWS EC2 tag keys 'aws:' prefix case-insensitive enforcement

💡 Result:

Short answer: AWS reserves the aws: prefix case‑insensitively. You cannot create/edit/delete tag keys or values that begin with aws: in any case variant (e.g., aws:, AWS:, Aws:, aWs:, etc.); those tags are reserved for AWS, won’t count toward tag quotas, and are protected. Tag keys otherwise remain case‑sensitive. [1][2]

Sources:

  • AWS tagging restrictions (multiple service docs stating “Don’t use aws:, AWS:, or any upper or lowercase combination…”). [1][2]

🌐 Web query:

AWS duplicate tag keys same resource allowed

💡 Result:

No — AWS requires each tag key to be unique per resource. If you add a tag with an existing key on the same resource, the new value overwrites the old value (duplicate keys are not allowed). [1][2][3]

Sources:

  • Amazon EC2 tagging docs. [1]
  • AWS KMS tagging docs. [2]
  • Amazon Athena tagging docs. [3]

Update validation rule to enforce AWS's case-insensitive prefix restriction.

AWS reserves the aws: prefix case-insensitively across all variants (e.g., aws:, AWS:, Aws:). The current rule only checks lowercase and will incorrectly permit tags like AWS:environment. Update to:

- rule: '!self.startsWith(''aws:'')'
+ rule: '!self.lowerAscii().startsWith(''aws:'')'

This ensures the validation aligns with AWS's actual tag restrictions.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- message: the prefix 'aws:' is reserved for AWS system
usage and cannot be used at the beginning of a key
rule: '!self.startsWith(''aws:'')'
- message: the prefix 'aws:' is reserved for AWS system
usage and cannot be used at the beginning of a key
rule: '!self.lowerAscii().startsWith(''aws:'')'
🤖 Prompt for AI Agents
In
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml
around lines 1203-1205, the validation rule only rejects the lowercase 'aws:'
prefix; update it to perform a case-insensitive check so variants like 'AWS:' or
'Aws:' are also blocked — replace the current rule '!self.startsWith('aws:')'
with a case-insensitive test (for example using self.lower().startsWith('aws:')
or an equivalent case-insensitive regex match) so the validation rejects any tag
beginning with the aws: prefix in any letter case.

value:
description: |-
value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag.
Expand All @@ -1222,6 +1226,10 @@ spec:
maxItems: 25
type: array
x-kubernetes-list-type: atomic
x-kubernetes-validations:
- message: resourceTags are immutable and may only be configured
during installation
rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
serviceEndpoints:
Comment on lines +1229 to 1233
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Immutability rule can be bypassed via duplicates; add size equality

self.all(x, x in oldSelf) && oldSelf.all(x, x in self) is set‑equality and doesn’t detect duplicate insertions/removals. Add a size check to prevent silently adding/removing identical entries:

- rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
+ rule: size(self) == size(oldSelf) &&
+       self.all(x, x in oldSelf) &&
+       oldSelf.all(x, x in self)
🤖 Prompt for AI Agents
In
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-Default.crd.yaml
around lines 1229 to 1233, the CEL immutability rule uses set-equality but can
be bypassed by adding or removing duplicate identical entries; update the
validation rule to also require the list sizes be equal (i.e., add a size
equality check between self and oldSelf) so duplicates cannot be added or
removed while preserving set membership.

description: |-
serviceEndpoints list contains custom endpoints which will override default
Expand Down Expand Up @@ -1250,6 +1258,9 @@ spec:
type: array
x-kubernetes-list-type: atomic
type: object
x-kubernetes-validations:
- message: resourceTags may only be configured during installation
rule: has(oldSelf.resourceTags) == has(self.resourceTags)
azure:
description: azure contains settings specific to the Azure infrastructure
provider.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,7 @@ spec:
key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag.
Key should consist of between 1 and 128 characters, and may
contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'.
Key must not start with 'aws:'.
maxLength: 128
minLength: 1
type: string
Expand All @@ -1396,6 +1397,9 @@ spec:
space (' '), '_', '.', '/', '=', '+', '-', ':',
'@'
rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$')
- message: the prefix 'aws:' is reserved for AWS system
usage and cannot be used at the beginning of a key
rule: '!self.startsWith(''aws:'')'
value:
Comment on lines +1401 to 1403
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Confirm case sensitivity of the reserved prefix.

Rule forbids only lowercase aws:. If AWS treats tag keys as case‑sensitive, this is fine; if the reservation is case‑insensitive, consider lower(self).startsWith('aws:').


🌐 Web query:

Do AWS tagging rules reserve only the lowercase 'aws:' prefix, or any case-insensitive variant? Cite official AWS docs if possible.

💡 Result:

AWS reserves the prefix in a case-insensitive way — you must not use "aws:", "AWS:", or any upper/lowercase combination as a tag key prefix. [1][2]

Sources:

  • IAM tagging docs: "You cannot create a tag key or value that begins with the text aws:. This tag prefix is reserved for AWS internal use." [1]
  • Boto3 / service docs: "Do not use aws:, AWS:, or any upper or lowercase combination of such as a prefix for keys ... it is reserved for Amazon Web Services use." [2]

References:
[1] AWS Identity and Access Management — Tagging IAM resources.
[2] AWS service SDK/docs (Boto3 / Forecast example) — Tagging restrictions.


Fix case-insensitive handling of AWS reserved tag prefix.

The rule currently forbids only lowercase aws: prefix, but AWS reserves the prefix case-insensitively. The rule should use lower(self).startsWith('aws:') to prevent all case variants (AWS:, Aws:, etc.) from being used as tag key prefixes, consistent with AWS tagging policy.

🤖 Prompt for AI Agents
In
config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml
around lines 1401-1403, the validation rule only blocks lowercase "aws:" prefix;
update the condition to perform a case-insensitive check by using
lower(self).startsWith('aws:') (i.e. replace the current
"!self.startsWith('aws:')" expression with the negated lower-case check) so that
any case variant like "AWS:" or "Aws:" is also rejected for tag key prefixes.

description: |-
value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag.
Expand All @@ -1419,6 +1423,10 @@ spec:
maxItems: 25
type: array
x-kubernetes-list-type: atomic
x-kubernetes-validations:
- message: resourceTags are immutable and may only be configured
during installation
rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
serviceEndpoints:
description: |-
serviceEndpoints list contains custom endpoints which will override default
Expand Down Expand Up @@ -1447,6 +1455,9 @@ spec:
type: array
x-kubernetes-list-type: atomic
type: object
x-kubernetes-validations:
- message: resourceTags may only be configured during installation
rule: has(oldSelf.resourceTags) == has(self.resourceTags)
azure:
description: azure contains settings specific to the Azure infrastructure
provider.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1190,6 +1190,7 @@ spec:
key sets the key of the AWS resource tag key-value pair. Key is required when defining an AWS resource tag.
Key should consist of between 1 and 128 characters, and may
contain only the set of alphanumeric characters, space (' '), '_', '.', '/', '=', '+', '-', ':', and '@'.
Key must not start with 'aws:'.
maxLength: 128
minLength: 1
type: string
Expand All @@ -1199,6 +1200,9 @@ spec:
space (' '), '_', '.', '/', '=', '+', '-', ':',
'@'
rule: self.matches('^[0-9A-Za-z_.:/=+-@ ]+$')
- message: the prefix 'aws:' is reserved for AWS system
usage and cannot be used at the beginning of a key
rule: '!self.startsWith(''aws:'')'
value:
description: |-
value sets the value of the AWS resource tag key-value pair. Value is required when defining an AWS resource tag.
Expand All @@ -1222,6 +1226,10 @@ spec:
maxItems: 25
type: array
x-kubernetes-list-type: atomic
x-kubernetes-validations:
- message: resourceTags are immutable and may only be configured
during installation
rule: self.all(x, x in oldSelf) && oldSelf.all(x, x in self)
serviceEndpoints:
description: |-
serviceEndpoints list contains custom endpoints which will override default
Expand Down Expand Up @@ -1250,6 +1258,9 @@ spec:
type: array
x-kubernetes-list-type: atomic
type: object
x-kubernetes-validations:
- message: resourceTags may only be configured during installation
rule: has(oldSelf.resourceTags) == has(self.resourceTags)
azure:
description: azure contains settings specific to the Azure infrastructure
provider.
Expand Down
Loading