# Custom Enrichment Examples

The following are examples of using custom enrichments for detections.

### Example for translating 1Password UUIDs into human readable names

Please see our guide about using custom enrichments to translate 1Password's Universally Unique Identifier (UUID) values into human readable names: [Using Custom Enrichments: 1Password UUIDs](/enrichment/custom/examples/1password-uuids.md).

### Example using CIDR matching through Panther Console

**Example scenario:** Let's say you want to write detections that consider the traffic logs from company IP space (e.g. VPNs and hosted systems) differently from others logs originating from public IP space.

You have a list of your company's allowed CIDR blocks listed in a `.csv` file (e.g. `4.5.0.0/16`):

<table><thead><tr><th width="333">cidr</th><th>description</th></tr></thead><tbody><tr><td>10.2.3.0/24</td><td>San Francisco Office</td></tr><tr><td>20.3.4.0/24</td><td>DC Office</td></tr><tr><td>30.4.5.0/24</td><td>Boston Office</td></tr></tbody></table>

#### Set up a custom enrichment with the CIDR list

1. Follow the [instructions to set up a custom enrichment via file upload](/enrichment/custom.md#option-1-import-lookup-table-data-via-file-upload) and configure its basic information.
   * The name of the Enrichment in this example is `Company CIDR Blocks`.
2. On the Associated Log Types page, choose the Log Type and Selectors.
   * For this example, we used `AWS.VPCFlow` logs and associated the source IP (`srcAddr`) and destination (`dstAddr`) keys.\
     ![The image shows the "Associated Log Types" page while setting up Lookup Tables. There is a dropdown menu labeled Log Type, and AWS.VPCFlow is selected. In the field labeled "Selectors," it is filled in with "srcAddr" and "dstAddr."](/files/D1hf6WiW24ZEWnhdfuTY)
3. Associate a schema for your Enrichment: Select an existing one from your list or [create a new schema](/data-onboarding/custom-log-types.md#how-to-define-a-custom-schema).
   * **Note:** The primary key column which will hold the CIDR blocks needs to have a `CIDR` validation applied in the schema to indicate that this enrichment will do CIDR block matching on IP addresses. [See our log schema reference](https://docs.runpanther.io/data-onboarding/custom-log-types/reference#validation-by-string-type).

     ```yaml
     # Will allow valid ip6 CIDR ranges
     # e.g. 2001:0db8:85a3:0000:0000:0000:0000:0000/64
     - name: address
       type: string
       validate:
         cidr: "ipv6" 
         
     # Will allow valid ipv4 IP addresses e.g. 100.100.100.100/00
     - name: address
       type: string
       validate:
         cidr: "ipv4"  
     ```
4. Drag & drop a file or click **Select File** to choose the file of your CIDR block list to import. The file must be in `.csv` or `.json` format. The maximum file size supported is 5MB.
5. After you successfully import a file, click **View in Data Explorer** to query that table data or click **Finish Setup** to go back to a list of your custom Enrichments.

![](/files/TRWRYHr0JNeIZL2U1y6a)

#### Write a detection

You might like to receive an alert if any VPC traffic comes from a source IP address that is not part of your company's allowed CIDR blocks. Here is an example of a rule that will send an alert in this case:

{% tabs %}
{% tab title="Python" %}

```python
def rule(event):
  if event.get('flowDirection') == 'egress': # we care about inbound
        return False
  if event.get('action') == 'REJECT': # we don't care about these either
        return False
  if deep_get(event, 'p_enrichment','Company CIDR Blocks','srcAddr'): # these are ok
        return False 
  return True # alert if NOT from an approved network range
```

{% endtab %}

{% tab title="Simple Detection" %}

```yaml
Detection:
  - KeyPath: flowDirection
    Condition: DoesNotEqual
    Value: egress
  - KeyPath: action
    Condition: DoesNotEqual
    Value: REJECT
  - KeyPath: p_enrichment.'Company CIDR Blocks'.srcAddr
    Condition: DoesNotExist
```

{% endtab %}
{% endtabs %}

**Note**: The CIDR [validation](#set-up-a-lookup-table-with-the-cidr-list) applied in the Enrichment schema in this example will enable the system to match IP addresses in VPC flow log to CIDR blocks in the lookup.

### Example using IP for Geolocation with Panther Analysis Tool

Let's say you want to know which geographical location your employees are connecting from (e.g., using info like geonames.org). In this scenario, your company has a static file that maps CIDRs to a GeoId, like the one we have in this [example\_cidr\_lookup\_content.csv](https://github.com/panther-labs/panther-analysis/blob/master/templates/example_cidr_lookup_content.csv).

{% code overflow="wrap" %}

```
> curl https://raw.githubusercontent.com/panther-labs/panther-analysis/master/templates/example_cidr_lookup_content.csv

network,geoname_id
1.0.0.0/24,2077422
1.0.1.0/24,1814991
1.0.2.0/23,1814991
1.0.4.0/22,2077456
1.0.8.0/21,1814991
1.0.16.0/20,1814991
```

{% endcode %}

You could use a YAML schema similar to the following:

```yaml
AnalysisType: lookup_table # always lookup_table
LookupName: simple_cidr_lookup # str
Enabled: true # bool
Description: Enrichment description # str (Optional)
FileName: ./relative/path/to/content.csv # str (Optional)
Reference: An optional reference link # str (Optional)
Schema: Custom.Simple.Cidr # str (should already exist)
LogTypeMap:
  PrimaryKey: network # str
  AssociatedLogTypes: # [...]
    - LogType: Aws.CloudTrail # str
      Selectors: # [str]
        - 'p_any_ip_addresses'
    - LogType: Aws.VPCFlow
      Selectors:
        - 'p_any_ip_addresses'
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.panther.com/enrichment/custom/examples.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
