Working with Policies
Create a Policy
Section titled “Create a Policy”Before you can send telemetry about how PII is used in your software systems, you must define the reasons that you use the data. Each reason should then suggest how long you must retain data items for when they are used for this reason, based on your business requirements. For example, if you sell goods on your website and use a payment method that supports chargebacks for up to 3 months, you should use a sales policy which is at least 3 months, although you may want to allow a small window of extra time to be able to recognise customers who checked out without creating an account. If you support a product returns policy, you should create a second policy for product returns which matches your business requirements for the duration of product returns. If you keep customer details for at least 30 days after a customer support request, you might have another policy for customer support, so that after each interaction, the customer data is kept for an additional 30 days and after that time, any cases are considered resolved and the customer data should expire.
We must create an instance of the PolicyManagementApi client to work with policies
then call the putPolicy method which has the following signature:
putPolicy(policySlug, policyData), where policyData must contain all of aging
strategy, aging offset amount and aging offset unit when creating a policy.
import { AgingOffsetUnit, AgingStrategy, PolicyManagementApi, ServerConfiguration, createConfiguration } from "@privatedataservices/metronome-client";import { explainError } from "./errors";
const clientConfig = createConfiguration( { baseServer: new ServerConfiguration("https://the-flower-boutique.dev.eu-west-1.privatedataservices.com", {}), authMethods: { ApiKeyAuth: process.env.METRONOME_API_KEY }});const pmApiClient = new PolicyManagementApi(clientConfig);
try { const response = await pmApiClient.putPolicy("user-account-access", {agingStrategy: AgingStrategy.since_last_read_or_write, agingOffsetAmount: 2, agingOffsetUnit: AgingOffsetUnit.month}); console.log("Policy %s created successfully. Fields updated were: %s", response.policyId, response.fieldsModified.join(", "));} catch (err) { explainError(err);}require 'metronome'require_relative 'errors'
# Configure client with API keyclient_config = Metronome::Configuration.newclient_config.scheme = 'https'client_config.host = 'code-examples.dev.eu-west-1.metronome.privatedataservices.com'client_config.api_key['X-API-Key'] = ENV['METRONOME_API_KEY']
pm_api_client = Metronome::PolicyManagementApi.new(Metronome::ApiClient.new(client_config))
begin request = Metronome::CreateOrModifyPolicyRequest.new( aging_strategy: Metronome::AgingStrategy::SINCE_LAST_READ_OR_WRITE, aging_offset_amount: 2, aging_offset_unit: Metronome::AgingOffsetUnit::MONTH ) response = api_client.put_policy("user-account-access", create_or_modify_policy_request: request) puts "Policy %s created successfully. Fields updated were: %s" % [response.policy_id, response.fields_modified.join(", ")]rescue => err explain_error(err)endPolicies have 2 aging strategies:
- since-last-read-or-write
- since-first-read-or-write
Most policies will likely use the first strategy so that each interaction can
extend the useful life of the PII being handled. The second aging strategy is
most likely to be used for data on-boarding, so that data that was stored before
Metronome was implemented can begin to be tracked. An on-boarding policy that
uses since-first-read-or-write will only work once, but if the data has already
been introduced to Metronome by another policy, the on-boarding policy will be
skipped because the data is already known.
The aging offset amount must be a positive integer greater than 1.
Metronome supports 3 aging offset units:
- day
- month
- year
In the example above, a policy named user-account-access is defined which causes
PII handled with this policy to be retained for 2 months from the time of the
observation.
Modify a Policy
Section titled “Modify a Policy”The example below modifies the user-account-access policy to retain data for
1 year after being handled with this policy.
We again create an instance of the PolicyManagementApi client to work with policies
then call the putPolicy but for modifications, policyData must contain at least
1 of aging strategy, aging offset amount or aging offset unit. You can change several
attributes such as aging offset amount and aging offset unit at the same time.
import { AgingOffsetUnit, PolicyManagementApi, ServerConfiguration, createConfiguration } from "@privatedataservices/metronome-client";import { explainError } from "./errors";
const clientConfig = createConfiguration( { baseServer: new ServerConfiguration("https://the-flower-boutique.dev.eu-west-1.privatedataservices.com", {}), authMethods: { ApiKeyAuth: process.env.METRONOME_API_KEY }});const pmApiClient = new PolicyManagementApi(clientConfig);
try { const response = await pmApiClient.putPolicy("user-account-access", {agingOffsetAmount: 1, agingOffsetUnit: AgingOffsetUnit.year}); console.log("Policy %s modified successfully. Fields updated were: %s", response.policyId, response.fieldsModified.join(", "));} catch (err) { explainError(err);}require 'metronome'require_relative 'errors'
# Configure client with API keyclient_config = Metronome::Configuration.newclient_config.scheme = 'https'client_config.host = 'code-examples.dev.eu-west-1.metronome.privatedataservices.com'client_config.api_key['X-API-Key'] = ENV['METRONOME_API_KEY']
pm_api_client = Metronome::PolicyManagementApi.new(Metronome::ApiClient.new(client_config))
begin request = Metronome::CreateOrModifyPolicyRequest.new( aging_offset_amount: 1, aging_offset_unit: Metronome::AgingOffsetUnit::YEAR ) response = api_client.put_policy("user-account-access", create_or_modify_policy_request: request) puts "Policy %s modified successfully. Fields updated were: %s" % [response.policy_id, response.fields_modified.join(", ")]rescue => err explain_error(err)endReading Policies
Section titled “Reading Policies”To read 1 specific policy, you call the PolicyManagementApi client’s getPolicy
method with the only parameter being the slug of the policy you wish to read.
import { PolicyManagementApi, ServerConfiguration, createConfiguration } from "@privatedataservices/metronome-client";import { explainError } from "./errors";
const clientConfig = createConfiguration( { baseServer: new ServerConfiguration("https://the-flower-boutique.dev.eu-west-1.privatedataservices.com", {}), authMethods: { ApiKeyAuth: process.env.METRONOME_API_KEY }});const pmApiClient = new PolicyManagementApi(clientConfig);
try { const policy = await pmApiClient.getPolicy("user-account-access"); console.log("Policy ID is %s created at %s with aging strategy %s which ages by %s %s", policy.policyId, policy.createDate, policy.agingStrategy, policy.agingOffsetAmount, policy.agingOffsetUnit);} catch (err) { explainError(err);}require 'metronome'require_relative 'errors'
# Configure client with API keyclient_config = Metronome::Configuration.newclient_config.scheme = 'https'client_config.host = 'code-examples.dev.eu-west-1.metronome.privatedataservices.com'client_config.api_key['X-API-Key'] = ENV['METRONOME_API_KEY']
pm_api_client = Metronome::PolicyManagementApi.new(Metronome::ApiClient.new(client_config))
begin policy = api_client.get_policy("user-account-access") puts "Policy ID is %s created at %s with aging strategy %s which ages by %s %s" % [ policy.policy_id, policy.create_date, policy.aging_strategy, policy.aging_offset_amount, policy.aging_offset_unit ]rescue => err explain_error(err)endListing Policies
Section titled “Listing Policies”The policy listing interface is pagenated. In the event that there are more than 1000 entries, the
first call will receive 1000 items and a continuation token for your next call. The next call should
specify the continuation token as the first parameter to the getManyPolicies method. The second
parameter is a policy slug prefix, should you only wish to search for policies starting with a specific prefix.
The third possible parameter specifies whether you wish to see the details of each policy (includeData)
or whether you wish only to receive a list of the policies themselves.
The method signature for this method is getManyPolicies(nextContinuationToken, prefix, includeData).
All parameters are optional.
import { PolicyData, PolicyListResponse, PolicyDataListResponse, PolicyManagementApi, ServerConfiguration, createConfiguration } from "@privatedataservices/metronome-client";import { explainError } from "./errors";
const clientConfig = createConfiguration( { baseServer: new ServerConfiguration("https://the-flower-boutique.dev.eu-west-1.privatedataservices.com", {}), authMethods: { ApiKeyAuth: process.env.METRONOME_API_KEY }});const pmApiClient = new PolicyManagementApi(clientConfig);
const getManyPoliciesExample = async () => { try { const response = await pmApiClient.getManyPolicies() as PolicyListResponse; console.log("All known policies are: %s", response.result.join(", ")); } catch (err) { explainError(err); }}
const getManyPolicyDefinitionsNoFilterExample = async () => { try { const response = await pmApiClient.getManyPolicies(undefined, undefined, true) as PolicyDataListResponse; console.log("There are %d policy definitions:", response.result.length); response.result.forEach((policy: PolicyData, index: number) => { console.log("Policy %d has ID %s created at %s with aging strategy %s which ages by %s %s", index+1, policy.policyId, policy.createDate, policy.agingStrategy, policy.agingOffsetAmount, policy.agingOffsetUnit); }); } catch (err) { explainError(err); }}
const getManyPolicyDefinitionsWithFilterExample = async () => { try { const response = await pmApiClient.getManyPolicies("user-", undefined, true) as PolicyDataListResponse; console.log("There are %d policy definitions that match the filter prefix 'user-'.", response.result.length); response.result.forEach((policy: PolicyData, index: number) => { console.log("Policy %d has ID %s created at %s with aging strategy %s which ages by %s %s", index+1, policy.policyId, policy.createDate, policy.agingStrategy, policy.agingOffsetAmount, policy.agingOffsetUnit); }); } catch (err) { explainError(err); }}require 'metronome'require_relative 'errors'
# Configure client with API keyclient_config = Metronome::Configuration.newclient_config.scheme = 'https'client_config.host = 'code-examples.dev.eu-west-1.metronome.privatedataservices.com'client_config.api_key['X-API-Key'] = ENV['METRONOME_API_KEY']
pm_api_client = Metronome::PolicyManagementApi.new(Metronome::ApiClient.new(client_config))
def get_many_policies_example(api_client) begin response = api_client.get_many_policies() puts "All known policies are: %s" % response.result.join(", ") rescue => err explain_error(err) endend
def get_many_policy_definitions_no_filter_example(api_client) begin response = api_client.get_many_policies(include_data: true) puts "There are %d policy definitions:" % response.result.length response.result.each_with_index do |policy, index| puts "Policy %d has ID %s created at %s with aging strategy %s which ages by %s %s" % [ index+1, policy.policy_id, policy.create_date, policy.aging_strategy, policy.aging_offset_amount, policy.aging_offset_unit ] end rescue => err explain_error(err) endend
def get_many_policy_definitions_with_filter_example(api_client) begin response = api_client.get_many_policies(prefix: "user-", include_data: true) puts "There are %d policy definitions that match the filter 'user-'." % response.result.length response.result.each_with_index do |policy, index| puts "Policy %d has ID %s created at %s with aging strategy %s which ages by %s %s" % [ index+1, policy.policy_id, policy.create_date, policy.aging_strategy, policy.aging_offset_amount, policy.aging_offset_unit ] end rescue => err explain_error(err) endend