Permissions Policy

Enabled Decide what API's the site can access.


Permissions Policy provides mechanisms for web developers to explicitly declare what functionality can and cannot be used on a web site. You define a set of "policies" that restrict what APIs the site's code can access or modify the browser's default behavior for certain features.

ℹ Read more about this header here.

Usage

This header is enabled by default but you can change its behavior like following.

export default defineNuxtConfig({
  // Global
  security: {
    headers: {
      permissionsPolicy: <OPTIONS>,
    },
  },

  // Per route
  routeRules: {
    '/custom-route': {
      security: {
        headers: {
          permissionsPolicy: <OPTIONS>,
        },
      },
    }
  }
})

You can also disable this header by setting permissionsPolicy: false. To disable certain API completely, set its value to empty array like:

export default defineNuxtConfig({
  security: {
    headers: {
      permissionsPolicy: {
        'camera': [] // This will block usage of camera by this website
      },
    },
  },
})

Default value

By default, Nuxt Security will set following value for this header.

Permissions-Policy: accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), display-capture=(), document-domain=(), encrypted-media=(), fullscreen=(), gamepad=(), geolocation=(), gyroscope=(), layout-animations=(self), legacy-image-formats=(self), magnetometer=(), microphone=(), midi=(), oversized-images=(self), payment=(), picture-in-picture=(), publickey-credentials-get=(), speaker-selection=(), sync-xhr=(self), unoptimized-images=(self), unsized-media=(self), usb=(), screen-wake-lock=(), web-share=(), xr-spatial-tracking=();

Available values

The permissionsPolicy header can be configured with following values.

permissionsPolicy: {
  'camera'?: string[] | string;
  'display-capture'?: string[] | string;
  'fullscreen'?: string[] | string;
  'geolocation'?: string[] | string;
  'microphone'?: string[] | string;
  'web-share'?: string[] | string;
} | false

And several 🧪 Experimental API's.

type PermissionsPolicyValue = {
  'accelerometer'?: string[] | string;
  'ambient-light-sensor'?: string[] | string;
  'autoplay'?: string[] | string;
  'battery'?: string[] | string;
  'document-domain'?: string[] | string;
  'encrypted-media'?: string[] | string;
  'execution-while-not-rendered'?: string[] | string;
  'execution-while-out-of-viewport'?: string[] | string;
  'gamepad'?: string[] | string;
  'gyroscope'?: string[] | string;
  'hid'?: string[] | string;
  'idle-detection'?: string[] | string;
  'local-fonts'?: string[] | string;
  'magnetometer'?: string[] | string;
  'midi'?: string[] | string;
  'payment'?: string[] | string;
  'picture-in-picture'?: string[] | string;
  'publickey-credentials-get'?: string[] | string;
  'screen-wake-lock'?: string[] | string;
  'serial'?: string[] | string;
  'speaker-selection'?: string[] | string;
  'usb'?: string[] | string;
  'xr-spatial-tracking'?: string[] | string;
}
ℹ Read more about all available APIs here.

Per-route configuration

All Permissions Policy options can be defined on a per-route level.

As examplified below, rules are merged recursively when resolved :

export default defineNuxtConfig({
  // Global
  security: {
    headers: {
      permissionsPolicy: {
        'geolocation': [] // By default, geolocation disabled
      }
    }
  }
  // Per route
  routeRules: {
    '/some-prefix/**': {
      security: {
        headers: {
          permissionsPolicy: {
            'geolocation': ['self'] // Self origin allowed for geolocation on all routes beginning with /some-prefix/
          }
        }
      }
    },
    '/some-prefix/some-route/**': {
      security: {
        headers: {
          permissionsPolicy: {
            'geolocation': ['self', 'https://*.example.com']  // Self AND *.example.com allowed for routes beginning with /some-prefix/some-route/
          }
        }
      }
    },
    '/some-prefix/some-route/some-page': {
      security: {
        headers: {
          contentSecurityPolicy: {
            'geolocation': ['self']  // ONLY self allowed on /some-prefix/some-route/some-page
          }
        }
      }
    }
  }
})