Skip to content

Add audit script for ECS short ARNs#1

Open
derek-palmer wants to merge 1 commit into
mainfrom
add-ecs-short-arn-checks
Open

Add audit script for ECS short ARNs#1
derek-palmer wants to merge 1 commit into
mainfrom
add-ecs-short-arn-checks

Conversation

@derek-palmer
Copy link
Copy Markdown
Owner

@derek-palmer derek-palmer commented Mar 24, 2026

Summary by CodeRabbit

  • New Features
    • Added an audit script to validate ECS service ARN formats across your clusters, repositories, and IAM resources.

@derek-palmer derek-palmer self-assigned this Mar 24, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 24, 2026

📝 Walkthrough

Walkthrough

A new Bash script audit-ecs-short-arns.sh added to audit ECS clusters and sources for short-form service ARN usage. The script validates ARN formats across repository scans, AWS credentials, ECS service discovery, and IAM policy analysis.

Changes

Cohort / File(s) Summary
ECS Audit Script
scripts/audit-ecs-short-arns.sh
New executable Bash script with 436 lines implementing multi-phase ARN auditing: repository scanning via ripgrep, AWS credential verification, ECS service discovery and validation, and IAM customer-managed and inline role policy scanning. Enforces short-form ARN pattern detection across distributed sources with configurable skips and batch processing.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant Script as audit-ecs-short-arns.sh
    participant Repo as Repository
    participant AWS as AWS STS
    participant ECS as AWS ECS API
    participant IAM as AWS IAM API
    
    User->>Script: Execute with --cluster, --region, etc.
    
    rect rgba(0, 100, 150, 0.5)
    Note over Script,Repo: Phase 1: Repository Scan
    Script->>Repo: ripgrep for arn:aws:ecs:*:service/*
    Repo-->>Script: Matching references
    end
    
    rect rgba(0, 150, 100, 0.5)
    Note over Script,AWS: Phase 2: AWS Verification
    Script->>AWS: get-caller-identity
    AWS-->>Script: Account ID validation
    end
    
    rect rgba(100, 150, 0, 0.5)
    Note over Script,ECS: Phase 3: ECS Service Validation
    Script->>ECS: list-services (or use --service)
    ECS-->>Script: Service names
    Script->>ECS: describe-services (batches of 10)
    ECS-->>Script: Service ARN shapes
    Script->>Script: Validate ARN format patterns
    end
    
    rect rgba(150, 100, 0, 0.5)
    Note over Script,IAM: Phase 4 & 5: IAM Policy Scanning
    Script->>IAM: list-policies (customer-managed)
    IAM-->>Script: Policy list
    Script->>IAM: get-policy-version
    IAM-->>Script: Policy documents
    Script->>IAM: list-roles
    IAM-->>Script: Role list
    Script->>IAM: get-role-policy
    IAM-->>Script: Inline policy documents
    Script->>Script: Search for short-form ARN patterns
    end
    
    Script-->>User: Pass/Fail with audit results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hoppy audits ECS with care,
Short ARNs spotted everywhere!
From repos to IAM's nest,
This script puts ARNs to the test.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title clearly and concisely describes the main change: adding a new audit script for ECS short ARNs, which matches the new executable script file added to the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-ecs-short-arn-checks
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch add-ecs-short-arn-checks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
audit-ecs-short-arns.sh (2)

14-14: Declare and assign separately to avoid masking return values.

Per SC2155: if the subshell fails, the exit code is masked by the readonly declaration. Split declaration and assignment for proper error handling.

Proposed fix
-readonly REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
+readonly REPO_ROOT
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit-ecs-short-arns.sh` at line 14, Split the readonly declaration and the
subshell assignment to avoid masking the subshell exit status: first declare the
variable name (REPO_ROOT) or assign it normally, then perform the subshell
expansion using "$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" and after
successful assignment mark REPO_ROOT readonly; reference the REPO_ROOT variable
and the use of "${BASH_SOURCE[0]}"/.. subshell in the change so reviewers can
locate and verify the fix.

184-184: Consider using jq for JSON parsing.

Parsing JSON with awk -F'"' is fragile and depends on specific formatting. If jq is available (common in AWS environments), it's more robust:

Proposed fix
-  actual_aws_account_id="$(awk -F'"' '/"Account"/{print $4}' <<< "$caller_identity")"
+  actual_aws_account_id="$(jq -r '.Account' <<< "$caller_identity")"

Add jq to require_command in main() if adopted.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit-ecs-short-arns.sh` at line 184, Replace the fragile awk JSON parsing
that assigns actual_aws_account_id from caller_identity with a jq-based
extraction: read the caller_identity JSON and extract the Account field using
jq's raw output option, then assign that to actual_aws_account_id; also add jq
to the require_command list in main() so the script verifies jq is available
before use. Ensure you update the exact assignment line that references
actual_aws_account_id and the require_command array in main().
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@audit-ecs-short-arns.sh`:
- Around line 240-254: The script currently calls aws ecs describe-services
twice per batch; change it to call describe-services once, capture the JSON
output into a variable (e.g., services_json) using the same parameters (region,
cluster, --services "${batch[@]}"), then use that captured JSON to both render
the human-readable table and extract ARNs (e.g., use jq to format a table of
serviceArn, desiredCount, serviceName and to produce a whitespace-separated list
for batch_arns). Update references to batch_arns to use the parsed output from
services_json and remove the duplicate aws ecs describe-services invocation.

---

Nitpick comments:
In `@audit-ecs-short-arns.sh`:
- Line 14: Split the readonly declaration and the subshell assignment to avoid
masking the subshell exit status: first declare the variable name (REPO_ROOT) or
assign it normally, then perform the subshell expansion using "$(cd "$(dirname
"${BASH_SOURCE[0]}")/.." && pwd)" and after successful assignment mark REPO_ROOT
readonly; reference the REPO_ROOT variable and the use of "${BASH_SOURCE[0]}"/..
subshell in the change so reviewers can locate and verify the fix.
- Line 184: Replace the fragile awk JSON parsing that assigns
actual_aws_account_id from caller_identity with a jq-based extraction: read the
caller_identity JSON and extract the Account field using jq's raw output option,
then assign that to actual_aws_account_id; also add jq to the require_command
list in main() so the script verifies jq is available before use. Ensure you
update the exact assignment line that references actual_aws_account_id and the
require_command array in main().

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 62434334-73aa-4b4b-9d7c-4f22eb46a4b9

📥 Commits

Reviewing files that changed from the base of the PR and between b968145 and 36299b1.

📒 Files selected for processing (1)
  • audit-ecs-short-arns.sh

Comment thread audit-ecs-short-arns.sh
Comment on lines +240 to +254
aws ecs describe-services \
--region "$AWS_REGION" \
--cluster "$ECS_CLUSTER_NAME" \
--services "${batch[@]}" \
--query 'services[].{arn:serviceArn,desired:desiredCount,name:serviceName}' \
--output table

batch_arns="$(
aws ecs describe-services \
--region "$AWS_REGION" \
--cluster "$ECS_CLUSTER_NAME" \
--services "${batch[@]}" \
--query 'services[].serviceArn' \
--output text
)"
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 | 🟡 Minor

Duplicate AWS API calls in each batch iteration.

The aws ecs describe-services command is called twice per batch: once for table display and once to extract ARNs. This doubles API calls, increases execution time, and risks throttling.

Proposed fix - single API call with JSON parsing
   for (( i = 0; i < ${`#ECS_SERVICES`[@]}; i += batch_size )); do
     batch=("${ECS_SERVICES[@]:$i:$batch_size}")
 
-    aws ecs describe-services \
-      --region "$AWS_REGION" \
-      --cluster "$ECS_CLUSTER_NAME" \
-      --services "${batch[@]}" \
-      --query 'services[].{arn:serviceArn,desired:desiredCount,name:serviceName}' \
-      --output table
-
-    batch_arns="$(
-      aws ecs describe-services \
-        --region "$AWS_REGION" \
-        --cluster "$ECS_CLUSTER_NAME" \
-        --services "${batch[@]}" \
-        --query 'services[].serviceArn' \
-        --output text
-    )"
+    local batch_json
+    batch_json="$(
+      aws ecs describe-services \
+        --region "$AWS_REGION" \
+        --cluster "$ECS_CLUSTER_NAME" \
+        --services "${batch[@]}" \
+        --query 'services[].{arn:serviceArn,desired:desiredCount,name:serviceName}' \
+        --output json
+    )"
+
+    # Display table format
+    printf '%s\n' "$batch_json" | jq -r '["ARN","DESIRED","NAME"], (.[] | [.arn, .desired, .name]) | `@tsv`' | column -t
+
+    batch_arns="$(printf '%s\n' "$batch_json" | jq -r '.[].arn')"
📝 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
aws ecs describe-services \
--region "$AWS_REGION" \
--cluster "$ECS_CLUSTER_NAME" \
--services "${batch[@]}" \
--query 'services[].{arn:serviceArn,desired:desiredCount,name:serviceName}' \
--output table
batch_arns="$(
aws ecs describe-services \
--region "$AWS_REGION" \
--cluster "$ECS_CLUSTER_NAME" \
--services "${batch[@]}" \
--query 'services[].serviceArn' \
--output text
)"
local batch_json
batch_json="$(
aws ecs describe-services \
--region "$AWS_REGION" \
--cluster "$ECS_CLUSTER_NAME" \
--services "${batch[@]}" \
--query 'services[].{arn:serviceArn,desired:desiredCount,name:serviceName}' \
--output json
)"
# Display table format
printf '%s\n' "$batch_json" | jq -r '["ARN","DESIRED","NAME"], (.[] | [.arn, .desired, .name]) | `@tsv`' | column -t
batch_arns="$(printf '%s\n' "$batch_json" | jq -r '.[].arn')"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@audit-ecs-short-arns.sh` around lines 240 - 254, The script currently calls
aws ecs describe-services twice per batch; change it to call describe-services
once, capture the JSON output into a variable (e.g., services_json) using the
same parameters (region, cluster, --services "${batch[@]}"), then use that
captured JSON to both render the human-readable table and extract ARNs (e.g.,
use jq to format a table of serviceArn, desiredCount, serviceName and to produce
a whitespace-separated list for batch_arns). Update references to batch_arns to
use the parsed output from services_json and remove the duplicate aws ecs
describe-services invocation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant