Skip to content

doc(policies): add security, privacy, accessibility and support documents - #2383

Open
rkaraivanov wants to merge 7 commits into
masterfrom
docs/security-compliance-privacy
Open

rkaraivanov wants to merge 7 commits into
masterfrom
docs/security-compliance-privacy

Conversation

@rkaraivanov

Copy link
Copy Markdown
Member

Rewrite SECURITY.md around the agreed support window: all fixes for the
latest major, critical fixes backported to the last minor of the previous
major. Add scope, response targets, disclosure, release verification with
gh attestation, and security considerations for consumers (chat sanitizer,
icon and QR URL fetches, clipboard, CSP).

Add PRIVACY.md stating the no-telemetry, no-storage, no-remote-code
position and listing the browser capabilities the components touch.

Add ACCESSIBILITY.md with the WCAG 2.1 AA target, how axe audits and
manual NVDA checks verify it, and how the components work around ARIA
relations that cannot cross shadow boundaries with ElementInternals and
ARIA element reflection.

Add SUPPORT.md and an issue-template config that routes security reports
to private vulnerability reporting.

Add scripts/build-notices.mjs, which reads the runtime and optional peer
dependencies from the published manifest, collects each package's license
text from node_modules, and writes THIRD-PARTY-NOTICES.md. lit and
@lit/context are BSD-3-Clause, which requires notice reproduction.

Updated README, CONTRIBUTING and issue/PR templates.

…ents

Rewrite SECURITY.md around the agreed support window: all fixes for the
latest major, critical fixes backported to the last minor of the previous
major. Add scope, response targets, disclosure, release verification with
gh attestation, and security considerations for consumers (chat sanitizer,
icon and QR URL fetches, clipboard, CSP).

Add PRIVACY.md stating the no-telemetry, no-storage, no-remote-code
position and listing the browser capabilities the components touch.

Add ACCESSIBILITY.md with the WCAG 2.1 AA target, how axe audits and
manual NVDA checks verify it, and how the components work around ARIA
relations that cannot cross shadow boundaries with ElementInternals and
ARIA element reflection.

Add SUPPORT.md and an issue-template config that routes security reports
to private vulnerability reporting.
Add scripts/build-notices.mjs, which reads the runtime and optional peer
dependencies from the published manifest, collects each package's license
text from node_modules, and writes THIRD-PARTY-NOTICES.md. lit and
@lit/context are BSD-3-Clause, which requires notice reproduction.

The file records declared version ranges rather than installed versions,
so `check-notices` (picked up by `npm run check`) fails only when a
dependency is added, removed or relicensed, not on patch bumps.
`build:publish` regenerates the file and copies it into dist next to
LICENSE.
CodeQL analyzes the TypeScript sources on push, pull request and weekly,
skipping build output and spec/story files. Scorecard runs on push to
master, on branch-protection changes and weekly, publishing results so
the README badge and API resolve; the job follows the publishing API's
workflow restrictions.

Pin every action in the CI and Storybook workflows to a commit SHA with
the version in a trailing comment, matching the release workflow.
Dependabot keeps the pins current.
Move the lint, check, test and Storybook commands from the README into
CONTRIBUTING. Add sections on accessibility requirements (axe on both DOM
trees, APG keyboard patterns, ElementInternals over IDREF), dependency
policy (discuss first, permissive licenses only, both manifests, notices
regeneration, SHA-pinned actions), security expectations for changes, and
the Keep a Changelog `Security` category. State that no CLA or DCO
sign-off is required.

Extend the pull request checklist with changelog, accessibility,
dependency and security items.
Reorder into quick start, components, browser support, tooling, then
short Accessibility, Security and supply chain, Privacy, Contributing,
Support and License sections that each link to their document. Add
CodeQL, OpenSSF Scorecard and license badges and a table of contents.

Development commands now live in CONTRIBUTING. New document links are
absolute URLs because the same README ships in the npm package.
@rkaraivanov
rkaraivanov requested review from damyanpetev and a lite review from Copilot September 16, 2026 10:44
@rkaraivanov rkaraivanov added documentation Improvements or additions to documentation squash-merge Build/CI labels Sep 16, 2026
GitHub rejects SARIF from a workflow-based CodeQL configuration while
default setup is enabled for the repository, and default setup already
scans javascript-typescript on every push and pull request. Remove the
workflow and its README badge, and describe the default setup in the
README and SECURITY.md.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved critical workflow and moderate license-notice issues remain, along with documentation and contribution-policy corrections.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

This PR adds security, privacy, accessibility, support, and supply-chain documentation, plus license-notice automation and security workflows.

Changes:

  • Adds policy documents, support routing, and updated contributor templates.
  • Generates and packages third-party license notices.
  • Adds CodeQL/Scorecard workflows and pins CI actions.
File summaries
File Summary and final findings
THIRD-PARTY-NOTICES.md Generated dependency notices. Moderate (1 vote): marked-shiki lacks reproduced MIT license text; add a vetted fallback or fail generation.
SECURITY.md Security policy and release guidance. Nit (1 vote): Document both immediate logo-src loading and later export fetching.
scripts/build.mjs Packages third-party notices.
scripts/build-notices.mjs Notice generation. Moderate (2 votes): Respect peerDependenciesMeta when labeling optional peers. Moderate (1 vote): Handle missing license files with a reviewed fallback or failure. Nit (1 vote): Replace unchecked any types with validated unknown shapes.
README.md Adds policy and security links. Nit (3 votes): Correct the universal claim that every specification audits both DOM trees.
PRIVACY.md Privacy commitments and browser capabilities. Nit (3 votes): Qualify host-supplied URL fetches. Nit (2 votes): Document BroadcastChannel usage and distinguish automatic capabilities. Nit (1 vote): Clarify automatic locale/time-zone and reduced-motion checks. Nit (1 vote): Correct the reduced-motion media query. Nit (1 vote): Document both logo-src and export-time image requests.
package.json Adds notice build and check scripts.
ACCESSIBILITY.md Accessibility targets and verification. Nit (3 votes): Qualify or complete light/shadow DOM audit coverage. Nit (1 vote): Document the same-root aria-describedby exception.
.github/workflows/scorecard.yml Adds Scorecard analysis. Critical (2 votes): Add contents: read so checkout can access the repository.
.github/workflows/node.js.yml Pins CI actions.
.github/workflows/gh-pages-deploy.yml Pins deployment actions.
.github/workflows/codeql.yml Adds CodeQL analysis.
.github/SUPPORT.md Adds support routing.
.github/pull_request_template.md Adds review checklists.
.github/ISSUE_TEMPLATE/config.yml Routes security reports privately.
.github/CONTRIBUTING.md Expands contribution requirements. Nit (1 vote): Align the mandatory light-DOM audit rule with existing specifications. Nit (1 vote): Add the required [Unreleased] changelog entry.
Review details

Suppressed comments (11)

.github/CONTRIBUTING.md:100

  • This new mandatory rule is not compatible with existing specifications: src/components/qr-code/qr-code.spec.ts:18-22 and src/components/navbar/navbar.spec.ts:10-16 have no light-DOM audit. Update the affected specs in the same change or scope the requirement to cases where a light-DOM audit is applicable.
- Every component specification must audit the component with axe, on both its light DOM and its shadow DOM, in each state the specification exercises: `await expect(el).to.be.accessible()` and `await expect(el).shadowDom.to.be.accessible()`.

.github/CONTRIBUTING.md:94

  • This PR adds user-visible policy and contributor documentation but does not add an entry under the existing [Unreleased] section in CHANGELOG.md. That conflicts with the changelog requirement being introduced here; add a concise Added or Changed entry before merge.
- **Changelog**: Add an entry under `[Unreleased]` in [CHANGELOG.md](../CHANGELOG.md) for every user-visible change. The file follows [Keep a Changelog](https://keepachangelog.com/), so use the `Added`, `Changed`, `Deprecated`, `Removed`, `Fixed` and `Security` categories. A fix for a vulnerability goes under `Security`, with a link to the advisory once it is published.

ACCESSIBILITY.md:36

  • This says all relations use element references, but the implementation intentionally keeps the editor's own description as a same-root aria-describedby IDREF when no projected description exists (see src/internals/controllers/aria-projection.ts:64-68 and 198-200). Qualify this to cross-root relations and document the same-root exception.
- **ARIA element reflection.** Relations are set as element references (`ariaLabelledByElements`, `ariaDescribedByElements`, `ariaControlsElements`, `ariaActiveDescendantElement`) rather than IDREF strings. Element reflection resolves across shadow boundaries into ancestor tree scopes, which lets a composite component point at an element the page or another component owns. The projection controller in `src/internals/controllers/aria-projection.ts` carries those references to the native control inside an input-shaped component, since that is the element assistive technology lands on.

PRIVACY.md:24

  • This sentence overstates the boundary: the icon registry deliberately publishes user-registered icon SVGs and references over BroadcastChannel to same-origin browsing contexts, and the fetch rows send host-supplied URLs to their origins. Qualify it to data rendered by the components except for the explicitly documented network and cross-context operations.
Data your application passes into a component, such as chat messages, form values or dates, stays in the page. The components render it and expose it back through their properties and events, and nowhere else.

PRIVACY.md:14

  • Locale/time-zone formatting and reduced-motion checks are performed automatically while components render or animate; they are not all triggered by an explicit host call or user action. Narrow this sentence to the network and clipboard operations, or state that these preferences may be read automatically.
Some components use browser APIs that can involve user data. Each is triggered only by an explicit call from the host application or by a user action inside the component.

PRIVACY.md:22

  • The documented media query does not match the implementation, which calls matchMedia('(prefers-reduced-motion: reduce)'). Correcting the query is important for consumers who use this table to audit browser capabilities.
| Reduced-motion preference     | Animations                           | Read through `matchMedia('(prefers-reduced-motion)')` to shorten or skip animations.           |

PRIVACY.md:19

  • Assigning logo-src already creates an Image and loads the URL to determine its dimensions; exporting then may fetch the same non-data URL again to inline it. Describing the request as occurring only during QR export can cause consumers to miss a network/privacy request at render time.
| `fetch` of an application URL | QR code export with an embedded image| Only for the image URL the host application passes to the export call.                         |

SECURITY.md:79

  • Setting logo-src loads the image immediately to determine its aspect ratio, before any export call; toBlob()/toImage() can then fetch it again while inlining it. Document both triggers so consumers do not assume this request is deferred until export.
- **QR code export.** Exporting a QR code with an embedded image fetches the image URL you pass to draw it on a canvas. Only supply URLs you trust.

THIRD-PARTY-NOTICES.md:836

  • This generated section is the only entry without reproduced license text: it lists MIT for marked-shiki but emits only a pointer to its repository. That does not meet the document's stated goal of carrying license terms for redistributors and contradicts the PR description's promise to collect each package's license text. Please add a vetted license-text fallback or fail notice generation when a declared license file is absent.
The package ships no license file. Its manifest declares `MIT`; refer to the source repository for the license text.

scripts/build-notices.mjs:110

  • When a package has no matching file, this path records only the SPDX identifier and emits no license text. The generated notice currently does this for marked-shiki, even though the document promises license terms and the package declares MIT; an identifier plus a repository link does not reproduce the MIT grant/attribution. Please fail generation or provide a reviewed fallback/override for packages that omit their license file instead of silently accepting an incomplete notice.
  if (files.length === 0) {
    log(CATEGORY, `${name} ships no license file; recording its SPDX id only`);
  }

scripts/build-notices.mjs:19

  • The new script uses any for parsed JSON and manifests in four JSDoc signatures. This bypasses the repository's strict typing guidance and makes malformed manifest shapes unchecked; define a manifest/notice input shape and use unknown plus validation/narrowing instead.
/**
 * @param {string} file - Path to a JSON file.
 * @returns {any} Parsed content.
 */
  • Files reviewed: 15/15 changed files
  • Comments generated: 6
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/workflows/scorecard.yml
Comment thread scripts/build-notices.mjs
Comment thread ACCESSIBILITY.md Outdated
Comment thread PRIVACY.md Outdated
Comment thread PRIVACY.md Outdated
Comment thread README.md Outdated
Correct claims that did not match the source: only some specifications
audit both the light and the shadow DOM, the reduced-motion query is
"(prefers-reduced-motion: reduce)", a QR logo loads when logo-src is set
and again on export, and the icon registry opens a same-origin
BroadcastChannel automatically. Qualify the "no third party" and
"nowhere else" statements in PRIVACY.md to the documented host-supplied
URL fetches, and note the same-root aria-describedby exception in
ACCESSIBILITY.md.

Make the notices generator label peers from peerDependenciesMeta instead
of assuming every peer is optional, and fail when a package declares a
license but ships no license file unless a reviewed copy exists under
scripts/license-overrides. Add the MIT text for marked-shiki from its
source repository and record the shipped notices file in the changelog.
Comment on lines +3 to +5
- name: 🔒 Report a security vulnerability
url: https://github.com/IgniteUI/igniteui-webcomponents/security/advisories/new
about: Report vulnerabilities privately. Never open a public issue for a security problem.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is there by default and the links are additive.
For ref https://github.com/IgniteUI/igniteui-blazor/blob/master/.github/ISSUE_TEMPLATE/config.yml adds just the two links:
Image

Also, would not mind these being somewhat consistent across repos TBH, so not a 100% on the rest of the links

Comment thread .github/CONTRIBUTING.md
Comment on lines +17 to +18
No contributor license agreement or sign-off is required. By submitting a pull request you agree that your contribution is licensed under the project's [MIT License](../LICENSE).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure we need to re-iterate this bit explicitly, however, I had a look around and that's stated in the GitHub ToS in D.6 Contributions Under Repository License -
https://docs.github.com/en/site-policy/github-terms/github-terms-of-service#6-contributions-under-repository-license

More importantly the text there includes the critical bit that

and you agree that you have the right to license that Content under those terms

which is significant.

// CC @kdinev

Comment thread .github/CONTRIBUTING.md
Runtime dependencies increase the install footprint and the attack surface of every application that uses the library, so they are added rarely and deliberately.

- **Discuss first.** Open an issue or a discussion before adding a runtime dependency or an optional peer dependency. Prefer a small, focused implementation in `src/internals` over a package that does more than the component needs.
- **Licenses.** Runtime and peer dependencies must be licensed under MIT, BSD-2-Clause, BSD-3-Clause, ISC, Apache-2.0, 0BSD or an equivalent permissive license. Copyleft licenses (GPL, LGPL, AGPL, SSPL) are not accepted for anything that ships to consumers. Dual-licensed packages are accepted when one of the options is permissive.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not super sure of the dual bit

Comment thread .github/CONTRIBUTING.md
- **Manifests.** A runtime dependency is declared in both `package.json` and the published manifest `scripts/_package.json`. Optional peer dependencies are declared with `peerDependenciesMeta.optional: true` in the published manifest.
- **Notices.** After changing a runtime or peer dependency, run `npm run build:notices` and commit the regenerated `THIRD-PARTY-NOTICES.md`. CI fails when the file is out of date. Generation fails for a package that declares a license but ships no license file; copy the text from the package's source repository into `scripts/license-overrides/<package-name>` (with `/` replaced by `__` for scoped packages) and note where it came from in the pull request.
- **Lockfile.** Commit `package-lock.json` changes together with the manifest change. Install with `npm ci`, never `npm install`, so the lockfile stays authoritative.
- **Updates.** Dependabot raises security updates for npm packages daily and version updates for GitHub Actions weekly. Routine npm version bumps are done by maintainers in batches. GitHub Actions are pinned to a commit SHA with the version in a trailing comment; keep that format when adding or updating an action.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that a dev workflow or just re-hashing info here since it seemed related?

Comment thread .github/CONTRIBUTING.md
- **Provide Details**: In your issue report, provide as much detail as possible to help diagnose the problem. This might include steps to reproduce the issue, error messages, and expected behavior.

See [SUPPORT.md](./SUPPORT.md) for where questions, feature requests, security reports and commercial support requests belong.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This I don't think fits into the contributing guidance much TBH.

- [ ] Breaking changes are documented in the description
- [ ] Accessibility: axe audits pass on the light and shadow DOM, and keyboard interaction is covered by tests
- [ ] Dependencies: no new runtime or peer dependency, or its license was reviewed and `THIRD-PARTY-NOTICES.md` was regenerated
- [ ] Security: the change adds no network access, storage, telemetry or unsanitized HTML rendering

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, wouldn't a general "I've read the contributing" check do? Just trying to figure out the pattern for the checkboxes (usually "things to do") while the last one is defensive.

Comment thread .github/SUPPORT.md
Comment on lines +13 to +14
| Get help with a commercial Ignite UI product | [Infragistics support](https://www.infragistics.com/about-us/contact-us) |
| Read the documentation | [Product documentation](https://www.infragistics.com/products/ignite-ui-web-components) and [Storybook](https://igniteui.github.io/igniteui-webcomponents) |

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd put Read the documentation higher in the list ;) And maybe merge or group the bug and accessibility issues

Comment thread SECURITY.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need careful review, assuming a similar pattern should be applied across the board

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to test this one out, however alt suggestion since @turbobobbytraykov already established a similar check in IgniteUI/igniteui-blazor#371 using actions/dependency-review-action

     - name: Review dependency changes
        uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0

https://github.com/IgniteUI/igniteui-blazor/blob/caee9f6c7f93d48a9a4b9b003b1fc3d37a9a71ff/.github/workflows/ci.yml#L29-L30

Producing

Image https://github.com/IgniteUI/igniteui-blazor/actions/runs/35250925962 as an example.

Again, all with the goal of consistency across the repos :)

Comment thread README.md
Comment on lines +31 to +67
## Quick start

Install the `igniteui-webcomponents` package:

```sh
npm install igniteui-webcomponents
```

Import and register the components you need with the `defineComponents` function:

```ts
import {
defineComponents,
IgcAvatarComponent,
IgcBadgeComponent,
} from 'igniteui-webcomponents';

defineComponents(IgcAvatarComponent, IgcBadgeComponent);
```

You can also register every component at once with `defineAllComponents`:

```ts
import { defineAllComponents } from 'igniteui-webcomponents';

defineAllComponents();
```

Registering all components increases the bundle size of your application, so register only the ones you use.

After the components are registered, use them in your HTML:

```html
<igc-avatar initials="AZ"></igc-avatar><igc-badge></igc-badge>
```

See the [documentation][Ignite UI for Web Components] for guides on each component, theming, and framework integration.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure, but I think the component table was quite intentionally left at the top of content (affects repo and npm pacakge views IIRC)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Build/CI documentation Improvements or additions to documentation squash-merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants