Skip to content
Open
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
141 changes: 139 additions & 2 deletions resources/grafana/generated/dashboards/rhacs-cluster-overview.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions resources/grafana/sources/.claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{

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.

Can we add this file to .gitignore?

"permissions": {
"allow": [
"Read(//home/ebenshet/workspaces/rox-34665-grafana-display-scans-per-day/github.com/stackrox/rhacs-observability-resources/**)",
"Bash(jj status *)",
"Bash(jj rebase *)",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python - <<'PY'
import json

path = "resources/grafana/sources/.claude/settings.local.json"
with open(path, encoding="utf-8") as stream:
    rules = json.load(stream)["permissions"]["allow"]

matches = [rule for rule in rules if rule.startswith("Bash(jj rebase")]
if not matches:
    raise SystemExit("No jj rebase rule found")

for rule in matches:
    print(rule)
    if rule == "Bash(jj rebase *)":
        raise SystemExit("Unscoped jj rebase permission found")
PY

Repository: stackrox/rhacs-observability-resources

Length of output: 230


🌐 Web query:

Claude Code permissions allow rules Bash command glob prefix Bash command:*

💡 Result:

In Claude Code, Bash permission rules support glob pattern matching using the asterisk (*) character [1][2]. These rules allow you to specify which shell commands Claude is permitted to execute, blocked from executing (deny), or required to ask about (ask) [3][4]. Key details regarding the use of glob patterns in Bash rules: Positioning and Matching: Wildcards can be placed at the beginning, middle, or end of a command string [1][3]. - Bash(npm ) matches any command starting with "npm " [1][3]. - Bash( install) matches any command ending in " install" [1][3]. - Bash(git * main) matches commands like "git checkout main" or "git log --oneline main" [1][3]. Word Boundaries: The placement of a space before the asterisk is significant because it enforces word boundaries [1][2]. - Bash(ls ) matches "ls -la" but does not match "lsof" [1][2]. - Bash(ls) matches both "ls -la" and "lsof" [1][2]. Alternative Suffix: The:* suffix is functionally equivalent to a trailing wildcard [1][2]. For example, Bash(ls:*) matches the same commands as Bash(ls *) [1][2]. Important Behaviors: - Compound Commands: Claude Code parses compound commands (e.g., those using && or ||) individually. A Bash rule such as Bash(safe-cmd *) does not automatically permit a command like "safe-cmd && rm -rf." because each subcommand must match the permission rules independently [3]. - Rule Evaluation: Rules are evaluated in the order of deny, then ask, then allow [4]. The first matching rule determines the outcome [4]. A deny rule is the strongest and will block a command even if a more specific allow rule exists [4]. - Tool Removal vs. Scoping: A deny rule specified with just the tool name (e.g., "Bash") removes the tool entirely from Claude's context [1][3]. A scoped deny rule (e.g., "Bash(rm *)") keeps the tool available but blocks only the matching command pattern [3][4]. These rules are typically configured in your.claude/settings.json or ~/.claude/settings.json files [5][6].

Citations:


Narrow the jj rebase permission.

Bash(jj rebase *) permits arbitrary jj rebase options and subcommands. Remove this rule or replace it with a specific command such as Bash(jj rebase --continue *) for the exact workflow.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/grafana/sources/.claude/settings.local.json` at line 6, Update the
permissions configuration entry for Bash(jj rebase *) to remove the broad rule
or replace it with a narrowly scoped permission such as Bash(jj rebase
--continue *) that permits only the intended workflow.

Source: Path instructions

"Bash(rm -f resources/grafana/generated/dashboards/new-panel.yaml resources/grafana/sources/.claude/settings.local.json)",
"Bash(rmdir resources/grafana/sources/.claude)",
"Bash(jj commit -m 'ROX-34665: Add Scans per Day by Namespace panel to cluster overview dashboard *)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

python - <<'PY'
import json

path = "resources/grafana/sources/.claude/settings.local.json"
with open(path, encoding="utf-8") as stream:
    rules = json.load(stream)["permissions"]["allow"]

rule = next(rule for rule in rules if rule.startswith("Bash(jj commit"))
body = rule[len("Bash("):-1]

if body.count("'") % 2:
    raise SystemExit("Commit permission has unbalanced single quotes")
if body.endswith(" *"):
    raise SystemExit("Commit permission is broader than the exact command")
PY

Repository: stackrox/rhacs-observability-resources

Length of output: 223


🌐 Web query:

Claude Code IAM Bash rules exact Bash(command) prefix Bash(command:*)

💡 Result:

Claude Code uses flexible pattern matching for Bash command permissions, supporting exact matches, wildcard patterns, and a specialized cmd: specifier [1][2]. ### Bash Permission Matching Syntax Claude Code evaluates rules based on the following patterns: * Exact Matches: Bash(npm run build) allows only that specific command [3][2]. * Wildcard Patterns: Use * to match arbitrary characters [3]. * Bash(npm *): Matches any command starting with npm . * Bash(* install): Matches any command ending with install [3][4]. * Bash(git * main): Matches commands with mid-string wildcards, such as git checkout main [3]. * Note: The presence of a space before the * is significant. Bash(ls *) matches ls -la but not lsof, whereas Bash(ls*) matches both [3][2]. * Legacy Prefix Syntax: The :* suffix (e.g., Bash(git:*)) is a legacy, deprecated syntax equivalent to using a wildcard space pattern [1][2]. ### The cmd: Specifier The cmd: prefix matches against the base command name, providing resilience against quoted arguments, shell operators, and special characters [2]. * Bash(cmd:git): Matches any invocation where the base command is git, regardless of arguments [2]. * Bash(cmd:git *): Matches any git command followed by any arguments [2]. * Bash(cmd:*): Matches all Bash commands (functionally equivalent to Bash) [2]. ### Important Considerations * Compound Commands: Claude Code recognizes shell operators (&&, ||, ;, |, |&, &, newlines). Rules must match each subcommand independently; a rule like Bash(safe-cmd *) does not grant permission to execute safe-cmd && dangerous-cmd [3][1]. * Security Warning: Bash permission patterns are fragile and should not be relied upon as a primary security boundary [5]. They can often be bypassed by flag reordering, protocol changes, or using shell variables [5]. * Automatic Stripping: Safe wrapper commands (e.g., timeout, nice) and safe environment variable assignments are automatically stripped before matching so that permission rules apply to the core command [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
sed -n '1,40p' resources/grafana/sources/.claude/settings.local.json | cat -n

Repository: stackrox/rhacs-observability-resources

Length of output: 789


Fix the commit permission pattern.

The rule opens a single quote before the commit message but never closes it before *). It will not match the intended quoted commit command.

Use an exact rule:

Proposed fix
-      "Bash(jj commit -m 'ROX-34665: Add Scans per Day by Namespace panel to cluster overview dashboard *)"
+      "Bash(jj commit -m 'ROX-34665: Add Scans per Day by Namespace panel to cluster overview dashboard')"
📝 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
"Bash(jj commit -m 'ROX-34665: Add Scans per Day by Namespace panel to cluster overview dashboard *)"
"Bash(jj commit -m 'ROX-34665: Add Scans per Day by Namespace panel to cluster overview dashboard')"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/grafana/sources/.claude/settings.local.json` at line 9, Update the
Bash permission rule in the local Claude settings so the commit-message quote is
properly closed before the wildcard suffix, making the pattern match the
intended quoted jj commit command exactly.

]
}
}
141 changes: 139 additions & 2 deletions resources/grafana/sources/rhacs-cluster-overview.json
Original file line number Diff line number Diff line change
Expand Up @@ -2119,13 +2119,150 @@
],
"type": "table"
},
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"fieldConfig": {
"defaults": {
"custom": {
"align": "auto",
"cellOptions": {
"type": "auto"
},
"inspect": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"color": {
"mode": "thresholds"
}
},
"overrides": [
{
"matcher": {
"id": "byName",
"options": "namespace\\namespace"
},
"properties": [
{
"id": "custom.width",
"value": 236
}
]
},
{
"matcher": {
"id": "byName",
"options": "namespace\\Time"
},
"properties": [
{
"id": "custom.width",
"value": 232
}
]
},
{
"matcher": {
"id": "byName",
"options": "2026-05-08"
},
"properties": [
{
"id": "custom.width",
"value": 122
}
]
}
]
},
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 85
},
"id": 150,
"interval": "1d",
"maxDataPoints": 30,
"options": {
"showHeader": true,
"cellHeight": "sm",
"footer": {
"show": false,
"reducer": ["sum"],
"countRows": false,
"fields": ""
},
"sortBy": [
{
"displayName": "namespace\\Time",
"desc": true
}
]
},
"pluginVersion": "11.1.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "PBFA97CFB590B2093"
},
"editorMode": "code",
"exemplar": false,
"expr": "sum by (namespace) (increase(rox_central_scan_duration_count[1d]))",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restrict the query to the dashboard namespace scope.

Line 2227 aggregates scans from every namespace in the datasource. It ignores the $instance_id selection that existing dashboard panels use. This can show unrelated scan counts and increases query cost.

Proposed fix
- "expr": "sum by (namespace) (increase(rox_central_scan_duration_count[1d]))",
+ "expr": "sum by (namespace) (increase(rox_central_scan_duration_count{namespace=~\"rhacs-$instance_id\"}[1d]))",

As per path instructions, focus on “major issues impacting performance, readability, maintainability and security.”

📝 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
"expr": "sum by (namespace) (increase(rox_central_scan_duration_count[1d]))",
"expr": "sum by (namespace) (increase(rox_central_scan_duration_count{namespace=~\"rhacs-$instance_id\"}[1d]))",
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@resources/grafana/sources/rhacs-cluster-overview.json` at line 2227, Update
the Prometheus expression in the scan-count panel to filter
rox_central_scan_duration_count by the selected $instance_id label before
aggregating by namespace, matching the namespace scoping used by existing
dashboard panels.

Source: Path instructions

"format": "table",
"instant": false,
"interval": "",
"legendFormat": "__auto",
"range": true,
"refId": "A"
}
],
"timeFrom": "$_relativeTime/d",
"timeShift": "$_timeShift/d",
"title": "Scans per 24h by Namespace",
"transformations": [
{
"id": "formatTime",
"options": {
"outputFormat": "YYYY-MM-DD",
"timeField": "Time",
"useTimezone": true
}
},
{
"id": "groupingToMatrix",
"options": {
"columnField": "Time",
"rowField": "namespace",
"valueField": "Value"
}
}
],
"type": "table"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 85
"y": 93
},
"id": 149,
"panels": [],
Expand Down Expand Up @@ -2172,7 +2309,7 @@
"h": 13,
"w": 24,
"x": 0,
"y": 86
"y": 94
},
"id": 148,
"options": {
Expand Down
Loading