# Using AWS Security Agent for Diff Scanning in Pre-Commit and Pre-PR Pipelines

> Accelerate your CI/CD with AWS Security Agent for diff scanning. Inspect only changed code in pre-commit and pre-PR pipelines for rapid validation. Secure your repository efficiently.

- Repository: [Amazon Web Services/agent-toolkit-for-aws](https://github.com/aws/agent-toolkit-for-aws)
- Tags: how-to-guide
- Published: 2026-07-02

---

**The AWS Security Agent diff scan inspects only changed code since a Git reference, making it ideal for fast pre-commit and pre-PR pipeline validation.**

The **AWS Security Agent** (ASA) provides a lightweight diff scanning capability within the `aws/agent-toolkit-for-aws` repository that analyzes precisely what has changed in your Git history. This targeted approach delivers security findings in seconds rather than minutes, fitting naturally into developer workflows where rapid feedback prevents vulnerabilities from reaching production. Unlike full repository scans, the diff scan requires no prior historical artifacts and operates statelessly, making it perfect for CI/CD guardrails.

## How the Diff Scan Works

The diff scanning workflow follows a deterministic eight-step process defined in [`plugins/aws-agents-for-devsecops/skills/diff-scanning-with-aws-security-agent/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/plugins/aws-agents-for-devsecops/skills/diff-scanning-with-aws-security-agent/SKILL.md).

### Local Configuration Resolution

The skill first reads [`.security-agent/config.json`](https://github.com/aws/agent-toolkit-for-aws/blob/main/.security-agent/config.json) to obtain the `agent_space_id` and AWS `region`. If this configuration is missing, the `setup-security-agent` workflow executes automatically to provision the necessary local state.

### Base Reference Selection

You specify the Git reference against which to generate the diff:

- `HEAD` for uncommitted changes in the working directory
- `main` (or any branch name) for branch-comparison scenarios
- A custom Git ref supplied via the `BASE_REF` parameter

### Diff Generation and Early Exit

The tool runs `git diff` to create a patch file at `/tmp/diff.patch`. If the diff is empty, the scan aborts immediately, preventing unnecessary uploads and API calls.

### Workspace Packaging

The entire repository is zipped into `/tmp/source.zip`, excluding large or transient directories using the same exclusion list as full scans. This keeps uploads under the 2 GB limit enforced by the service.

### S3 Upload Operation

Both the source zip and diff patch upload to `security-agent-scans-<account>-<region>` using standard `aws s3 cp` commands.

### CodeReview Initialization

The skill creates or fetches a **CodeReview** object via `aws securityagent create-code-review`, attaching the uploaded source zip as an asset.

### Diff Job Execution

The diff patch is passed to `aws securityagent start-code-review-job` using the `--diff-source` argument. The service returns a `codeReviewJobId` that is persisted locally in [`.security-agent/scans.json`](https://github.com/aws/agent-toolkit-for-aws/blob/main/.security-agent/scans.json).

### Polling and Results Retrieval

The agent polls `aws securityagent batch-get-code-review-jobs` every two minutes. Once the job reaches **COMPLETED**, findings download as a markdown report (`findings-<scan_id>.md`) scoped specifically to the changed lines.

## Why It Fits Pre-Commit and Pre-PR Pipelines

The architectural design of the ASA diff scan aligns perfectly with fast-feedback CI/CD patterns:

- **Speed** – Only changed files undergo analysis, reducing scan duration from minutes to seconds
- **Self-contained** – The workflow requires no prior full-scan artifacts to establish a baseline
- **Deterministic scope** – Findings map directly to the diff, showing developers exactly which new changes introduced vulnerabilities
- **Fail-fast behavior** – Empty diffs trigger immediate exit without network overhead or cost
- **Stateless execution** – All metadata resides in `.security-agent/` or S3, making it safe for ephemeral CI runners

## Implementation Examples

### Pre-Commit Hook (Bash)

Add this script to `.git/hooks/pre-commit` to block commits with security issues:

```bash
#!/usr/bin/env bash

# .git/hooks/pre-commit

# Load the Agent Toolkit command (installed via MCP)

mcp run diff-scanning-with-aws-security-agent \
  BASE_REF=HEAD \
  --no-interactive   # suppress prompts for CI

```

The `BASE_REF=HEAD` flag targets uncommitted changes, while `--no-interactive` forces the skill to use default values from [`.security-agent/config.json`](https://github.com/aws/agent-toolkit-for-aws/blob/main/.security-agent/config.json) instead of hanging for input.

### Pre-PR GitHub Action

Integrate into pull request workflows to scan changes against the target branch:

```yaml
name: Security Diff Scan
on:
  pull_request:
    types: [opened, synchronize, reopened]

jobs:
  diff-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install Agent Toolkit
        run: |
          curl -fsSL https://aws-agent-toolkit-for-aws.s3.amazonaws.com/install.sh | bash
      - name: Run ASA Diff Scan
        env:
          AWS_DEFAULT_REGION: us-east-1
        run: |
          mcp run diff-scanning-with-aws-security-agent \
            BASE_REF=origin/main \
            --no-interactive

```

This configuration uses `origin/main` as the comparison baseline. The workflow leaves a markdown findings file in `.security-agent/findings-*.md`, which you can surface as a PR comment using `gh pr comment`.

### Polling and Reporting (Python)

For environments preferring Python over shell scripts, implement the polling logic manually:

```python
import json, subprocess, time, pathlib

def poll_job(agent_space, job_id):
    while True:
        out = subprocess.check_output([
            "aws", "securityagent", "batch-get-code-review-jobs",
            "--agent-space-id", agent_space,
            "--code-review-job-ids", job_id,
            "--output", "json"
        ])
        status = json.loads(out)["codeReviewJobs"][0]["status"]
        if status == "COMPLETED":
            return
        if status in ("FAILED", "CANCELLED"):
            raise RuntimeError(f"Job {job_id} ended with {status}")
        time.sleep(120)   # 2-minute interval

# Example usage after the diff-scan step

agent_space = "<id>"
job_id = "<codeReviewJobId>"
poll_job(agent_space, job_id)

# Retrieve findings

subprocess.run([
    "aws", "securityagent", "get-code-review-findings",
    "--agent-space-id", agent_space,
    "--code-review-id", "<cr-id>",
    "--output", "text",
    "--query", "findings[].markdown"
], capture_output=True, text=True)

```

This mirrors the polling behavior implemented in the skill and allows custom reporting logic or integration with existing security dashboards.

## Summary

- The AWS Security Agent diff scan targets only changed code via `git diff`, creating a patch at `/tmp/diff.patch` before uploading to S3
- Configuration resides in [`.security-agent/config.json`](https://github.com/aws/agent-toolkit-for-aws/blob/main/.security-agent/config.json) with automatic provisioning via `setup-security-agent` if missing
- The `aws securityagent start-code-review-job` command accepts the diff via `--diff-source`, returning a job ID tracked in [`.security-agent/scans.json`](https://github.com/aws/agent-toolkit-for-aws/blob/main/.security-agent/scans.json)
- Polling occurs every two minutes using `batch-get-code-review-jobs` until status reaches **COMPLETED**
- Ideal for pre-commit hooks (using `BASE_REF=HEAD`) and pre-PR pipelines (using `BASE_REF=origin/main`) due to sub-minute execution times
- Fail-fast design aborts on empty diffs, preventing unnecessary API calls and costs

## Frequently Asked Questions

### What is the maximum file size for diff scanning uploads?

The AWS Security Agent enforces a 2 GB limit on the source zip file, identical to full scan constraints. The skill automatically excludes directories like `node_modules`, `.git`, and build artifacts to keep uploads within this boundary according to the exclusion rules defined in [`plugins/aws-agents-for-devsecops/skills/diff-scanning-with-aws-security-agent/SKILL.md`](https://github.com/aws/agent-toolkit-for-aws/blob/main/plugins/aws-agents-for-devsecops/skills/diff-scanning-with-aws-security-agent/SKILL.md).

### Can I run diff scans without a prior full repository scan?

Yes. The diff scanning workflow is completely self-contained and does not depend on historical scan artifacts. The service generates findings solely from the uploaded diff patch and source context, making it suitable for new repositories or feature branches without baseline data.

### How do I configure the S3 bucket for scan uploads?

The skill automatically resolves the bucket name following the pattern `security-agent-scans-<account>-<region>`, retrieving the account ID and region from [`.security-agent/config.json`](https://github.com/aws/agent-toolkit-for-aws/blob/main/.security-agent/config.json). If this configuration is missing, the `setup-security-agent` workflow creates the necessary local state and IAM roles before proceeding with the upload operation.

### What happens if the diff scan finds no security issues?

When the scan completes with no findings, the AWS Security Agent still generates a markdown report indicating a clean scan. The job status transitions to **COMPLETED** with an empty findings array, and the CLI returns exit code 0, allowing your pre-commit or pre-PR pipeline to continue uninterrupted.