> AI agents: this is one page from PostHog's docs. Full index of Markdown docs for LLMs: https://posthog.com/llms.txt # Securely install the JavaScript SDK Canonical URL: https://posthog.com/docs/libraries/js/security > **Cloud region:** This page uses US Cloud hosts. For an EU Cloud project, use `https://eu-assets.i.posthog.com` instead of `https://us-assets.i.posthog.com` (assets host). ## On this page - [Pin and update SDK versions](#pin-and-update-sdk-versions) - [Use Subresource Integrity with a pinned script](#use-subresource-integrity-with-a-pinned-script) - [Configure Content Security Policy](#configure-content-security-policy) - [Use nonces for authorized scripts and styles](#use-nonces-for-authorized-scripts-and-styles) - [Bundle the SDK without external scripts](#bundle-the-sdk-without-external-scripts) - [Review data access and verify your installation](#review-data-access-and-verify-your-installation) The [JavaScript SDK](https://posthog.com/docs/libraries/js.md) runs with the same access to your page as your own application code. Use version controls, Subresource Integrity (SRI), Content Security Policy (CSP), and nonces to control how you load it. These controls protect different boundaries; none makes untrusted code safe to run. ## Pin and update SDK versions If you need to review SDK changes before deployment, follow [snippet versioning](https://posthog.com/docs/libraries/js/snippet-versioning.md) for CDN installations or the [package-manager lockfile guidance](https://posthog.com/docs/health-checks/keeping-sdks-current.md#npm-and-package-manager-lockfiles) for npm installations. Use an exact dependency version, commit the lockfile, and enforce frozen installs in CI. Version pins and [versioned feature scripts](https://posthog.com/docs/libraries/js/snippet-versioning.md#versioned-external-scripts) select releases; they don't verify the bytes returned by a CDN or proxy. The token-specific `/array//config.js` script isn't pinned by `strict_script_versioning`. Review and deploy updates regularly so pins don't prevent security fixes from reaching your users. See [keeping SDKs current](https://posthog.com/docs/health-checks/keeping-sdks-current.md). ## Use Subresource Integrity with a pinned script [Subresource Integrity (SRI)](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity) enables the browser to check a downloaded script against an expected cryptographic hash before executing it. Use it with an exact-version URL, not a moving URL such as `/static/array.js` or `/static/1/array.js`. ### Generate and review the hash Download the exact asset you intend to deploy and calculate its SHA-384 digest. Version `1.444.0` below is an example; choose a release you have reviewed. ```bash curl --fail --show-error --silent --location \ "https://us-assets.i.posthog.com/static/1.444.0/array.js" \ --output posthog-array.js printf 'sha384-' openssl dgst -sha384 -binary posthog-array.js | openssl base64 -A printf '\n' ``` Use your actual regional asset host or reverse-proxy URL. Review the downloaded artifact through your normal dependency approval process, then store the expected hash in your application code. Calculating a hash from a compromised download doesn't establish that the code is trustworthy. Don't fetch the expected hash dynamically from the same server at page load. ### Add the hash to the SDK script In the [HTML snippet](https://posthog.com/docs/libraries/js.md#installation), replace the `p.src` assignment with these comma-separated assignments, before the script is inserted into the DOM: ```javascript p.integrity = "sha384-", p.crossOrigin = "anonymous", p.src = s.api_host.replace(".i.posthog.com", "-assets.i.posthog.com") + "/static/1.444.0/array.js" ``` Replace `` with the digest from the previous step, and keep the rest of the snippet unchanged. The URL must serve the exact bytes you hashed. Cross-origin SRI requires a CORS response header such as `Access-Control-Allow-Origin: *`; PostHog's asset hosts provide this. Preserve it if you serve assets through a cross-origin proxy. Adding `integrity` to the outer inline `