bcquality/microsoft/knowledge/security/use-secrettext-for-credentials.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.5 KiB
Markdown

---
bc-version: [26..28]
domain: security
keywords: [secrettext, credentials, debugger, type]
technologies: [al]
countries: [w1]
application-area: [all]
---
# Use SecretText for credentials
> **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
SecretText is a compile-time-checked AL type for credentials, API keys, tokens, and similar sensitive values. The compiler rejects literal assignments to SecretText and blocks implicit conversion back to Text or Code, which prevents many accidental disclosures via logs, errors, and the debugger (regular and snapshot). A SecretText value remains opaque throughout its lifetime.
## Best Practice
Type every credential-carrying variable, procedure parameter, and return as SecretText. Compose values with SecretStrSubstNo (see compose-secrets-with-secretstrsubstno). For HttpClient integration, see use-secrettext-with-httpclient. When a secret must be extracted from a Text source, contain that conversion in a NonDebuggable procedure (see use-nondebuggable-when-parsing-secrets).
See sample: `samples/security/use-secrettext-for-credentials/good.al`.
## Anti Pattern
Passing credentials around as Text or Code parameters. Every such variable is visible in the debugger and may be captured by error handlers, logs, and telemetry that treat Text as non-sensitive.
See sample: `samples/security/use-secrettext-for-credentials/bad.al`.