Skip to content

Custom Mapping Definitions

This guide explains how to create custom YAML definitions to extend the resource mapper with patterns for non-standard SDKs or tool-specific client wrappers.

⚠️ Critical Requirements

1. Prefix Must Match Method Name Start

The prefix field filters which patterns to try. It must match the beginning of the method name.

❌ WRONG:

- name: "Custom Client"
  prefix: "_client."  # Method names start with "service_client", not "_client"
  rule: "(?<resource_group>[a-z0-9_]+)_client\\.(?<operation>[a-z0-9_]+)\\.values"

✅ CORRECT:

- name: "Custom Client"
  prefix: ""  # Empty prefix matches all method names
  rule: "(?<resource_group>[a-z0-9_]+)_client\\.(?<operation>[a-z0-9_]+)\\.values"

2. Use Inline Regex for Identifiers with Underscores

Grok's %{WORD} pattern only matches [a-zA-Z0-9]+ and excludes underscores. For service names like cognito_idp, use inline regex.

❌ WRONG:

rule: "%{WORD:resource_group}_client\\.%{WORD:operation}\\.values"
# Won't match "cognito_idp_client" - WORD stops at first underscore

✅ CORRECT:

rule: "(?<resource_group>[a-z0-9_]+)_client\\.(?<operation>[a-z0-9_]+)\\.values"
# Inline regex with named capture groups matches underscores

Usage

Local File

cce -folder ./myproject -language AUTO \\
    -mapper-file /path/to/custom_definition.yaml \\
    -filter all -format json -output findings.json

Remote HTTPS URL

cce -folder ./myproject -language AUTO \\
    -mapper-file https://example.com/definitions/custom.yaml \\
    -filter all -format json -output findings.json

YAML Structure

Data tables and prefixes_from

Share prefix lists across rules (see data tables in the repo):

dataTables:
  aws_v1_go:
    prefixes:
      - "github.com/aws/aws-sdk-go/service/"

definition:
  language:
    go:
      - name: "AWS SDK v1"
        prefixes_from: aws_v1_go
        provider: AWS_V1

CCE expands prefixes_from into one rule per prefix at load time.

Action hints (inventory only; pair with OpenRewrite)

Optional fields emit suggested_action in JSON — they do not rewrite code:

      - name: "Legacy requests"
        prefix: "requests."
        provider: TECH_DEBT
        openrewrite_recipe: "org.openrewrite.python.migrate.ReplaceRequestsWithHttpx"
        replacement_fqn: "httpx"
        docs_url: "https://www.python-httpx.org/"

Standard definition block

definition:
  language:
    python:
      - name: "Pattern Name"
        prefix: ""  # Empty or specific prefix
        rule: "(?<resource_group>[a-z0-9_]+)_pattern\\.(?<operation>[a-z0-9_]+)"
        provider: AWS  # AWS, AZURE, GCP, etc.

      - name: "Extract from Argument"
        prefix: "function_name"
        rule: "function_name"
        provider: AWS
        extract_resource_from: "first_argument"  # Extract service from first arg

  providers:
    AWS:
      servicenameMapping:
        "wafv2": "waf-v2"  # Map custom names to standard service names
        "cognito_idp": "cognito-identity-provider"

Pattern Syntax

Grok Patterns

  • %{WORD:name} - Matches [a-zA-Z0-9]+ (no underscores)
  • %{GREEDYDATA} - Matches everything (greedy)
  • %{DATA:name} - Matches everything until next delimiter (greedy)
  • (?<name>[a-z0-9_]+) - Named capture group with underscores
  • \\. - Escaped dot (literal period)
  • [a-zA-Z0-9_]+ - Character class

Example: Prowler Client Wrappers

Prowler uses custom client wrappers like s3_client.buckets.values():

definition:
  language:
    python:
      - name: "Prowler AWS Client - .values()"
        prefix: ""
        rule: "(?<resource_group>[a-z0-9_]+)_client\\.(?<operation>[a-z0-9_]+)\\.values"
        provider: AWS

      - name: "Prowler AWS Client - .items()"
        prefix: ""
        rule: "(?<resource_group>[a-z0-9_]+)_client\\.(?<operation>[a-z0-9_]+)\\.items"
        provider: AWS

  providers:
    AWS:
      servicenameMapping:
        "cognito_idp": "cognito-identity-provider"
        "wafv2": "waf-v2"

Debugging

Enable debug logging to see which patterns are being tried:

cce -folder ./myproject -language AUTO \\
    -mapper-file custom.yaml -filter all \\
    -log-level debug -format text

Look for: - "We do not support this method name yet" - Prefix doesn't match - "could not map the method call" - Pattern doesn't match - "multiple language definitions matched" - Multiple patterns match (first one wins)

Security

  • HTTPS only: Remote URLs must use HTTPS (SSRF protection)
  • Size limit: Remote files limited to 10MB
  • No redirects: Direct downloads only
  • Validation: YAML structure validated before use

Best Practices

  1. Use empty prefix unless you have a very specific common prefix
  2. Use inline regex for identifiers with underscores or hyphens
  3. Test incrementally - start with one pattern, verify it works
  4. Order matters - more specific patterns first
  5. Service name mapping - map custom names to standard cloud service names