Skip to content

Local Code Scan

Krishna Kishor Tirupati edited this page Jul 23, 2026 · 2 revisions

Local Code Scan

policyaware scan is a fast local governance and compliance scanner for AI application repositories.

It scans source code, policy files, notebooks, infrastructure config, and data pipeline code for risks that matter in LLM, RAG, MCP, and AI-agent applications.

It does not call models, does not call external services, and does not execute project code.

Install

pip install policyaware

For local development from the repository:

pip install -e ".[dev]"

Quick Start

Scan a local folder:

policyaware scan ./mylocalfolder

Default output:

policyaware-scan-report.html

Open the HTML report:

policyaware scan ./mylocalfolder --open

Generate all report formats:

policyaware scan ./mylocalfolder --format html,json,sarif,markdown

Fail CI on high or critical findings:

policyaware scan ./mylocalfolder --fail-on high

What It Checks

Area Examples Recommendation
PII Emails, phone numbers, SSNs, credit card-like values Redact before prompts reach models, tools, logs, or evals.
PHI Patient IDs, medical records, diagnosis or prescription language Use regulated-domain policies and redaction.
Secrets API keys, tokens, bearer tokens, secret assignments Move to environment variables or secret managers and rotate exposed keys.
Direct LLM calls OpenAI, Anthropic, Bedrock, Vertex, LiteLLM, Ollama, vLLM, LlamaIndex, DSPy, Semantic Kernel Route through Gateway.chat(...) before execution.
Provider governance Provider/framework usage without PolicyAware routing Route by approved provider, role, risk, region, cost, and availability policy.
Data residency External endpoints, regions, API bases, cloud locations Add tenant, region, and compliance constraints before regulated data leaves approved boundaries.
MCP/tool governance MCP tools, function calling, LangChain tools, risky actions Add connector/action policies and approval requirements.
Autonomous agents while True, agent.run, auto-execute patterns Add human approval, max iterations, budgets, and audit logs.
Cost governance Model or agent calls without token, timeout, rate, retry, or cost limits Define request-level and workflow-level limits.
RAG governance Retrieval, vector stores, embeddings, missing citations Add grounding, source metadata, and citation checks.
Guardrails integration NeMo Guardrails, Guardrails AI, custom guard usage, missing guard config Orchestrate guardrails through PolicyAware and declare guard behavior in YAML.
Data pipelines PySpark, Spark reads/writes, sensitive columns, cloud storage paths Mask sensitive columns and audit data writes.
Configuration governance .env, YAML, JSON, Terraform, Docker, CI/CD files Use secret manager references and avoid plaintext secrets.
YAML policy quality Policy schema errors and missing default: deny Validate policies and keep deny-by-default behavior.
Audit gaps Model calls without trace/audit language Capture request, decision, route, eval result, and response metadata.

Supported File Types

.py, .js, .jsx, .ts, .tsx, .java, .scala, .kt, .go, .rs, .sh
.yml, .yaml, .json, .toml, .ini, .properties, .env
.ipynb, .sql, .tf, .hcl, Dockerfile
.md, .txt, .example, .sample

The scanner extracts code and markdown text from Jupyter notebooks.

Report Formats

HTML report:

policyaware scan . --out policyaware-scan-report.html

JSON report:

policyaware scan . --json policyaware-scan-report.json

SARIF report:

policyaware scan . --sarif policyaware-scan-report.sarif

Markdown report:

policyaware scan . --markdown policyaware-scan-report.md

All formats:

policyaware scan . --format html,json,sarif,markdown

HTML Report

The generated HTML report includes:

  • executive summary
  • overall risk
  • severity counts
  • finding categories
  • compliance area counts
  • compliance-area filter
  • top recommendations
  • remediation checklist
  • finding table
  • findings grouped by file
  • redacted evidence
  • suggested fix snippets
  • guardrails orchestration findings
  • policy coverage score
  • governance reviewer summary
  • links to PolicyAware documentation

Scan Config YAML

Create policyaware-scan.yaml:

scan:
  include_extensions:
    - .py
    - .yaml
    - .json
    - .ipynb
    - .tf

  exclude_dirs:
    - tests/fixtures
    - generated

  ignore_patterns:
    - docs/examples/**

  disabled_categories:
    - Provider Governance

  severity_overrides:
    Data Residency: high
    Cost Governance: low

  max_file_size: 1mb
  max_findings_per_file: 30

Run it:

policyaware scan . --config policyaware-scan.yaml --format html,json,sarif,markdown

Use enabled_categories for a narrow scan:

scan:
  enabled_categories:
    - Secrets
    - PII
    - PHI
    - Configuration Governance

The repository includes a ready-to-use example:

policyaware scan . --config examples/policyaware-scan.yaml

Inline Suppressions

Suppress the next line:

# policyaware-ignore-next-line: documented test credential
OPENAI_API_KEY = "sk_test_abcdefghijklmnop"

Suppress the current line:

OPENAI_API_KEY = "sk_test_abcdefghijklmnop"  # policyaware-ignore-line: fixture

Suppress a whole file:

# policyaware-ignore-file: generated fixture

Use suppressions only for intentional examples, generated fixtures, or already-reviewed findings.

Ignore File

Create .policyawareignore:

tests/fixtures/**
docs/**
examples/demo-secrets.py

Run:

policyaware scan . --ignore-file .policyawareignore

Baseline

Create a baseline:

policyaware scan . --write-baseline policyaware-baseline.json

Use the baseline:

policyaware scan . --baseline policyaware-baseline.json --fail-on high

Baselines store stable finding fingerprints so teams can focus on new findings.

Git Diff Scanning

Scan only changed files in a pull request:

policyaware scan . --diff --diff-base origin/main --fail-on high

Use full scheduled scans for deeper repository coverage:

policyaware scan . --format html,json,sarif,markdown

CI Example

GitHub Actions:

name: PolicyAware Scan

on:
  pull_request:
  push:
    branches: [main]

jobs:
  policyaware-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install PolicyAware
        run: python -m pip install policyaware

      - name: Run PolicyAware scan
        run: |
          policyaware scan . \
            --out policyaware-scan-report.html \
            --config examples/policyaware-scan.yaml \
            --format html,json,sarif,markdown \
            --fail-on high

Python API

from pathlib import Path

from policyaware import LocalCodeScanner, ScanConfig

config = ScanConfig.from_file(Path("examples/policyaware-scan.yaml"))

report = LocalCodeScanner(workers=4, config=config).scan(
    Path("."),
    out=Path("policyaware-scan-report.html"),
    json_out=Path("policyaware-scan-report.json"),
    sarif_out=Path("policyaware-scan-report.sarif"),
    markdown_out=Path("policyaware-scan-report.md"),
)

print(report.overall_risk)
print(report.category_counts)
print(report.compliance_counts)

JSON Output Shape

{
  "overall_risk": "High",
  "policy_coverage_score": 78,
  "suppressed_findings": 1,
  "baseline_ignored": 0,
  "severity_counts": {
    "critical": 1,
    "high": 3
  },
  "category_counts": {
    "Secrets": 1,
    "LLM Governance": 2
  },
  "compliance_counts": {
    "Security / Secrets Management": 1,
    "Model Governance": 2
  },
  "compliance_framework_mapping": {
    "SOC 2": [
      "Secrets"
    ],
    "AI Governance": [
      "LLM Governance"
    ]
  },
  "scanned_files": [
    "app.py"
  ],
  "findings": []
}

Guardrails Scan Checks

policyaware scan detects guardrails-related governance gaps:

  • direct NeMo Guardrails or Guardrails AI usage outside PolicyAware orchestration
  • NeMo guard policy entries missing config_path or config
  • Guardrails AI policy entries missing rail_spec, rail, or spec
  • custom guard policy entries missing custom: true
  • guard policy entries without a when condition

Example finding category:

Guardrails Integration

Recommended fix:

guards:
  input:
    - name: nemo
      config_path: rails/
      when:
        request.task_type: chatbot
  output:
    - name: guardrails_ai
      rail_spec: guardrails/spec.rail
      when:
        request.output_format: json

Recommended Workflow

  1. Run policyaware scan . locally.
  2. Open policyaware-scan-report.html.
  3. Fix critical secrets first.
  4. Route direct LLM calls through Gateway.
  5. Add tool permissions and approval requirements.
  6. Add RAG citation and grounding checks.
  7. Add audit traces for model and tool execution.
  8. Re-run the scan.
  9. Add CI with --fail-on high.

Related Pages

Clone this wiki locally