# Selecting Data Elements to Redact or Reveal

## What are operations?

Operations are different ways to navigate structured data and transform a piece of it by either redacting or replacing the value with a surrogate value.

## Operations Examples

**Most Common:**

* JSONPath (JSON)
* XPath (XML)
* Form
* HTML / CSS
* Regex

## JSONPath

```json
{
    "customers": {
        "first_customer": {
            "first_name": "John",
            "last_name": "Doe",
            "credit_card": "4111111111111111",
            "card_exp": "9/23",
            "card_cvv": "123"
            },
        "second_customer": {
            "first_name": "Jane",
            "last_name": "Smith",
            "credit_card": "4222222222222222",
            "card_exp": "9/23",
            "card_cvv": "123"
        }
    }
}
```

To redact the PCI data in this, we would simply need to create two JSONPath Operations.

Nesting with JSONPath is fairly straightforward. Every level down you go in standard JSON is just `$.toplevelkey.midlevelkey.finallevelkey` like if there are lists in between; you select the item using the index (or you can use wildcards).

To redact the `credit_card` number. All we have to do is select the key. With JSONPath selected as the operation, enter this snippet on the line next to it:

`$.customers..credit_card`

To redact `credit_card` number only for the `first_customer,` we would need to select the next snippet:

`$.[0].credit_card`

If you want to experiment with JSONPath, check out this [tool.](https://jsonpath.curiousconcept.com/)

In advanced options, you can select FPE\_6\_T\_4 to keep the credit card format for mod 10/ Luhn validation.

To redact the CVV, we need to store that in memory, not persistently. So, we add an "Add Entry".

Do exactly the same thing, but change JSONPath to:

`$.[0].card_cvv`

In the advanced options, we need to select Storage *Volatile*

## Xpath

```xml
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schp.org/e/" xmlns:xsd="http:rg/2chema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <AddCardResponse xmlns="">
            <ResponseCode>00</ResponseCode>
            <ResponseDesc>New Card Purchase Order Completed Successfully (932501******1238)</ResponseDesc>
            <NewCardNumber>
                    <Number>4111111111111111</Number>
                <ExpiryDate>092019</ExpiryDate>
            </NewCardNumber>
            <Balance>0.00</Balance>
            <TransId>F378</TransId>
            <CustomerId>3250033</CustomerId>
            <Fee>0.00</Fee>
            <ReferenceID>32513325</ReferenceID>
            <NameOnCard>Andrew</NameOnCard>
        </AddCardResponse>
    </soapenv:Body>
</soapenv:Envelope>
```

An example of how to correctly specify the path to get ***Number*** data:

`//Number`

or

`/Envelope/Body/AddCardResponse/NewCardNumber/Number`

Invalid path:

`/soapenv:Envelope/soapenv:Body/AddCardResponse/NewCardNumber/Number`

> You do not need to specify *Namespace* in your path

To check XPath navigation, use this [tool](https://www.freeformatter.com/xpath-tester.html#ad-output).

## Form

The last type of transformer in this guide is the Form operation. We just use the form field input names as the selector.

HTML form example:

```html
<div class="creditCardForm">
    <div class="heading">
        <h1>Confirm Purchase</h1>
    </div>
    <div class="payment">
        <form action="https://<VAULT_ID>.<ENVIRONMENT>.verygoodproxy.com" method="post">
            <div class="form-group owner">
                <label for="owner">Owner</label>
                <input type="text" class="form-control" name="owner" id="owner">
            </div>
            <div class="form-group CVV">
                <label for="cvv">CVV</label>
                <input type="text" class="form-control" name="cvv" id="cvv">
            </div>
            <div class="form-group" id="card-number-field">
                <label for="cardNumber">Card Number</label>
                <input type="text" class="form-control" name="cardNumber" id="cardNumber">
            </div>
            <div class="form-group" name="expiration-date" id="expiration-date">
                <label>Expiration Date</label>
                <select>
                    <option value="01">January</option>
                    <option value="02">February </option>
                    <option value="03">March</option>
                    <option value="04">April</option>
                    <option value="05">May</option>
                    <option value="06">June</option>
                    <option value="07">July</option>
                    <option value="08">August</option>
                    <option value="09">September</option>
                    <option value="10">October</option>
                    <option value="11">November</option>
                    <option value="12">December</option>
                </select>
                <select>
                    <option value="16"> 2016</option>
                    <option value="17"> 2017</option>
                    <option value="18"> 2018</option>
                    <option value="19"> 2019</option>
                    <option value="20"> 2020</option>
                    <option value="21"> 2021</option>
                </select>
            </div>
            <div class="form-group" id="pay-now">
                <button type="submit" class="btn btn-default" id="confirm-purchase">Confirm</button>
            </div>
        </form>
    </div>
</div>
```

For forms, the "name" of the input field is all that's required to replace with a surrogate value. If the Form is URL encoded, make sure you enter the filters as they look decoded.

Select the "Form" transformer and just enter:

`cardNumber`

and under a new entry, volatile storage for CVV

`cvv`

## HTML

You can select this transformer option to select data in HTML forms by using [CSS selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors).

If you have used a JS library like Sizzle or jQuery, you will already be familiar with these.

The simplest selectors allow you to match on

* class names through a `.` e.g. `.myClassName`
* an identifier via a `#` e.g. `#myId`
* an attribute using a series of brackets, with an attribute name and optionally a value inside, e.g. `[attr=value]`
* an element type by simply typing the name of the element, e.g. `input`

You can nest these selectors in order to achieve precise selection of data on the page, e.g. `#myId .myClassName` will match the input element in the following section

```html
<html>
  <body>
    <div id="myId">
      <span class="myClassName">
        Text that will be operated on
      </span>
    </div>
  </body>
</html>
```

## Regex

If the above examples do not cover the type of selection you need, then you can always fall back to a regex. VGS provides a series of named prefixes to assist with complex matching. These are

* `prefix` - Anything to match before
* `token` - The data to match
* `suffix` - Anything matched after

If these are omitted, then anything matched by the regex in its entirety will be operated on.

Here are two examples

* `(\d{16})` - would operate on any 16-digit sequence
* `(?<prefix>foo)(?<token>\d{16})(?<suffix>\d{3})` - would operate on a 16 digit sequence prefixed with `foo` and suffixed with three digits e.g. `foo1234567890123456123` would become `footok_sandbox_asd123123` where the prefix is `foo`, the suffix is `123` and the 16 digit value `1234567890123456` is replaced with the value `tok_sandbox_asd123`

These examples cover the most common operation use cases.

### Replace the value with any text and aliased value.

Replacement parameter: `any text <alias placeholder>`

Route config:&#x20;

<figure><img src="/files/Ay5Aesbtf86SneNiHtEr" alt=""><figcaption></figcaption></figure>

```yaml
transformer: REGEX
transformer_config: - '\b[0-9 ]{13,20}\b'
transformer_config_map:
    patterns: - '\b[0-9 ]{13,20}\b'
    replacement: 'any text:%s'
```

Input:

```json
{
    "first_name": "JOHN",
    "card_number": "4111 1111 1111 1111",
    "ssn": "444411111",
    "dob": "1931-01-01"
}
```

Output:

```json
{
    "first_name": "JOHN",
    "card_number": "any text:tok_sfvDwkNetJGnNWaPqPeYhY",
    "ssn": "444411111",
    "dob": "1931-01-01"
}
```

### Replace the value with Aliased value and preserved group

Replacement parameter: `<regexp group placeholder> any text <alias placeholder>`

Route config:&#x20;

```yaml
transformer: REGEX
transformer_config: - '4313-35(?<card1>00)-(?<card2>0000)-(?<lastFour>\d{4})'
transformer_config_map:
    patterns: - '4313-35(?<card1>00)-(?<card2>0000)-(?<lastFour>\d{4})'
    replacement: '%s:${lastFour}'
```

Input:

```json
{
    "first_name": "JOHN",
    "card_number": "4313-3500-0000-1234",
    "ssn" : "444411111",
    "dob" : "1931-01-01"
}
```

Output:

```json
{
    "first_name": "JOHN",
    "card_number": "tok_mTkSAHoAvvNiFUCEiYSWtj:1234",
    "ssn": "444411111",
    "dob": "1931-01-01"
}
```

If you have any questions or trouble, please contact us at <support@vgs.io>


---

# 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.verygoodsecurity.com/vault/http-proxy/operations.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.
