mirror of
https://github.com/microsoft/BCQuality.git
synced 2026-08-08 10:26:52 +01:00
Correct security and privacy guidance
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 9c2eebc4-dcd5-4b85-8113-90772d818900
This commit is contained in:
parent
7a678d1aff
commit
ec8f891954
34 changed files with 189 additions and 150 deletions
|
|
@ -1,26 +1,26 @@
|
|||
---
|
||||
bc-version: [all]
|
||||
domain: privacy
|
||||
keywords: [privacy-notice, consent, http-client, outgoing-request, external-service, getprivacynoticeapprovalstate]
|
||||
keywords: [privacy-notice, consent, http-client, outgoing-request, external-service, confirmprivacynoticeapproval]
|
||||
technologies: [al]
|
||||
countries: [w1]
|
||||
application-area: [all]
|
||||
---
|
||||
|
||||
# Outgoing requests to external services require a Privacy Notice consent check
|
||||
# Check the custom Privacy Notice before external data transfer
|
||||
|
||||
## Description
|
||||
|
||||
Business Central ships a built-in Privacy Notice framework that the admin uses to grant or withhold per-integration consent for sending data to external services. The relevant API surface is `Codeunit "Privacy Notice"` (consent checks via `GetPrivacyNoticeApprovalState()`), `Codeunit "Privacy Notice Registrations"` (well-known notice IDs for integrations such as Exchange, OneDrive, Teams), and the `Enum "Privacy Notice Approval State"` with values `Agreed`, `Disagreed`, and `Not Set`. The admin UI is the **Privacy Notices Status** page. The compliance concern in code review is therefore not that personal data is included in an outgoing HTTP body — that is normal business functionality — but that the code path issuing the request contains no `PrivacyNotice.GetPrivacyNoticeApprovalState(...)` check.
|
||||
Business Central's `Codeunit "Privacy Notice"` creates notices and records per-integration approval. A custom integration needs its own stable notice ID; it must not borrow the Exchange or another built-in service's consent. `ConfirmPrivacyNoticeApproval` shows the notice when needed and returns whether the request is approved. `GetPrivacyNoticeApprovalState` checks an existing notice without showing UI.
|
||||
|
||||
## Best Practice
|
||||
|
||||
Before issuing an outgoing HTTP request to an external service, verify `PrivacyNotice.GetPrivacyNoticeApprovalState(<integration id>) = "Privacy Notice Approval State"::Agreed`. The check does not have to live next to the `HttpClient.Post` call — it can sit anywhere upstream in the same code path (for example in the page's `OnOpenPage`, in a wizard step, or in a setup action) as long as no execution path reaches the request without passing through it.
|
||||
Register the custom notice with `CreatePrivacyNotice` during setup or through `OnRegisterPrivacyNotices`. Before sending data, call `ConfirmPrivacyNoticeApproval(<custom id>)` outside a write transaction, or check `GetPrivacyNoticeApprovalState(<custom id>)` when the flow must not show UI. No path should issue the request without approval.
|
||||
|
||||
See sample: `privacy-notice-consent-for-external-data-transfer.good.al`.
|
||||
|
||||
## Anti Pattern
|
||||
|
||||
A `procedure SendDataToExternalService(...)` that posts customer data to an external endpoint with no `PrivacyNotice.GetPrivacyNoticeApprovalState` anywhere upstream. The same anti-pattern applies in reverse: removing an existing privacy-notice check from code that still issues the external call.
|
||||
A custom integration that posts data without checking its own notice, or that gates the call with a built-in ID such as the Exchange privacy notice ID. Consent for one service does not authorize another.
|
||||
|
||||
See sample: `privacy-notice-consent-for-external-data-transfer.bad.al`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue