feat: Allow toolmakers to explain why they need CSP exceptions with selective optional domain consent#431
Conversation
Co-authored-by: Power-Maverick <36135520+Power-Maverick@users.noreply.github.com>
|
@copilot show required and optional in separate section and user should have the ability to allow all required but selet which optional to allow by selecting them. |
… checkboxes Co-authored-by: Power-Maverick <36135520+Power-Maverick@users.noreply.github.com>
Done in dc44571. The modal now has two distinct sections:
Only the checked optional domains are stored and applied to the tool's CSP. Required domains are always applied when consent is granted. |
|
@copilot Store the required domain list as part of the consent as well. In future we would need to track at given point in time which domains were given consent and do we need to trigger getting re-consent because the domain list has changed |
Co-authored-by: Power-Maverick <36135520+Power-Maverick@users.noreply.github.com>
Done in c304e8d. Required domains are now stored at consent time in a new Changes:
This means when re-consent detection is implemented, it can compare the stored |
|
@copilot few more changes
Instead of this "cspConsents": {
"12345678-27a1-4acb-b8f4-6b62ef0021e0": true,
"12345678-c6cb-4c3c-80b2-ea46490c2b79": true
},
"cspRequiredConsents": {
"12345678-27a1-4acb-b8f4-6b62ef0021e0": [
"https://raw.githubusercontent.com"
],
"12345678-c6cb-4c3c-80b2-ea46490c2b79": [
"fonts.googleapis.com",
"api.example.com"
]
},
"cspOptionalConsents": {
"12345678-27a1-4acb-b8f4-6b62ef0021e0": [],
"12345678-c6cb-4c3c-80b2-ea46490c2b79": [
"cdn.example.com"
]
},Do this "cspConsents": {
"12345678-27a1-4acb-b8f4-6b62ef0021e0": {
"allowed": true,
"required": [
"https://raw.githubusercontent.com"
],
"optional": []
},
"12345678-c6cb-4c3c-80b2-ea46490c2b79": {
"allowed": true,
"required": [
"fonts.googleapis.com",
"api.example.com"
],
"optional": [
"cdn.example.com"
]
},
} |
…red domains Co-authored-by: Power-Maverick <36135520+Power-Maverick@users.noreply.github.com>
Done in 8e1f1a4. 1. Required checkboxes: Required domains now render as pre-checked, disabled checkboxes — same layout as optional but with 2. Unified consent storage — three separate keys collapsed into one: "cspConsents": {
"12345678-27a1-4acb-b8f4-6b62ef0021e0": {
"allowed": true,
"required": ["https://raw.githubusercontent.com"],
"optional": []
},
"12345678-c6cb-4c3c-80b2-ea46490c2b79": {
"allowed": true,
"required": ["fonts.googleapis.com", "api.example.com"],
"optional": ["cdn.example.com"]
}
}
|
Bundle Size Report 📦
Bundle Analysis ReportsThe detailed bundle analysis reports are available in the workflow artifacts:
Download the artifacts from the workflow run to view interactive visualizations. Bundle size tracking is now active! This helps prevent bundle bloat. |
There was a problem hiding this comment.
Pull request overview
Adds richer CSP exception metadata for tool manifests (reason + optionality) and updates the CSP consent flow so users can selectively approve optional domains while required domains are always enforced once consent is granted.
Changes:
- Introduces
CspExceptionEntry/CspExceptionSourceand anormalizeCspExceptionSource()helper to support both legacy string sources and detailed entries. - Updates the CSP consent modal UI + controller to display required vs optional exceptions separately and return the user-approved optional domain list.
- Reworks persisted CSP consent storage to a per-tool
CspConsentRecord(allowed + required/optional domain snapshots) and applies only approved optional domains when building tool CSP.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/common/types/common.ts | Adds CspExceptionEntry, CspExceptionSource, and normalizeCspExceptionSource(); updates CSP exception typings. |
| src/common/types/settings.ts | Introduces CspConsentRecord and updates UserSettings.cspConsents to store richer consent records. |
| src/common/types/api.ts | Updates Toolbox API typings for grantCspConsent and getCspConsents. |
| src/main/managers/settingsManager.ts | Stores/reads unified CSP consent records and exposes required/optional domain accessors. |
| src/main/managers/browserviewProtocolManager.ts | Applies optional CSP domains only if explicitly approved by the user. |
| src/main/preload.ts | Updates the exposed toolboxAPI.grantCspConsent signature to pass required + approved optional domains. |
| src/main/index.ts | Updates IPC handler for granting CSP consent to accept required/optional domain lists. |
| src/renderer/modules/cspExceptionModal.ts | Changes modal return type to string[] | null and forwards approved optional domains from modal to caller. |
| src/renderer/modals/cspException/view.ts | Renders required/optional sections with checkboxes and inline-markdown reasons (escaped). |
| src/renderer/modals/cspException/controller.ts | Collects checked optional domains and sends them back on accept. |
| src/renderer/modules/toolManagement.ts | Computes required domains from manifest and persists consent with required + approved optional domains. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Bundle Size Report 📦
Bundle Analysis ReportsThe detailed bundle analysis reports are available in the workflow artifacts:
Download the artifacts from the workflow run to view interactive visualizations. Bundle size tracking is now active! This helps prevent bundle bloat. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Bundle Size Report 📦
Bundle Analysis ReportsThe detailed bundle analysis reports are available in the workflow artifacts:
Download the artifacts from the workflow run to view interactive visualizations. Bundle size tracking is now active! This helps prevent bundle bloat. |
|
Need following test:
|
Bundle Size Report 📦
Bundle Analysis ReportsThe detailed bundle analysis reports are available in the workflow artifacts:
Download the artifacts from the workflow run to view interactive visualizations. Bundle size tracking is now active! This helps prevent bundle bloat. |

Tool developers can now provide a markdown-formatted explanation (
exceptionReason) and anoptionalflag for each CSP exception domain. The consent modal shows required and optional exceptions in separate sections — both using checkboxes for visual consistency — with required ones pre-checked and disabled, and optional ones pre-checked but user-toggleable. Consent records are stored in a single unified object per tool to support future re-consent detection when domain lists change.Type changes (
src/common/types/common.ts)CspExceptionEntryinterface:{ domain, exceptionReason?, optional? }CspExceptionSource = string | CspExceptionEntry— fully backward-compatible with existing string arraysnormalizeCspExceptionSource()helper exported for converting either format toCspExceptionEntryCspExceptionsdirectives now typed asCspExceptionSource[]Type changes (
src/common/types/settings.ts)CspConsentRecordinterface:{ allowed: boolean; required: string[]; optional: string[] }UserSettings.cspConsentstype updated to{ [toolId: string]: CspConsentRecord }— consolidates the former separatecspRequiredConsentsandcspOptionalConsentskeys into one record per toolRuntime changes
browserviewProtocolManager: CSP header builder only applies optional domains that were explicitly approved by the user; required domains are always applied when consent is grantedmodals/cspException/view: Both Required and Optional sections use checkboxes for consistency — required items are pre-checked and disabled (withcursor: not-allowedstyling); optional items are pre-checked and user-toggleable with an "Uncheck any you do not want to allow" hint; both showexceptionReasonrendered as inline markdown (**bold**,*italic*,`code`)modals/cspException/controller: Accept handler collects only non-disabled (optional) checkbox values using.csp-optional-checkbox:not([disabled])selectorcspExceptionModal: Return type isPromise<string[] | null>—nullmeans declined,string[]contains the approved optional domainssettingsManager:grantCspConsent(toolId, requiredDomains, approvedOptionalDomains)writes a singleCspConsentRecord;revokeCspConsentdeletes the record;getApprovedRequiredDomains()andgetApprovedOptionalDomains()read from the unified recordtoolManagement: Computes required domains fromtool.cspExceptions(all non-optional entries) before granting consent and passes them alongside approved optional domainsNew manifest format
The old string-only format continues to work unchanged.
Stored consent format
Original prompt
🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.