Skip to main content

Keychain

import decentriq_platform as dq
from decentriq_platform.analytics import *
from decentriq_platform.lookalike_media import LookalikeMediaDcrBuilder

USER_EMAIL = "@@ YOUR EMAIL HERE @@"
OTHER_EMAIL = "@@ OTHER EMAIL HERE @@"
API_TOKEN = "@@ YOUR TOKEN HERE @@"
KEYCHAIN_PASSWORD = "@@ YOUR KEYCHAIN PASSWORD HERE @@"

client = dq.create_client(USER_EMAIL, API_TOKEN)

KEYCHAIN_PASSWORD = "@@ YOUR KEYCHAIN PASSWORD HERE @@"

enclave_specs = dq.enclave_specifications.latest()

auth, _ = client.create_auth_using_decentriq_pki(enclave_specs)
session = client.create_session(auth, enclave_specs)

client = dq.create_client(USER_EMAIL, API_TOKEN)
builder = AnalyticsDcrBuilder(client=client)

dcr_definition = builder.\
with_name("My DCR").\
with_owner(USER_EMAIL).\
with_description("My test DCR").\
add_node_definitions([
RawDataNodeDefinition(name="my-raw-data-node", is_required=True),
TableDataNodeDefinition(
name="my-table-data-node",
columns=[
Column(
name="name",
format_type=FormatType.STRING,
is_nullable=False,
),
Column(
name="salary",
format_type=FormatType.INTEGER,
is_nullable=False,
),
],
is_required=True,
),
]).\
add_participant(
USER_EMAIL,
data_owner_of=[
"my-raw-data-node",
"my-table-data-node",
]
).\
build()
dcr = client.publish_analytics_dcr(dcr_definition)
DCR_ID = dcr.id

Please follow the Get started with Python SDK tutorial to learn how to connect with the Decentriq platform, create DCRs, provision datasets and run computations.

Let's start by importing the necessary packages.

import decentriq_platform as dq
from decentriq_platform import Keychain, KeychainEntry

Activate the Keychain

The keychain can be unlocked using the get_or_create_unlocked_keychain method. If you logged into the Decentriq UI before, you will already have a keychain and this method will try to decrypt it using the provided password. If no keychain exists yet, a new one will be created for you. Please note that in the first case, this call might throw an exception if the provided password does not match the one you initially set when creating the keychain in the UI.

from decentriq_platform import Keychain

my_keychain = Keychain.get_or_create_unlocked_keychain(client, bytes(KEYCHAIN_PASSWORD, 'utf8'))

Note that the password must be a binary string. If your password exists in the form of a normal Python string, simply call its .encode() method.

Encrypt and provision a new dataset to an existing DCR

Assume you have:

  • a published Data Clean Room with:
  • a data node (leaf) where you have Data Owner permissions to provision a dataset to it
DCR_ID = "1b56c9252eb6f4cf69ac0daf3d2525bcea4706d3f4ce748aebb41ac14a4857d9"
LEAF_NODE = "my-table-data-node"
DCR_ID = dcr.id

First, you generate a key to encrypt a new dataset, upload it to the Decentriq platform and provision it to the data node inside an existing DCR.

# Generate an encryption key
encryption_key = dq.Key()

# Read dataset locally, encrypt, upload and provision it to DCR
with open("/path/to/dataset.csv", "rb") as dataset:
DATASET_ID = client.upload_dataset(
dataset,
encryption_key,
"dataset_name",
store_in_keychain=my_keychain
)
note

client.upload_dataset() also has a convenience parameter store_in_keychain=my_keychain that already stores the encryption key in the Keychain. Please check the Save DCR results to datasets guide for more details.

Store the encryption key in the Keychain

As the dataset has been successfully uploaded and has a known ID, you can store the generated encryption key and reference the dataset ID so that it is convenient to retrieve it later.

This can be achieved by initializing the Keychain with your password and calling the insert() method that expects an entry of type dataset_key.

Note that the password must be a binary string.

# Generate an encryption key
encryption_key = dq.Key()

# Read dataset locally, encrypt, upload and provision it to DCR
with open("/path/to/dataset.csv", "rb") as dataset:
DATASET_ID = client.upload_dataset(
dataset,
encryption_key,
"dataset_name",
)
my_keychain = Keychain.get_or_create_unlocked_keychain(client, bytes(KEYCHAIN_PASSWORD, 'utf8'))
my_keychain.insert(KeychainEntry("dataset_key", DATASET_ID, encryption_key.material))

Provision a dataset to other DCRs

At a later moment, you can retrieve from the Keychain the encryption key of the same dataset and provision it to other DCRs.

Assume you have:

  • another published Data Clean Room with:
  • a data node (leaf) where you have Data Owner permissions to provision a dataset to it
DCR_ID2 = "cd9948b4f93e0dd1fbf053ad541294fcd9ddf8767f40eeddc95bf0f90b1af90a"
LEAF_NODE_ID2 = "my-table-data-node"
DCR_ID2 = dcr.id

Retrieve the encryption key from the Keychain referencing the previously dataset ID by calling the get() method.

retrieved_key = my_keychain.get("dataset_key", DATASET_ID)

Provision the dataset to another DCR using the publish_dataset() method. This can be done multiple times just by specifying retrieving other DCR ID and data node.

# Get the DCR via the ID seen in the Decentriq UI
dcr = client.retrieve_analytics_dcr(DCR_ID2)

# Then, retrieve the encryption key stored in the Keychain.
# DATASET_ID is an id copied from the Decentriq UI "Datasets" page or
# from the list of datasets retrieved via the SDK.
retrieved_key = my_keychain.get("dataset_key", DATASET_ID)

# Reprovision the existing dataset to a DCR
dcr.get_node("my-raw-data-node").publish_dataset(
DATASET_ID,
dq.Key(retrieved_key.value)
)

Deprovision a dataset

To remove a dataset from a DCR, only the DCR ID and data node name need to be specified.

This will not delete the dataset nor remove the encryption key from the Keychain.

dcr.get_node("my-raw-data-node").remove_published_dataset()

Delete an encryption key

When deleting a dataset from the Decentriq platform, using the client.delete_dataset(DATASET_ID), the encryption key will remain in the Keychain and must be removed separately.

To delete an encryption key from the Keychain, call the remove() method specifying the referenced dataset ID. This will not delete the dataset, nor deprovision it from any DCR. To do so, check the instructions above.

my_keychain.remove("dataset_key", DATASET_ID)