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 typeText[1024]
and aclientId
of typeGuid
as parameters. If theSecretSetup
record doesn’t exist, it creates a new record with theclientId
. Then, it stores the secret in isolated storage using theSet
method. - ReadClientSecret Procedure: This procedure retrieves the client secret from isolated storage. It fetches the
SecretSetup
record and uses theGet
method to read the stored secret, returning it as aText[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.