Spread the love

In this blog post, we will explore how to use isolated storage in Business Central to securely store secrets, ensuring they are only accessible through code within your extension. The primary purpose of using isolated storage is to safeguard sensitive information, such as passwords, from unauthorized access, especially by individuals with malicious intent. Isolated storage allows you to store values securely using a key-value pair structure, similar to a dictionary.

All source code can be found here: dfredborg/BusinessCentralIsolatedStorage: Small example of how to use Isolated Storage in Business Central (github.com)

Why Use Isolated Storage?

Isolated storage provides a secure way to manage sensitive data in Business Central, ensuring that it remains protected and is only accessible to authorized code within your extension. This mechanism prevents sensitive data from being exposed to unauthorized users or systems.

Example: Storing a Client Secret

In our example, we aim to store a client secret securely. To do this, we first create a setup table named SecretSetup with two fields: a Code field and a Guid field.

Here is the table definition:

table 50700 SecretSetup
{
    Caption = 'Secret Setup';
    DataClassification = SystemMetadata;

    fields
    {
        field(1; "Code"; Code[10])
        {
            Caption = 'Code';
        }
        field(2; Secret; Guid)
        {
            Caption = 'Secret';
        }
    }
    keys
    {
        key(PK; "Code")
        {
            Clustered = true;
        }
    }
}

How It Works

The Guid field in the SecretSetup table holds our client ID, which is used to access the isolated storage and retrieve the corresponding client secret. By using isolated storage, we ensure that the client secret remains secure and is only accessible through the appropriate code paths.

Updating the Client Secret via API

To facilitate seamless integration with third-party services, we expose a function as an API to allow these services to update the client secret directly. This capability is particularly useful if a system connected to Business Central generates a new client secret. Instead of manually updating the secret in Business Central, the third-party service can update it automatically via the API, eliminating the need to send the new key to a person for manual entry.

Implementing Actions to Write and Retrieve Values from Isolated Storage

To interact with isolated storage in Business Central, we use the system variable type IsolatedStorage, which provides Set and Get methods for managing our values. Below is a simple example demonstrating how to write to and retrieve values from isolated storage.

Codeunit for Managing Client Secrets

We define a codeunit named ClientSecret to encapsulate the logic for writing and retrieving client secrets using isolated storage.

codeunit 50700 ClientSecret
{
    [NonDebuggable]
    procedure WriteClientSecret(secret: Text[1024]; clientId: Guid)
    var
        SecretSetup: Record SecretSetup;
        SecretValue: SecretText;
    begin
        if not SecretSetup.Get() then begin
            SecretSetup.Secret := clientId;
            SecretSetup.Insert();
        end;

        SecretValue := secret;
        IsolatedStorage.Set(SecretSetup.Secret, secret);
    end;

    [NonDebuggable]
    procedure ReadClientSecret(): Text[1024]
    var
        SecretSetup: Record SecretSetup;
        SecretValue: SecretText;
        ClientSecret: Text[1024];
    begin
        SecretSetup.Get();
        IsolatedStorage.Get(SecretSetup.Secret, ClientSecret);
        exit(ClientSecret);
    end;
}

Explanation of the Code

  • WriteClientSecret Procedure: This procedure writes a client secret to isolated storage. It takes a secret of type Text[1024] and a clientId of type Guid as parameters. If the SecretSetup record doesn’t exist, it creates a new record with the clientId. Then, it stores the secret in isolated storage using the Set method.
  • ReadClientSecret Procedure: This procedure retrieves the client secret from isolated storage. It fetches the SecretSetup record and uses the Get method to read the stored secret, returning it as a Text[1024].
  • NonDebuggable Attribute: The [NonDebuggable] attribute is used to ensure that these procedures cannot be accessed using a debugger, enhancing security by preventing unauthorized access to the stored values.

This implementation demonstrates how straightforward it is to work with isolated storage in Business Central. By encapsulating the logic in a codeunit and marking functions as NonDebuggable, we maintain a secure environment for handling sensitive information like client secrets.

Exposing the Codeunit as a Web Service

To make the ClientSecret codeunit accessible externally, we can expose it as a web service in Business Central. By doing so, you can interact with it using HTTP requests. Below is an example of how to perform POST requests to write and read client secrets via the web service.

Writing to Isolated Storage

To write a client secret to isolated storage, you can use the following POST request:

URL:

https://api.businesscentral.dynamics.com/v2.0/{{TenantID}}/dev/ODataV4/ClientSecret_WriteClientSecret?company={{CompanyID}}
{
    "clientId": "820460af-2e9b-4d26-b1b9-1cce4769bde8",
    "secret": "test2"
}

This request writes the secret "test2" to isolated storage using the specified clientId.

Reading from Isolated Storage

To read the client secret from isolated storage, send the following POST request:

URL:

https://api.businesscentral.dynamics.com/v2.0/{{TenantID}}/dev/ODataV4/ClientSecret_ReadClientSecret?company={{CompanyID}}

Response:

{
    "@odata.context": "https://api.businesscentral.dynamics.com/v2.0/f96cb47d-63f6-4856-b062-89bc94bc58e2/dev/ODataV4/$metadata#Edm.String",
    "value": "test2"
}

This response returns the value "test2", which was previously stored in isolated storage.

Security Considerations

In a real-world scenario, you might want to limit access to reading from isolated storage through web services to enhance security. Consider separating the read and write functionalities into different codeunits or implementing access controls to manage permissions more effectively.

Conclusion

Using isolated storage in Business Central provides a secure and efficient method for managing sensitive information like client secrets. By implementing isolated storage alongside web services, you can automate and streamline the management of secrets while maintaining robust security measures. Always consider security best practices when exposing sensitive operations through web services to prevent unauthorized access.

By following these guidelines, you can ensure that your Business Central application securely handles sensitive data and remains adaptable to the needs of your organization.

Leave a Reply