Business Central AL IsolatedStorage: Secure Secrets & API Tokens
Business Central integrations frequently need credentials such as API tokens, client secrets, refresh tokens or provider-specific keys. Putting these values directly into AL source code or ordinary setup tables can create unnecessary security exposure.
1. What is IsolatedStorage?
Business Central AL provides IsolatedStorage for storing data that should be isolated from ordinary application data. It is commonly useful for sensitive integration values that an extension needs to retrieve later without putting the value directly into a normal application table.
Microsoft documents Isolated Storage as a way for extensions to store data isolated from the rest of the application. The API supports storing, retrieving, checking and deleting values by key, with different data scopes.
Microsoft Learn — IsolatedStorage data type
2. Why not store API tokens directly in AL code?
// ❌ Avoid this
Token := 'sk-live-xxxxxxxxxxxxxxxx';
// ❌ Avoid storing secrets in source-controlled setup code
ClientSecret := 'my-production-secret';
Source code can be downloaded, reviewed, copied into repositories, included in packages or exposed to developers who should not have access to production credentials.
Instead, keep the secret outside source code and retrieve it through a controlled server-side mechanism.
3. IsolatedStorage key/value model
A simple pattern is to use a stable key and store the secret as a text value.
procedure SaveApiToken(Token: Text)
begin
IsolatedStorage.Set(
'Dynexal.ApiToken',
Token,
DataScope::Company);
end;
procedure LoadApiToken(): Text
var
Token: Text;
begin
if IsolatedStorage.Get(
'Dynexal.ApiToken',
DataScope::Company,
Token)
then
exit(Token);
Error('API token has not been configured.');
end;
The exact scope should be selected according to the ownership and isolation requirements of the secret.
4. Understand DataScope before choosing a key
Isolated Storage supports scopes that determine how stored values are isolated. The scope is part of the storage design, not an incidental implementation detail.
For example, a credential used by one company may need company-level isolation, while an extension-level value may have a different ownership model.
5. Company-specific integration credentials
Consider a Business Central environment containing multiple companies. If each company connects to a different Shopify store or external API account, the credential should not accidentally be shared between companies.
Company A
└── API Token A
Company B
└── API Token B
A company-scoped storage design can help maintain that separation when the integration's business requirement is company-specific.
6. Separate secret storage from setup configuration
A practical integration setup often contains both normal configuration and protected credentials.
Integration Setup Table
├── Enabled
├── Endpoint URL
├── Company Identifier
├── Timeout
└── Environment
IsolatedStorage
├── Access Token
├── Client Secret
└── Refresh Token
This separation keeps the setup page useful without turning the ordinary setup table into a repository for raw secrets.
7. Build a dedicated credential service
Do not scatter IsolatedStorage calls across every API codeunit. A dedicated credential service creates one place for key names, scope decisions, validation and error handling.
codeunit 50110 "Integration Credential Service"
{
procedure SetAccessToken(Token: Text)
begin
if Token = '' then
Error('Access token cannot be empty.');
IsolatedStorage.Set(
'Dynexal.AccessToken',
Token,
DataScope::Company);
end;
procedure GetAccessToken(): Text
var
Token: Text;
begin
if not IsolatedStorage.Get(
'Dynexal.AccessToken',
DataScope::Company,
Token)
then
Error('Access token is not configured.');
exit(Token);
end;
}
8. Never log the secret
One of the easiest mistakes is protecting a token in storage and then exposing it through logs, error messages or telemetry.
// ❌ Do not do this
Session.LogMessage(
'TOKEN_DEBUG',
Token,
Verbosity::Normal,
DataClassification::SystemMetadata);
// ❌ Do not include secrets in errors
Error('Authentication failed. Token was: %1', Token);
Log identifiers, status codes and safe diagnostic information instead of credentials.
9. Do not confuse encryption with authorization
Protecting a stored value does not mean every piece of application code should be allowed to retrieve it. Secret storage and application authorization are separate concerns.
- Storage protection: protects the stored value.
- Permissions: control who can execute application operations.
- Business authorization: controls which actions a user is allowed to perform.
- External API authorization: determines whether the provider accepts the credential.
A secure architecture considers all four layers.
10. Secret rotation
Production credentials should be replaceable without redeploying the extension.
Admin
│
▼
Set New Credential
│
▼
Protected Storage
│
▼
Integration Service
│
▼
External API
A setup action such as “Set Access Token” can validate that a non-empty value was supplied and then replace the stored credential. A separate “Clear Credential” action can remove it when appropriate.
11. Credential validation without exposing the value
A connection test should report whether authentication succeeds, not display the credential itself.
procedure TestConnection(): Boolean
var
Token: Text;
Response: HttpResponseMessage;
begin
Token := CredentialService.GetAccessToken();
// Build authenticated request.
// Never include Token in the response or log.
exit(Response.IsSuccessStatusCode());
end;
When troubleshooting authentication, record the endpoint, HTTP status and safe provider error details where permitted, but redact credentials.
12. IsolatedStorage is not a complete secrets-management strategy
Protected storage inside Business Central can solve an application-level secret-storage problem, but it should not be treated as a universal replacement for enterprise identity and secret-management architecture.
For cloud integrations, consider whether the external service supports modern authentication such as OAuth 2.0 and service-to-service authentication. For high-security environments, evaluate the organization's approved secret-management and identity controls.
Never place a production secret in GitHub, an AL source file, a public JavaScript file or a browser-side configuration object.
13. OAuth tokens and refresh tokens
OAuth-based integrations often have short-lived access tokens and longer-lived refresh credentials. The application should treat both as sensitive.
Access Token
│
├── expires
▼
Refresh Token
│
▼
Token Endpoint
│
▼
New Access Token
│
▼
Business Central API Call
If a refresh token is persisted, use protected storage and ensure that the refresh process does not write the credential into logs or user-visible error messages.
14. Multi-company and multi-environment design
Think about environment boundaries before choosing key names. Development, test and production should not accidentally reuse credentials.
Development
└── Dynexal.ApiToken → DEV credential
Test
└── Dynexal.ApiToken → TEST credential
Production
└── Dynexal.ApiToken → PROD credential
The deployment architecture and storage scope determine how these values are isolated. Operational procedures should also make it obvious which environment a credential belongs to.
15. Security checklist for AL integrations
- Is the credential absent from source code?
- Is it absent from client-side JavaScript?
- Is the secret stored using an appropriate protected mechanism?
- Is the selected DataScope correct for the business ownership?
- Are normal settings separated from credentials?
- Are tokens excluded from telemetry and error messages?
- Can administrators rotate credentials without a code deployment?
- Are integration permissions limited to the required operations?
- Does the integration use an appropriate authentication protocol?
- Are development and production credentials separated?
16. AI + Business Central example
For an AI-enabled Business Central extension, an AI provider API key should remain server-side. The page should call an application service, and the service should retrieve the credential internally.
Business Central Page
│
▼
AI Application Service
│
├── Get credential
│ ↓
│ IsolatedStorage
│
▼
Secure HTTP request
│
▼
AI Provider
The browser should never receive the provider secret. This is particularly important when an AL extension is integrated with a website or external frontend.
17. Interview-ready answer
18. Common mistakes
- Hardcoding production credentials in AL.
- Saving secrets in ordinary setup tables without considering exposure.
- Returning tokens through an API or page response.
- Logging Authorization headers for debugging.
- Using the wrong DataScope.
- Sharing one credential across unrelated companies.
- Putting secrets in website JavaScript or environment-independent static files.
- Failing to plan credential rotation.
- Testing production integrations with development credentials.
Conclusion
Secure credential handling is an important part of professional Business Central integration development. IsolatedStorage can provide an appropriate protected storage mechanism for extension data, but secure architecture also requires correct scope, permissions, authentication, logging and operational controls.
The most important rule is simple: credentials belong on the server side, outside source code and outside the browser.