npm package: @jackdbd/permissions-policy
Description: Define your `Permissions-Policy` in JavaScript and let this library generate the header for you.
Author: Giacomo Debidda
Latest version: 1.0.0

# permissions-policy

[![npm package badge](https://badge.fury.io/js/@jackdbd%2Fpermissions-policy.svg)](https://badge.fury.io/js/@jackdbd%2Fpermissions-policy)
[![install size badge](https://packagephobia.com/badge?p=@jackdbd/permissions-policy)](https://packagephobia.com/result?p=@jackdbd/permissions-policy)
[![CI GitHub workflow badge](https://github.com/jackdbd/permissions-policy/actions/workflows/ci.yaml/badge.svg)](https://github.com/jackdbd/permissions-policy/actions/workflows/ci.yaml)
[![CodeCov badge](https://codecov.io/gh/jackdbd/permissions-policy/graph/badge.svg?token=9jddzo5Dt3)](https://codecov.io/gh/jackdbd/permissions-policy)
[![CodeFactor badge](https://www.codefactor.io/repository/github/jackdbd/permissions-policy/badge)](https://www.codefactor.io/repository/github/jackdbd/permissions-policy)
[![Socket badge](https://socket.dev/api/badge/npm/package/@jackdbd/permissions-policy)](https://socket.dev/npm/package/@jackdbd/permissions-policy)
[![Conventional Commits badge](https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white)](https://conventionalcommits.org)

Define your `Permissions-Policy` in JavaScript and let this library generate the header for you.

- [Installation](#installation)
- [About](#about)
- [Docs](#docs)
- [Usage](#usage)
- [Configuration](#configuration)
  - [Options](#options)
  - [Features](#features)
  - [Allowlist](#allowlist)
- [Troubleshooting](#troubleshooting)
- [Dependencies](#dependencies)
- [License](#license)

## Installation

```sh
npm install @jackdbd/permissions-policy
```

**Note**: this library was tested on Node.js >=18. It might work on other Node.js versions though.

## About

This library allows you to define a [Permissions-Policy](https://w3c.github.io/webappsec-permissions-policy/) and a [Feature-Policy](https://developer.mozilla.org/en-US/docs/Web/API/FeaturePolicy) in JavaScript, and then it generates the corresponding headers for you.

## Docs

[Docs generated by TypeDoc](https://jackdbd.github.io/permissions-policy/permissions-policy/)

> :open_book: **API Docs**
>
> This project uses [API Extractor](https://api-extractor.com/) and [api-documenter markdown](https://api-extractor.com/pages/commands/api-documenter_markdown/) to generate a bunch of markdown files and a `.d.ts` rollup file containing all type definitions consolidated into a single file. I don't find this `.d.ts` rollup file particularly useful. On the other hand, the markdown files that api-documenter generates are quite handy when reviewing the public API of this project.
>
> *See [Generating API docs](https://api-extractor.com/pages/setup/generating_docs/) if you want to know more*.

## Usage

Here is how you can generate a `Permissions-Policy` header:

```ts
import { permissionsPolicy } from '@jackdbd/permissions-policy'

const { error, value } = permissionsPolicy({
  features: {
    bluetooth: [],
    camera: ['self'],
    fullscreen: ['*'],
    microphone: ['self', 'https://*.example.com']
  },
  reportingEndpoint: 'permissions_policy'
})
```

Since at the moment [browser support for Permissions-Policy](https://caniuse.com/?search=Permissions-Policy) is [not as wide as for Feature-Policy](https://caniuse.com/?search=Feature-Policy), it's probably a good idea to generate `Feature-Policy` too. This library has you covered:

```ts
import { featurePolicy } from '@jackdbd/permissions-policy'

const { error, value } = featurePolicy({
  features: {
    bluetooth: [],
    camera: ['self'],
    fullscreen: ['*'],
    microphone: ['self', 'https://*.example.com']
  }
})
```

## Configuration

Read these resources to understand how to configure the `Permissions-Policy` and the `Feature-Policy` HTTP response headers.

- [A new security header: Feature Policy](https://scotthelme.co.uk/a-new-security-header-feature-policy/)
- [Goodbye Feature Policy and hello Permissions Policy!](https://scotthelme.co.uk/goodbye-feature-policy-and-hello-permissions-policy/)
- [Permissions Policy Explainer](https://github.com/w3c/webappsec-permissions-policy/blob/main/permissions-policy-explainer.md)
- [Policy Controlled Features](https://github.com/w3c/webappsec-permissions-policy/blob/main/features.md)
- [Controlling browser features with Permissions Policy](https://developer.chrome.com/en/docs/privacy-sandbox/permissions-policy/)

### Options

| Key | Default | Description |
|---|---|---|
| `features` | `{}` | Hash map for configuring `Permissions-Policy`. Each entry has a [directive](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy#directives) as the key, and an [allowlist](https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy#allowlists) as the value. |
| `reportingEndpoint` | `undefined` | Endpoint for the [Reporting API](https://developer.mozilla.org/en-US/docs/Web/API/Reporting_API). Violations of `Permissions-Policy` (or `Permissions-Policy-Report-Only`) will be sent here. |

### Features

This library defines 55 `Permissions-Policy` features:

[accelerometer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/accelerometer), [ambient-light-sensor](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ambient-light-sensor), [attribution-reporting](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/attribution-reporting), [autoplay](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/autoplay), [battery](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/battery), [bluetooth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/bluetooth), [browsing-topics](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/browsing-topics), [camera](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/camera), [ch-device-memory](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ch-device-memory), [ch-downlink](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ch-downlink), [ch-ect](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ch-ect), [ch-rtt](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ch-rtt), [ch-save-data](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ch-save-data), [ch-ua-arch](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ch-ua-arch), [ch-ua-bitness](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/ch-ua-bitness), [clipboard-read](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/clipboard-read), [clipboard-write](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/clipboard-write), [conversion-measurement](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/conversion-measurement), [cross-origin-isolated](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/cross-origin-isolated), [display-capture](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/display-capture), [document-domain](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/document-domain), [encrypted-media](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/encrypted-media), [execution-while-not-rendered](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/execution-while-not-rendered), [execution-while-out-of-viewport](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/execution-while-out-of-viewport), [focus-without-user-activation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/focus-without-user-activation), [fullscreen](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/fullscreen), [gamepad](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/gamepad), [geolocation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/geolocation), [gyroscope](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/gyroscope), [hid](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/hid), [idle-detection](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/idle-detection), [layout-animations](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/layout-animations), [legacy-image-formats](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/legacy-image-formats), [magnetometer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/magnetometer), [microphone](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/microphone), [midi](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/midi), [navigation-override](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/navigation-override), [oversized-images](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/oversized-images), [payment](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/payment), [picture-in-picture](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/picture-in-picture), [publickey-credentials-get](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/publickey-credentials-get), [screen-wake-lock](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/screen-wake-lock), [serial](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/serial), [speaker-selection](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/speaker-selection), [sync-script](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/sync-script), [sync-xhr](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/sync-xhr), [trust-token-redemption](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/trust-token-redemption), [unload](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/unload), [unoptimized-images](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/unoptimized-images), [unsized-media](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/unsized-media), [usb](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/usb), [vertical-scroll](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/vertical-scroll), [web-share](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/web-share), [window-placement](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/window-placement), [xr-spatial-tracking](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Permissions-Policy/xr-spatial-tracking)

### Allowlist

An [allowlist](https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy#allowlists) is a list containing specific origins or special values.

## Troubleshooting

This library uses [debug](https://github.com/debug-js/debug) for logging.
You can control what's logged using the `DEBUG` environment variable.

For example, if you set your environment variables in a `.envrc` file, you can do:

```sh
export DEBUG=permissions-policy
```

If you are trying to configure `Permissions-Policy` or `Feature-Policy` with one or more features not implemented in this library, you can opt out of the schema validation by setting the environment variable `SKIP_VALIDATION` to `1`.

```sh
export SKIP_VALIDATION=1
```

## Dependencies

| Package | Version |
|---|---|
| [zod](https://www.npmjs.com/package/zod) | `^3.23.4` |
| [zod-validation-error](https://www.npmjs.com/package/zod-validation-error) | `^3.2.0` |

> ⚠️ **Peer Dependencies**
>
> This package defines 1 peer dependency.

| Peer | Version range |
|---|---|
| `debug` | `>=4.0.0` |

## License

&copy; 2024 [Giacomo Debidda](https://www.giacomodebidda.com/) // [MIT License](https://spdx.org/licenses/MIT.html)