Skip to main content

Step 1: Encrypt Credit Card Data

The most critical step in PCI-DSS compliance is protecting the Primary Account Number (PAN). This step teaches you how to encrypt the credit card number while preserving analytics-safe data like the last four digits and the card brand.

The Goal

You will transform the payment object by:

  1. Encrypting the card_number into a new card_number_encrypted field.
  2. Extracting the card_last_four and card_brand for analytics.
  3. Deleting the original, plaintext card_number.

Input Snippet:

{
"payment": {
"card_number": "4532-1234-5678-9010",
"expiration": "12/27"
}
}

Desired Output Snippet:

{
"payment": {
"expiration": "12/27",
"card_number_encrypted": "AES256GCM:v1:...",
"card_last_four": "9010",
"card_brand": "visa"
}
}

Implementation

  1. Start with the Foundation: Copy encryption-foundation.yaml to a new file, encrypt-card.yaml.

    cp examples/data-security/encryption-foundation.yaml encrypt-card.yaml
  2. Add the Encryption Logic: Open encrypt-card.yaml and add the following mapping processor to the pipeline section. This single processor performs the entire transformation.

    Add this to the 'processors' array in encrypt-card.yaml
    - mapping: |
    # Clean the card number of any spaces or dashes
    let clean_card = this.payment.card_number.re_replace_all("[^0-9]", "")

    # Encrypt the full, clean card number
    root.payment.card_number_encrypted = clean_card.encrypt_aes("gcm", env("CARD_ENCRYPTION_KEY"))

    # Extract the last 4 digits for analytics and customer service
    root.payment.card_last_four = clean_card.slice(-4)

    # Detect the card brand from the first digit (BIN range)
    root.payment.card_brand = if clean_card.has_prefix("4") {
    "visa"
    } else if clean_card.re_match("^5[1-5].*") {
    "mastercard"
    } else if clean_card.re_match("^3[47].*") {
    "american_express"
    } else {
    "unknown"
    }

    # CRITICAL: Remove the original plaintext card number field
    root.payment = this.payment.without("card_number")

    Note: Remember to set the CARD_ENCRYPTION_KEY environment variable as described in the setup.mdx guide.

  3. Deploy and Test:

    # Send the sample payment data from the setup step
    curl -X POST http://localhost:8080/events/payment \
    -H "Content-Type: application/json" \
    -d @/tmp/encryption-test/sample-payment.json
  4. Verify: Check your logs. You will see that the card_number field is gone, replaced by card_number_encrypted, card_last_four, and card_brand.

You have now implemented the core of PCI-DSS compliant card data protection. The same pattern can be applied to other sensitive fields.