bcquality/microsoft/knowledge/security/use-isolated-storage-for-module-and-company-secrets.md
Jesper Schulz-Wedde 0980397d27 Seed security knowledge corpus (16 articles + 30 AL samples)
Converts Jesper's existing AL security-review prompt into BCQuality seed
knowledge articles so the al-security-review leaf has a real corpus to
match against. Mirrors the performance seed phase.

Articles under microsoft/knowledge/security/ (16):
- Permission model: follow-least-privilege-in-permission-sets,
  use-indirect-permissions-for-elevated-access,
  use-inherent-permissions-to-grant-minimal-access
- Secrets: never-hardcode-secrets-in-al,
  use-isolated-storage-for-module-and-company-secrets,
  prefer-azure-key-vault-for-production-secrets,
  use-secrettext-for-credentials, use-secrettext-with-httpclient,
  compose-secrets-with-secretstrsubstno,
  use-nondebuggable-when-parsing-secrets
- External calls: require-https-for-external-calls,
  set-timeouts-for-external-calls, do-not-put-credentials-in-urls
- Error handling: avoid-sensitive-data-in-error-messages,
  do-not-swallow-security-errors-silently
- Extensibility: do-not-expose-sensitive-data-in-event-publishers

Paired AL samples under samples/security/<slug>/{bad,good}.al, object
IDs 50200-50231 (no overlap with performance 50100-50140).

Rubber-duck findings addressed:
- HttpClient secret-URI: SetSecretRequestUri is on HttpRequestMessage
  (not HttpClient). Rewrote use-secrettext-with-httpclient and its
  good sample to use HttpRequestMessage + HttpClient.Send.
- InherentPermissions only grants access to same-extension objects;
  the sample now defines its own table 50230 "Sec Sample Lookup" and
  grants 'r' on that, not on Database::Customer.
- Reworked compose-secrets-with-secretstrsubstno bad.al away from
  Format(SecretText) (unreliable) to a plain Text+StrSubstNo anti-
  pattern.
- Moved normative guidance out of Description in three articles
  (compose-secrets-..., prefer-azure-key-vault-..., use-inherent-...)
  so it sits in Best Practice / Anti Pattern per READ contract.
- Added a companion helper codeunit (50231) to the indirect-permissions
  good sample so it actually demonstrates the controlled write path.
- Rebuilt the event-publisher good/bad pair on the same ExportCustomer
  scenario so the contrast is the shape of the event signature, not a
  different event.

Also: broaden samples/README.md object-ID range note to 50100-50299.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 13:39:50 +02:00

29 lines
1.6 KiB
Markdown

---
bc-version: [26..28]
domain: security
keywords: [isolatedstorage, encryption, datascope, secrets]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Use IsolatedStorage for module and company secrets
> **Seed article.** Converted from an existing security-review prompt to bootstrap the BCQuality security corpus. Domain stewards should expand, restructure, and refine as needed.
## Description
IsolatedStorage is a per-extension, per-tenant key-value store. DataScope::Module isolates values to the extension across the tenant; DataScope::Company scopes them to a single company within the tenant. The SetEncrypted method stores the value encrypted at rest; Set stores it in plaintext. SetEncrypted accepts inputs up to 215 characters (special characters may consume more space).
## Best Practice
Use IsolatedStorage.SetEncrypted to write secrets, IsolatedStorage.Contains to probe, and IsolatedStorage.Get into a SecretText destination to read. Choose DataScope::Company for per-company credentials (for example, a tenant-per-company service account) and DataScope::Module for extension-wide configuration.
See sample: `samples/security/use-isolated-storage-for-module-and-company-secrets/good.al`.
## Anti Pattern
Storing secrets in a Setup table column as plain Text, or using IsolatedStorage.Set (unencrypted) for values that authenticate the extension to an external service. Both shapes leave the secret readable by anyone with read rights on the underlying storage.
See sample: `samples/security/use-isolated-storage-for-module-and-company-secrets/bad.al`.