Skip to content

feat(sdk): add Data Pipeline secret scanning check#11821

Open
YinkaMetrics wants to merge 3 commits into
prowler-cloud:masterfrom
YinkaMetrics:yinka/datapipeline-secrets-check
Open

feat(sdk): add Data Pipeline secret scanning check#11821
YinkaMetrics wants to merge 3 commits into
prowler-cloud:masterfrom
YinkaMetrics:yinka/datapipeline-secrets-check

Conversation

@YinkaMetrics

@YinkaMetrics YinkaMetrics commented Jul 2, 2026

Copy link
Copy Markdown

Context

Fixes #11818

Description

Adds AWS Data Pipeline support to the SDK and a new datapipeline_pipeline_no_secrets_in_definition check. The check scans Data Pipeline objects, parameter objects, and parameter values with the shared secret-scanning helper, reports the pipeline/object context without exposing secret values, and uses the existing verified-secret annotation path so live secrets are raised to critical.

Also updates the Prowler scan role additions policy and CloudFormation template with the read-only Data Pipeline permissions needed for collection.

Steps to review

  1. Review the new AWS Data Pipeline service collector.
  2. Review the new check metadata and secret line-context mapping.
  3. Run:
uv run pytest tests/providers/aws/services/datapipeline -q
uv run ruff check prowler/providers/aws/services/datapipeline tests/providers/aws/services/datapipeline
uv run ruff format --check prowler/providers/aws/services/datapipeline tests/providers/aws/services/datapipeline
python3 -m json.tool permissions/prowler-additions-policy.json

Local note: uv run cfn-lint permissions/templates/cloudformation/prowler-scan-role.yml currently reports pre-existing warning W1031 on the S3 integration bucket ARN substitution, outside the Data Pipeline change.

Checklist

Community Checklist
  • This feature/issue is listed in here or roadmap.prowler.com
  • Is it assigned to me, if not, request it via the issue/feature in here or Prowler Community Slack
  • Review if the code is being covered by tests.
  • Review if code is being documented following this specification https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings
  • Review if backport is needed.
  • Review if is needed to change the Readme.md
  • Ensure new entries are added to CHANGELOG.md, if applicable. The current SDK changelog top block is released v5.32.0 and there is no Prowler UNRELEASED block to edit yet.

SDK/CLI

  • Are there new checks included in this PR? Yes
    • If so, do we need to update permissions for the provider? Yes. Added datapipeline:GetPipelineDefinition and datapipeline:ListPipelines to the scan role additions.

UI

  • All issue/task requirements work as expected on the UI
  • If this PR adds or updates npm dependencies, include package-health evidence (maintenance, popularity, known vulnerabilities, license, release age) and explain why existing/native alternatives are insufficient.
  • Screenshots/Video of the functionality flow (if applicable) - Mobile (X < 640px)
  • Screenshots/Video of the functionality flow (if applicable) - Table (640px > X < 1024px)
  • Screenshots/Video of the functionality flow (if applicable) - Desktop (X > 1024px)
  • Ensure new entries are added to CHANGELOG.md, if applicable.

API

  • All issue/task requirements work as expected on the API
  • Endpoint response output (if applicable)
  • EXPLAIN ANALYZE output for new/modified queries or indexes (if applicable)
  • Performance test results (if applicable)
  • Any other relevant evidence of the implementation (if applicable)
  • Verify if API specs need to be regenerated.
  • Check if version updates are required (e.g., specs, uv, etc.).
  • Ensure new entries are added to CHANGELOG.md, if applicable.

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

Summary by CodeRabbit

  • New Features
    • Added AWS Data Pipeline support to retrieve pipeline metadata and definitions for scanning.
    • Introduced a new check to detect hardcoded secrets in Data Pipeline definitions, reporting PASS/FAIL (or MANUAL when scanning fails).
  • Bug Fixes
    • Expanded read-only permissions to allow listing and describing Data Pipeline resources and retrieving pipeline definitions.
  • Tests
    • Added unit test coverage for Data Pipeline discovery/definition loading and for secret-detection scenarios, including verified findings and scan error handling.

@YinkaMetrics YinkaMetrics requested a review from a team as a code owner July 2, 2026 13:10
@github-actions github-actions Bot added provider/aws Issues/PRs related with the AWS provider metadata-review labels Jul 2, 2026
@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a new AWS Data Pipeline service, a secret-scanning check for pipeline definitions, required IAM permissions, and tests covering pipeline loading and scan outcomes.

Changes

Data Pipeline secret detection

Layer / File(s) Summary
IAM permission updates for Data Pipeline read access
permissions/prowler-additions-policy.json, permissions/templates/cloudformation/prowler-scan-role.yml
Adds Data Pipeline read permissions to the shared policy and scan role IAM template.
DataPipeline service and Pipeline model
prowler/providers/aws/services/datapipeline/datapipeline_service.py, prowler/providers/aws/services/datapipeline/datapipeline_client.py, prowler/providers/aws/services/datapipeline/__init__.py
Defines the Pipeline model, loads pipelines across regions, fetches tags and definitions, and exposes a module-level DataPipeline client.
Secret-scanning check implementation and metadata
prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/__init__.py, prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition.metadata.json, prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition.py
Adds the check metadata and execute logic that builds payloads, runs batch secret detection, and reports PASS, FAIL, or MANUAL results.
Check test suite
tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/*
Adds tests for empty, clean, secret-containing, verified-secret, and scan-error pipeline definitions, plus helpers for building pipelines and running the check.
DataPipeline service test
tests/providers/aws/services/datapipeline/datapipeline_service_test.py
Adds mocked AWS API tests that validate pipeline listing, tagging, definition loading, and the describe-failure branch.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DataPipeline as DataPipeline
  participant RegionalClient as AWS Data Pipeline regional client
  participant Pipeline as Pipeline

  DataPipeline->>RegionalClient: list_pipelines
  RegionalClient-->>DataPipeline: pipeline ids and names
  DataPipeline->>Pipeline: create ARN and region entry
  DataPipeline->>RegionalClient: describe_pipelines
  RegionalClient-->>DataPipeline: tags
  DataPipeline->>RegionalClient: get_pipeline_definition
  RegionalClient-->>DataPipeline: pipelineObjects, parameterObjects, parameterValues
  DataPipeline->>Pipeline: store tags and definition
Loading
sequenceDiagram
  participant Check as datapipeline_pipeline_no_secrets_in_definition
  participant Client as datapipeline_client
  participant Scanner as detect_secrets_scan_batch

  Check->>Client: read pipelines
  Check->>Check: _build_definition_payload(definition)
  Check->>Scanner: scan payloads with ignore/validate settings
  Scanner-->>Check: scan results or SecretsScanError
  Check->>Check: annotate_verified_secrets on FAIL
  Check-->>Check: emit PASS/FAIL/MANUAL reports
Loading

Possibly related PRs

Suggested reviewers: danibarranqueroo, HugoPBrito

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a Data Pipeline secret scanning check.
Description check ✅ Passed The description includes context, a clear summary, review steps, and checklist notes, matching the template well.
Linked Issues check ✅ Passed The changes satisfy #11818 by adding Data Pipeline collection, scanning definitions for secrets, and escalating verified findings to critical.
Out of Scope Changes check ✅ Passed The PR stays focused on Data Pipeline support, secret scanning, tests, and required permissions updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@github-actions github-actions Bot added the community Opened by the Community label Jul 2, 2026
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

No Conflicts

No conflict markers, and the branch merges cleanly into its base.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with 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.

Inline comments:
In
`@prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition.py`:
- Around line 19-42: The generator-based payload construction in the
Datapipeline secret check can leave later pipelines without line context if
detect_secrets_scan_batch raises early, causing the reporting loop to fall back
to PASS. Materialize the payload and line-context mapping up front in
datapipeline_pipeline_no_secrets_in_definition (around payloads() and the
scan_error handling) so every pipeline index is recorded before calling
detect_secrets_scan_batch, and keep the MANUAL path in the result loop based on
scan_error even when a pipeline was not reached by the scanner.

In `@prowler/providers/aws/services/datapipeline/datapipeline_service.py`:
- Around line 9-17: The Pipeline model currently defines tags but they are never
populated, so report.resource_tags remains empty. Update the AWS Data Pipeline
flow in datapipeline_service.py so the tags returned by describe_pipelines are
copied onto Pipeline.tags when building the model, using the existing Pipeline
class and list_pipelines/describe_pipelines data path; if tags cannot be
propagated, remove the unused tags field instead.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 5f07cb1e-8cb0-4a57-a6dc-7e435d221fb5

📥 Commits

Reviewing files that changed from the base of the PR and between 4ae7c67 and c5720e7.

📒 Files selected for processing (11)
  • permissions/prowler-additions-policy.json
  • permissions/templates/cloudformation/prowler-scan-role.yml
  • prowler/providers/aws/services/datapipeline/__init__.py
  • prowler/providers/aws/services/datapipeline/datapipeline_client.py
  • prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/__init__.py
  • prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition.metadata.json
  • prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition.py
  • prowler/providers/aws/services/datapipeline/datapipeline_service.py
  • tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/__init__.py
  • tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition_test.py
  • tests/providers/aws/services/datapipeline/datapipeline_service_test.py

Comment thread prowler/providers/aws/services/datapipeline/datapipeline_service.py

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
prowler/providers/aws/services/datapipeline/datapipeline_service.py (1)

67-79: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Split error handling so a describe_pipelines failure doesn't block the actual secret scan.

describe_pipelines (tags-only, cosmetic) and get_pipeline_definition (the data the security check actually scans) share one try/except. If describe_pipelines raises (e.g. throttling, missing permission — see next comment), get_pipeline_definition never runs and pipeline.definition stays at its empty default. Downstream, the datapipeline_pipeline_no_secrets_in_definition check would then scan an empty definition and likely report PASS, silently missing real secrets instead of flagging a scan failure.

🛠️ Proposed fix: isolate the tags fetch
         try:
             regional_client = self.regional_clients[pipeline.region]
-            pipeline_descriptions = regional_client.describe_pipelines(
-                pipelineIds=[pipeline.id]
-            ).get("pipelineDescriptionList", [])
-            if pipeline_descriptions:
-                pipeline.tags = pipeline_descriptions[0].get("tags", [])
+            try:
+                pipeline_descriptions = regional_client.describe_pipelines(
+                    pipelineIds=[pipeline.id]
+                ).get("pipelineDescriptionList", [])
+                if pipeline_descriptions:
+                    pipeline.tags = pipeline_descriptions[0].get("tags", [])
+            except (ClientError, Exception) as error:
+                logger.error(
+                    f"{pipeline.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
+                )
             definition = regional_client.get_pipeline_definition(pipelineId=pipeline.id)
🤖 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 `@prowler/providers/aws/services/datapipeline/datapipeline_service.py` around
lines 67 - 79, The shared try/except in DatapipelineService is letting a
tags-only `describe_pipelines` failure prevent `get_pipeline_definition` from
running, which can leave `pipeline.definition` empty and hide real findings.
Refactor the logic in `DatapipelineService` so the `describe_pipelines` call is
isolated from the definition fetch: keep tag loading best-effort, but always
attempt `get_pipeline_definition` and assign `pipeline.definition` even if tag
retrieval fails. Use the existing `regional_client`, `describe_pipelines`, and
`get_pipeline_definition` calls as the key places to split the error handling.
🤖 Prompt for all review comments with 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.

Inline comments:
In `@prowler/providers/aws/services/datapipeline/datapipeline_service.py`:
- Around line 69-71: The Data Pipeline scan path now calls describe_pipelines in
datapipeline_service, but the scan role permissions are missing
datapipeline:DescribePipelines, which causes AccessDeniedException when
resources are found. Update the scan-role permission sources in
permissions/prowler-additions-policy.json and
permissions/templates/cloudformation/prowler-scan-role.yml to include the new
action alongside GetPipelineDefinition and ListPipelines so pipeline tags can be
retrieved successfully.

In
`@tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition_test.py`:
- Around line 108-151: The current test coverage only verifies PASS/FAIL/MANUAL
outcomes in test_scan_error_marks_all_scannable_pipelines_manual, but it does
not exercise the verified-secret path. Add a focused test around _execute_check
/ detect_secrets_scan_batch that simulates a live-verified secret using the
annotate_verified_secrets or validate flag, and assert the resulting report
severity is escalated to Critical. Use the existing datapipeline_client and
report assertions pattern so the new test clearly covers the verified-secret
branch.

In `@tests/providers/aws/services/datapipeline/datapipeline_service_test.py`:
- Around line 33-53: Add a companion test around the datapipeline service path
covered by mock_make_api_call and the pipeline.tags assertion that simulates
DescribePipelines failing while GetPipelineDefinition still succeeds. Use the
existing Datapipeline service test helpers and the pipeline/pipeline_definition
fixtures to verify the service’s split try/except behavior still populates
pipeline.definition even when DescribePipelines raises, and keep the new tags
assertion in the happy-path test.

---

Outside diff comments:
In `@prowler/providers/aws/services/datapipeline/datapipeline_service.py`:
- Around line 67-79: The shared try/except in DatapipelineService is letting a
tags-only `describe_pipelines` failure prevent `get_pipeline_definition` from
running, which can leave `pipeline.definition` empty and hide real findings.
Refactor the logic in `DatapipelineService` so the `describe_pipelines` call is
isolated from the definition fetch: keep tag loading best-effort, but always
attempt `get_pipeline_definition` and assign `pipeline.definition` even if tag
retrieval fails. Use the existing `regional_client`, `describe_pipelines`, and
`get_pipeline_definition` calls as the key places to split the error handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b837a1d3-008b-4d5e-a692-08baaf65f414

📥 Commits

Reviewing files that changed from the base of the PR and between c5720e7 and 37ba71a.

📒 Files selected for processing (4)
  • prowler/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition.py
  • prowler/providers/aws/services/datapipeline/datapipeline_service.py
  • tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition_test.py
  • tests/providers/aws/services/datapipeline/datapipeline_service_test.py

Comment thread prowler/providers/aws/services/datapipeline/datapipeline_service.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition_test.py (1)

108-149: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Good addition — resolves prior gap on verified-secret escalation coverage.

This test correctly exercises the verified-secret path (is_verified: TrueSeverity.critical, "confirmed to be live"), addressing the previously flagged coverage gap.

One minor nit: Severity is imported locally inside the test method (Line 109) instead of at the top of the file with other imports, which is inconsistent with the rest of the file's style.

🧹 Optional cleanup
-    def test_pipeline_with_verified_secret_escalates_severity(self):
-        from prowler.lib.check.models import Severity
-
-        pipeline = _build_pipeline(
+    def test_pipeline_with_verified_secret_escalates_severity(self):
+        pipeline = _build_pipeline(

And add at the top of the file:

from prowler.lib.check.models import Severity
🤖 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
`@tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition_test.py`
around lines 108 - 149, The new verified-secret test is correct, but the
`Severity` import is inconsistent because it is done locally inside
`test_pipeline_with_verified_secret_escalates_severity` instead of with the
file’s other imports. Move the `Severity` import to the top-level import section
so the test method only uses it, matching the style used elsewhere in the test
module. Use the `test_pipeline_with_verified_secret_escalates_severity` symbol
to locate the cleanup.
🤖 Prompt for all review comments with 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.

Duplicate comments:
In
`@tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition_test.py`:
- Around line 108-149: The new verified-secret test is correct, but the
`Severity` import is inconsistent because it is done locally inside
`test_pipeline_with_verified_secret_escalates_severity` instead of with the
file’s other imports. Move the `Severity` import to the top-level import section
so the test method only uses it, matching the style used elsewhere in the test
module. Use the `test_pipeline_with_verified_secret_escalates_severity` symbol
to locate the cleanup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 608ae993-3319-48da-9910-fb2de624e114

📥 Commits

Reviewing files that changed from the base of the PR and between 37ba71a and 72abcbb.

📒 Files selected for processing (5)
  • permissions/prowler-additions-policy.json
  • permissions/templates/cloudformation/prowler-scan-role.yml
  • prowler/providers/aws/services/datapipeline/datapipeline_service.py
  • tests/providers/aws/services/datapipeline/datapipeline_pipeline_no_secrets_in_definition/datapipeline_pipeline_no_secrets_in_definition_test.py
  • tests/providers/aws/services/datapipeline/datapipeline_service_test.py

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

Labels

community Opened by the Community metadata-review new-check provider/aws Issues/PRs related with the AWS provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[New Check]: Detect secrets in AWS Data Pipeline definitions

2 participants