This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Create a policy to protect Credit Card Number (CCN)

Workflow example to protect CCN.

Goal

Create a policy that protects Credit Card Number (CCN) using CCN data element, with:

  • At least one role.
  • At least one member source assigned to that role.
  • Deployed to at least one datastore.

This example provides a walkthrough of the complete workflow to create a policy to protect a Credit Card Number (CCN) with tokenization using Protegrity CLI and REST APIs. The example includes defining a CCN Data Element and access controls to deploy a policy that protectors can enforce at runtime. The CCNs have a specific format and must comply with existing regulations. Hence, this example uses the Credit Card token type, with a common usability pattern of keeping the last four digits visible while tokenizing the rest.

Before using the CLI or the REST APIs, determine the properties required for the CCNs. For example:

  • How many digits should be in the clear.
  • Whether invalid values should be rejected or tokenized, for example, via Luhn handling.
  • What security operations should be allowed. For example, protect, unprotect, or reprotect.

These properties determine how the data element and the policy rules that are configured. They determine what applications and users will experience when data is protected or unprotected.

A key design choice specific to tokenization is selecting the tokenizer. You need to choose a tokenizer because it defines the tokenization engine and lookup-table strategy. Protegrity uses the tokenizer to deterministically transform a CCN into a same-length token. The tokenizer controls how the CCN digits are mapped into tokens so the protector can reliably produce and resolve tokens under policy. Protegrity offers multiple Static Lookup Table (SLT) tokenizer variants, such as, SLT_1_3, SLT_2_3, SLT_1_6, and SLT_2_6, which differ mainly in lookup-table design and operational footprint. For most CCN use cases, this example uses SLT_2_3 because it strikes a practical balance of memory usage and performance while working well for standard PAN lengths. This avoids the much larger memory footprint of the _6 options unless specifically required.

Assumptions

To execute any CLI or API command in this example, the following assumptions have been made:

  • You are operating on a new AI Team Edition setup.
    • Set up the AI Team Edition by installing the Protegrity Provisioned Cluster. For more information about installing the PPC, refer to the section Installing PPC.
  • You are connected to the Policy Manager container.
    • Connect to the Policy Manager container by deploying the Protegrity Policy Manager. For more information about deploying the Protegrity Policy Manager, refer to the section Installing Policy Workbench.

CLI Examples

To execute any CLI command in this example, the following additional assumption has been made:

API Examples

To execute any API command in this example, the following additional assumption has been made:

  • You have access to the Protegrity Policy Management REST APIs.

1 - Initialize Policy Management

Initializing the policy management.

This step initializes the Policy Management system. This step needs to be executed only once.

CLI Code

pim invoke init

CLI Actual Output

✅ PIM successfully initialized (bootstrapped).

API Endpoint

POST /pim/init

Get Gateway host address

export GW_HOST="$(kubectl get gateway pty-main -n api-gateway -o jsonpath='{.status.addresses[0].value}')"

Generate JWT token

TOKEN=$(curl -k -s  https://$GW_HOST/api/v1/auth/login/token \
## -X Post \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'loginname=workbench' \
-d 'password=Admin123!' \
-D - -o /dev/null 2>&1 | grep -i 'pty_access_jwt_token:' | sed 's/pty_access_jwt_token: //' | tr -d '\r') && echo "${TOKEN:0:10}"

API Code

curl -k -H "Authorization: Bearer ${TOKEN}" -X POST "https://{$GW_HOST}/pty/v2/pim/init" -H "accept: application/json"

API Actual Output:

It does not return any output as response.

2 - Prepare Data Element

Create a data element.

What you are doing

Creating the data element that defines:

  • What is protected: CCN.
  • How it is protected: Tokenization settings.

Why it matters

Data elements are the protection building blocks that will be granted the permissions by the policy.

Tips

  • To keep nothing in clear: set --from-left 0 --from-right 0.
  • To avoid Luhn enforcement: omit --invalid-luhn-digit.

CLI Code

pim create dataelements token credit-card --name "de_ccn_token" --description "Tokenize credit card numbers, keeping last 4 chars in clear" --tokenizer "SLT_1_6" --from-left 0 --from-right 4 --invalid-luhn-digit

CLI Actual Output

UID NAME DESCRIPTION                                                TOKENIZER  FROMLEFT  FROMRIGHT  VALUEIDENTIFICATION
15  de_ccn_token  Tokenize credit card numbers, keeping last 4 chars in clear  SLT_1_6    0         4          {'invalidCardType': False, 'invalidLuhnDigit': True, 'alphabeticIndicator': False, 'alphabeticIndicatorPosition': 1}

API Endpoint

POST /pim/dataelements

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/dataelements" \
-d '{
"name": "de_ccn_token",
"description": "Tokenize credit card numbers, keeping last 4 chars in clear",
"creditCardToken": {
"tokenizer": "SLT_1_6",
"fromLeft": 0,
"fromRight": 4,
"valueIdentification": {
"invalidCardType": false,
"invalidLuhnDigit": true,
"alphabeticIndicator": false,
"alphabeticIndicatorPosition": 1
}
}
}'

API Actual Output

{"uid":"1","name":"de_ccn_token","description":"Tokenize credit card numbers, keeping last 4 chars in clear","creditCardToken":{"tokenizer":"SLT_1_6","fromLeft":0,"fromRight":4,"valueIdentification":{"invalidCardType":false,"invalidLuhnDigit":true,"alphabeticIndicator":false,"alphabeticIndicatorPosition":1}}}

2.1 - Create Mask

Create mask for the CCN.

What you are doing

Creating the mask that is applied to the unprotection permission of a data element to customize how data is displayed. The mask is to be used later on de_ccn_token.

Why it matters

Creating a mask defines what characters are displayed in the clear when the data is unprotected. The mask is optionally applied to an unprotection to display only a certain value to a consumer of the data.

CLI Code

pim create masks --name "clear_mask" --from-left 0 --from-right 4 --character "*"

CLI Actual Output

## Name        Description  Fromleft  Fromright  Masked  Character  Uid
clear_mask               0         4          False   *          1

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/masks" \
-d '{
"name": "clear_mask",
"masked": true,
"fromLeft": 0,
"fromRight": 4,
"character": "*"
}'

API Endpoint

POST /pim/masks

API Actual Output

{"uid":"1","name":"clear_mask","description":"","fromLeft":0,"fromRight":4,"masked":true,"character":"*"}

3 - Create Member Source

Create member source for the CCN.

What you are doing

You are creating a Member Source, which is a source that informs Protegrity where user identities are stored. For example, Active Directory, LDAP, Azure AD or a text file. This configuration stores the connection and the lookup context that Protegrity needs to discover users and groups that are then mapped to Roles.

Why it matters

Policies do not grant access to individual users directly. Access is granted through roles, and roles are populated from external identity systems via member sources. Without a source, you cannot reliably attach real enterprise groups or users to roles, synchronize memberships, or enforce policy access the same way your organization manages identity.

CLI Code

pim create sources file --name test-file --user-file exampleusers.txt --group-file examplegroups.txt

CLI Actual Output

NAME       DESCRIPTION  TYPE             USERFILE          GROUPFILE          TIMEOUT  UID
test-file               SourceType.FILE  exampleusers.txt  examplegroups.txt  120      1

API Endpoint

POST /pim/sources

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/sources" \
-d '{
"name": "test-file",
"type": "FILE",
"connection": {
"userFile": "exampleusers.txt",
"groupFile": "examplegroups.txt"
}
}'

API Actual Output

{"name":"test-file","description":"","type":"FILE","connection":{"userFile":"exampleusers.txt","groupFile":"examplegroups.txt"},"uid":"1"}

3.1 - Test New Member Source

Test whether the member source has been successfully created.

CLI Code

pim invoke sources test 1

CLI Actual Output

+----------------+--------+---------+
|      type      | passed | message |
+----------------+--------+---------+
|   connection   |  True  |         |
| authentication |  True  |         |
|     groups     |  True  |         |
|     users      |  True  |         |
+----------------+--------+---------+ 

API Endpoint

POST /pim/sources/{SOURCE_UID}/test

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/sources/1/test"

API Actual Output

{"connection":{"passed":true,"message":""},"authentication":{"passed":true,"message":""},"groups":{"passed":true,"message":""},"users":{"passed":true,"message":""}}

4 - Create Role

Create a role.

What you are doing

Creating the role that represents who can perform operations against the data element.

Why it matters

Permissions are granted to roles and roles map to users or groups, ideally from member sources.

Tips

  • If you keep the --allow-all option in the command, then set ALLOWALL to True.
  • Consider which user needs what level of access and create a role for each set of users.

CLI Code

pim create roles role --name "role_protect_ccn" --description "This role have access to protect CCN data" --mode "MANUAL"

CLI Actual Output

NAME              DESCRIPTION                                MODE             ALLOWALL  UID
role_protect_ccn  This role have access to protect CCN data  RoleMode.MANUAL  False     1

API Endpoint

POST /pim/roles

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/roles" \
-d '{
"name": "role_protect_ccn",
"description": "This role have access to protect CCN data",
"mode": "MANUAL",
"allowAll": false
}'

API Actual Output

{"name":"role_protect_ccn","description":"This role have access to protect CCN data","mode":"MANUAL","uid":"1","allowAll":false}

5 - Assign Member Source to Role

Assign member source to the role.

What you are doing

You are attaching a specific user or group from a member source to a role. This creates the who belongs in this role binding. If you run synchronization, it retrieves the current membership from the source into the role.

Why it matters

This is the step that turns a role from a named container into an identity-backed access control object. If you do not assign a source user or group to the role and synchronize it, then no real identities are associated with that role. This means that your policy rules may exist, but nobody in your organization will actually have the access that those rules intend to grant.

CLI Code

pim create roles members 1 --member "exampleuser1,1,USER"

CLI Actual Output

## Name          Source  Type             Uid
exampleuser1  1       MemberType.USER  1  

API Endpoint

POST /pim/roles/{SOURCE_UID}/test

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/roles/1/members" \
-d '[
{
"name": "exampleuser1",
"source": "1",
"type": "USER"
}
]'

API Actual Output

[{"type":"USER","name":"exampleuser1","syncid":"exampleuser1","uid":"1","source":"1"}]

5.1 - Synchronize Member Source

Synchronize the member source.

Connect and synchronize the users with your member source.

CLI Code

pim invoke roles sync 1

CLI Actual Output

Successfully synchronized members for role with UID '1'.  

API Endpoint

POST /pim/roles/{SOURCE_UID}/sync

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/roles/1/sync"

API Actual Output

The API does not return any output as response.

6 - Create Policy Shell

Create a policy shell.

What you are doing

Creating the policy that will hold the access rules. For example, Data Element, Role, and Rules.

Why it matters

The policy is the object that ties together the pieces and becomes deployable.

Tips

Multiple Roles, multiple data elements, and their corresponding rules can be added to a single policy. Consider structuring your policy around specific areas of focus, as in this example, the treatment of a Credit Card Number across the entirety of your enterprise.

CLI Code

pim create policies policy --name "ccn-policy" --description "Protect CCN with tokenization"

CLI Actual Output

NAME        DESCRIPTION                    ACCESS                                                      UID
ccn-policy  Protect CCN with tokenization  {'protect': False, 'reProtect': False, 'unProtect': False}  1  

API Endpoint

POST /pim/policies

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/policies" \
-d '{
"name": "ccn-policy",
"description": "Protect CCN with tokenization",
"template": {
"access": {
"protect": false,
"reProtect": false,
"unProtect": false
}
}
}'

API Actual Output

{"name":"ccn-policy","description":"Protect CCN with tokenization","uid":"1","template":{"access":{"protect":false,"reProtect":false,"unProtect":false}}}

7 - Define Rule with Data Element and Role

Define that includes a data element and role.

What you are doing

Creating the policy rule that binds:

  • A role: Who.
  • A data element: What.
  • Permitted operations: Protect, Reprotect, or Unprotect.

Why it matters

This binding is what makes the policy enforceable. Without rules, the policy exists but grants no access.

Tips

This rule grants the specified role permission to protect the CCN data element, while disallowing reprotect and unprotect.

CLI Code

pim create policies rules 1 --rule "1,1,1,NULL_VALUE,true,false,true"

CLI Actual Output

## Role  Dataelement  Mask  Noaccessoperation  Access
1     1            1     NULL_VALUE         {'protect': True, 'reProtect': False, 'unProtect': True}  

API Endpoint

POST /pim/policies/{POLICY_UID}/rules

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/policies/1/rules" \
-d '{
"role": "1",
"dataElement": "1",
"mask": "1",
"noAccessOperation": "NULL_VALUE",
"permission": {
"access": {
"protect": true,
"reProtect": false,
"unProtect": true
}
}
}'

API Actual Output

{"role":"1","mask":"1","dataElement":"1","permission":{"access":{"protect":true,"reProtect":false,"unProtect":true}}}

8 - Create Datastore

Create a datastore.

What you are doing

Creating the datastore target where a policy will be deployed.

Why it matters

A policy is not active for protectors until it is deployed to a datastore.

CLI Code

pim create datastores datastore --name "ds_protect_ccn" --description "Datastore to demonstrate CCN protection" --default

CLI Actual Output

## Name            Description                              Default  Uid
ds_protect_ccn  Datastore to demonstrate CCN protection  True     1  

API Endpoint

POST /pim/datastores

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/datastores" \
-d '{
"name": "ds_protect_ccn",
"description": "Datastore to demonstrate CCN protection",
"default": true
}'

API Actual Output

{"description":"Datastore to demonstrate CCN protection","name":"ds_protect_ccn","default":true,"uid":"1"}

9 - Deploy Policy to a Datastore

Deploy a policy to a datastore.

What you are doing

Deploying the policy to the datastore so protectors that target that datastore can load the policy.

Why it matters

Until the policy is deployed, the policy is not available to runtime protectors.

Tips

  • You may want to deploy the multiple policies to a single datastores. If so, include them by repeating the –-policies parameter.
  • You can also add a single policy to multiple datastores by creating a loop.

CLI Code

pim invoke datastores deploy 1 --policies 1

CLI Actual Output

Successfully deployed to datastore '1':
Policies: 1  

API Endpoint

POST /pim/datastores/{DATASTORE_UID}/deploy

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-X POST "https://${GW_HOST}/pty/v2/pim/datastores/1/deploy" \
-d '{
"policies": ["1"],
"applications": []
}'

API Actual Output

API does not return any output as response

10 - Confirm Deployment

Confirm the policy deployment.

What you are doing

Confirming which policies are deployed to which datastores.

Why it matters

Verifying deployment confirms the policy is active, correctly mapped, and enforceable.

CLI Code

pim get deploy

CLI Actual output

## Uid  Policies  Applications
1    ['1']     []  

API Endpoint

POST /pim/deploy

API Code

curl -k \
-H "Authorization: Bearer ${TOKEN}" \
-H "accept: application/json" \
-X GET "https://${GW_HOST}/pty/v2/pim/deploy"

API Actual Output

{"dataStores":[{"uid":"1","policies":["1"],"applications":[]}]}