Edit

Share via


Advanced user defined functions in Azure confidential ledger (preview)

Advanced user defined functions (UDFs) allow custom code to execute in the same Trusted Execution Environment (TEE) as the ledger. This feature extends the benefits of confidentiality and integrity guarantee to the custom code. Also, it supports custom Role Based Access Control (RBAC) for authorization.

Important

User defined functions are currently in PREVIEW under API version 2024-08-22-preview. You can request access for this preview via this sign-up form. See the Supplemental Terms of Use for Microsoft Azure Previews for legal terms that apply to Azure features that are in beta, preview, or otherwise not yet released into general availability.

Tip

For simpler scenarios, such as lightweight custom logic or direct integration with the ledger API, see simple user defined functions in Azure confidential ledger.

Use cases

Here are some scenarios where advanced user defined functions can be beneficial:

  • Data analysis and aggregation: Sensitive information can be processed in the TEE and aggregated information can be shared with the stakeholders.
  • Protecting confidential information: Confidential information like personal data, credit score, and health information can be shared with other confidential workloads after attestation.

Prerequisites

This tutorial assumes that you created a ledger instance. You can create one using the Azure portal, Azure CLI, or Azure PowerShell.

Developing applications

Ledger applications are developed using TypeScript and rolled-up into a JavaScript bundle. To learn more about the development process, refer to the Confidential Consortium Framework (CCF) documentation.

Important

Only Administrators can deploy applications and manage custom RBAC in the ledger. The rest of the section assumes that an Administrator executes the commands.

We use the banking application available at the azureconfidentialledger-app-samples repo (https://github.com/microsoft/azureconfidentialledger-app-samples) to demonstrate the feature.

Note

The banking application exposes APIs for commonly used banking scenarios like opening accounts, depositing and transferring funds using custom roles and actions.

Sign in to Azure

Note

Azure confidential ledger supports Microsoft Entra ID out-of-the-box. If your application integrates with other identity providers, contact customer support to configure it in the ledger.

Obtain a Microsoft Entra ID token.

az login --use-device-code
az account get-access-token --resource https://confidential-ledger.azure.com

Copy the raw token value from the output.

Download the ledger identity

A ledger is uniquely identified by a certificate called the service certificate. It's used to establish a secure connection to the ledger. Download it from a well-known endpoint and save it to servicer_cert.pem.

Note

contoso is the name of the ledger. Replace it with the appropriate ledger name.

curl https://identity.confidential-ledger.core.azure.com/ledgerIdentity/contoso --silent | jq ' .ledgerTlsCertificate' | xargs echo -e > service_cert.pem

Deploy the application

Deploy the JavaScript application bundle by invoking the /app/userDefinedEndpoints endpoint.

apiVersion="2024-08-22-preview"
content_type_application_json="Content-Type: application/json"
bundle="/path/to/bundle.json"
authorization="Authorization: Bearer raw_token_value"
server_identity="--cacert service_cert.pem"

# Deploy the application
#
curl $server_identity -X PUT "https://contoso.confidential-ledger.azure.com/app/userDefinedEndpoints?api-version=$apiVersion" -H "$content_type_application_json" -H "$authorization" -d @$bundle

# View the application
#
curl $server_identity "https://contoso.confidential-ledger.azure.com/app/userDefinedEndpoints?api-version=$apiVersion" -H "$authorization"

Note

Advanced user defined functions and simple user defined functions are mutually exclusive features. You can't create or run simple UDFs if advanced UDFs are defined, and vice versa. To switch between the two, follow the instructions in the UDF overview page.

Create roles and users

The banking application uses two personas, namely, a manager and a teller. We create roles and users to represent them.

Note

Each user is represented by a unique certificate.

Note

Application users can be assigned the built-in roles, namely, Administrator, Contributor and Reader. Custom roles are case-sensitive and built-in roles are case-insensitive. A user can be assigned multiple roles.

apiVersion="2024-08-22-preview"
content_type_application_json="Content-Type: application/json"
content_type_merge_patch_json="Content-Type: application/merge-patch+json"
authorization="Authorization: Bearer raw_token_value"
curve="secp384r1"
server_identity="--cacert service_cert.pem"

# These actions must match (case-sensitive) the values defined in the application.
#
role_actions='{"roles":[{"role_name":"manager","role_actions":["/banking/accounts/post","/banking/accounts/put","/banking/accounts/get","/banking/accounts/patch"]},{"role_name":"teller","role_actions":["/banking/accounts/put","/banking/accounts/get","/banking/accounts/patch"]}]}'

# Create the roles.
#
curl $server_identity -X PUT "https://contoso.confidential-ledger.azure.com/app/roles?api-version=$apiVersion" -H "$content_type_application_json" -H "$authorization" -d $role_actions

# View the roles
#
curl $server_identity "https://contoso.confidential-ledger.azure.com/app/roles?api-version=$apiVersion" -H "$authorization"

# Create a certificate for the manager user.
#
openssl ecparam -out "manager_privk.pem" -name "$curve" -genkey
openssl req -new -key "manager_privk.pem" -x509 -nodes -days 365 -out "manager_cert.pem" -sha384 -subj=/CN="manager"
manager_cert_fingerprint=$(openssl x509 -in "manager_cert.pem" -noout -fingerprint -sha256 | cut -d "=" -f 2)
manager_user="{\"user_id\":\"$manager_cert_fingerprint\",\"assignedRoles\":[\"manager\"]}"

# Create a certificate for the teller user.
#
openssl ecparam -out "teller_privk.pem" -name "$curve" -genkey
openssl req -new -key "teller_privk.pem" -x509 -nodes -days 365 -out "teller_cert.pem" -sha384 -subj=/CN="teller"
teller_cert_fingerprint=$(openssl x509 -in "teller_cert.pem" -noout -fingerprint -sha256 | cut -d "=" -f 2)
teller_user="{\"user_id\":\"$teller_cert_fingerprint\",\"assignedRoles\":[\"teller\"]}"

# Create the manager user.
#
curl $server_identity -X PATCH "https://contoso.confidential-ledger.azure.com/app/ledgerUsers/$manager_cert_fingerprint?api-version=$apiVersion" -H "$content_type_merge_patch_json" -H "$authorization" -d $manager_user

# Create the teller user.
#
curl $server_identity -X PATCH "https://contoso.confidential-ledger.azure.com/app/ledgerUsers/$teller_cert_fingerprint?api-version=$apiVersion" -H "$content_type_merge_patch_json" -H "$authorization" -d $teller_user

# View the users
#
curl $server_identity "https://contoso.confidential-ledger.azure.com/app/ledgerUsers?api-version=$apiVersion" -H "$authorization"

Update the runtime configuration (optional)

The JavaScript runtime configuration can be updated by calling the /app/userDefinedEndpoints/runTimeOptions endpoint. To demonstrate it, let us set the maximum execution time to 2,000 ms.

apiVersion="2024-08-22-preview"
content_type_merge_patch_json="Content-Type: application/merge-patch+json"
authorization="Authorization: Bearer raw_token_value"
runtime_options="{\"max_heap_bytes\":1024,\"max_stack_bytes\":1024,\"max_execution_time_ms\":2000,\"log_exception_details\":false,\"return_exception_details\":false,\"max_cached_interpreters\":1024}"
server_identity="--cacert service_cert.pem"

# Patch the runtime options
#
curl $server_identity -X PATCH "https://contoso.confidential-ledger.azure.com/app/userDefinedEndpoints/runTimeOptions?api-version=$apiVersion" -H "$content_type_merge_patch_json" -H "$authorization" -d $runtime_options

# View the runtime options
#
curl $server_identity "https://contoso.confidential-ledger.azure.com/app/userDefinedEndpoints/runTimeOptions?api-version=$apiVersion" -H "$authorization"

Now you're ready to call the application endpoints and submit transactions.

Clean up resources

Other quickstarts and tutorials in this collection build upon this quickstart. If you plan to continue on to work with subsequent quickstarts and tutorials, you may wish to leave these resources in place.

When no longer needed, you can use the Azure CLI az group delete command to remove the resource group and all related resources:

az group delete --name "myResourceGroup"

Next steps

In this tutorial, you deployed a custom JavaScript application into a confidential ledger instance. To learn more about Azure confidential ledger and how to integrate it with your applications, continue on to these articles: