Add type checking in Rego policies
Some checks failed
CI / Go tests (push) Has been cancelled
CI / More Go tests (push) Has been cancelled
CI / Go tests with previous Go version (push) Has been cancelled
CI / UI tests (push) Has been cancelled
CI / Go tests on Windows (push) Has been cancelled
CI / Mixins tests (push) Has been cancelled
CI / Build Prometheus for common architectures (push) Has been cancelled
CI / Build Prometheus for all architectures (push) Has been cancelled
CI / Check generated parser (push) Has been cancelled
CI / Check generated semconv (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
CI / fuzzing (push) Has been cancelled
CI / codeql (push) Has been cancelled
CI / Report status of build Prometheus for all architectures (push) Has been cancelled
CI / Publish main branch artifacts (push) Has been cancelled
CI / Publish release artefacts (push) Has been cancelled
CI / Publish UI on npm Registry (push) Has been cancelled

Signed-off-by: Arthur Silva Sens <arthursens2005@gmail.com>
This commit is contained in:
Arthur Silva Sens 2026-01-17 21:20:32 -03:00
parent 1d0de528fc
commit f7b009de9b
No known key found for this signature in database

View file

@ -123,6 +123,151 @@ deny contains metric_violation(
not group.annotations.prometheus.objectives
}
# =============================================================================
# Type Validation Rules
# =============================================================================
# Rule 8: buckets must be an array of numbers
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.buckets must be an array, got %v", [group.metric_name, type_name(group.annotations.prometheus.buckets)]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
group.annotations.prometheus.buckets
not is_array(group.annotations.prometheus.buckets)
}
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.buckets must contain only numbers, found non-number at index %d", [group.metric_name, idx]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
is_array(group.annotations.prometheus.buckets)
bucket := group.annotations.prometheus.buckets[idx]
not is_number(bucket)
}
# Rule 10: exponential_buckets must be an object with start, factor, count
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.exponential_buckets must be an object, got %v", [group.metric_name, type_name(group.annotations.prometheus.exponential_buckets)]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
group.annotations.prometheus.exponential_buckets
not is_object(group.annotations.prometheus.exponential_buckets)
}
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.exponential_buckets.start is required and must be a number", [group.metric_name]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
is_object(group.annotations.prometheus.exponential_buckets)
not is_number(group.annotations.prometheus.exponential_buckets.start)
}
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.exponential_buckets.factor is required and must be a number", [group.metric_name]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
is_object(group.annotations.prometheus.exponential_buckets)
not is_number(group.annotations.prometheus.exponential_buckets.factor)
}
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.exponential_buckets.count is required and must be a number", [group.metric_name]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
is_object(group.annotations.prometheus.exponential_buckets)
not is_number(group.annotations.prometheus.exponential_buckets.count)
}
# Rule 11: bucket_factor must be a number
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.bucket_factor must be a number, got %v", [group.metric_name, type_name(group.annotations.prometheus.bucket_factor)]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
group.annotations.prometheus.bucket_factor
not is_number(group.annotations.prometheus.bucket_factor)
}
# Rule 12: max_bucket_number must be a number
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.max_bucket_number must be a number, got %v", [group.metric_name, type_name(group.annotations.prometheus.max_bucket_number)]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
group.annotations.prometheus.max_bucket_number
not is_number(group.annotations.prometheus.max_bucket_number)
}
# Rule 13: min_reset_duration must be a string
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.min_reset_duration must be a string (e.g., \"1h\", \"30m\"), got %v", [group.metric_name, type_name(group.annotations.prometheus.min_reset_duration)]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
group.annotations.prometheus.min_reset_duration
not is_string(group.annotations.prometheus.min_reset_duration)
}
# Rule 14: objectives must be an object (map)
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.objectives must be an object (map of quantile to error), got %v", [group.metric_name, type_name(group.annotations.prometheus.objectives)]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
group.annotations.prometheus.objectives
not is_object(group.annotations.prometheus.objectives)
}
# Rule 15: objectives values must be numbers
deny contains metric_violation(
sprintf("Metric '%s': annotations.prometheus.objectives values must be numbers, found non-number for key '%s'", [group.metric_name, key]),
group.id,
group.metric_name
) if {
group := input.groups[_]
group.type == "metric"
group.instrument == "histogram"
is_object(group.annotations.prometheus.objectives)
val := group.annotations.prometheus.objectives[key]
not is_number(val)
}
# =============================================================================
# Helper Functions
# =============================================================================