diff --git a/env.d.ts b/env.d.ts index 453e8a03..2b267ef4 100644 --- a/env.d.ts +++ b/env.d.ts @@ -11,3 +11,7 @@ declare module "npm:@arcjet/deno" { export * from "@arcjet/deno"; export default arcjet; } + +declare module "npm:nosecone" { + export { default } from "nosecone"; +} diff --git a/next-server.d.ts b/next-server.d.ts new file mode 100644 index 00000000..4a93b637 --- /dev/null +++ b/next-server.d.ts @@ -0,0 +1,11 @@ +/** + * Augment the `next/server` module to fake the API differences between 14 & 15 + */ + +// Need to import next/server to augment it with `declare module` +import "next/server"; + +declare module "next/server" { + // Faking this because Next.js 14 doesn't have the `connection` export + export const connection: () => Promise; +} diff --git a/package-lock.json b/package-lock.json index 1395e248..4d828a40 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,8 @@ "@nestjs/config": "3.3.0", "@nestjs/core": "10.4.13", "@nestjs/platform-express": "10.4.13", + "@nosecone/next": "1.0.0-alpha.34", + "@nosecone/sveltekit": "1.0.0-alpha.34", "@remix-run/node": "2.15.0", "@sveltejs/kit": "2.9.0", "ai": "4.0.10", @@ -57,6 +59,7 @@ "nanostores": "0.11.3", "next": "14.2.15", "next-auth": "4.24.10", + "nosecone": "1.0.0-alpha.34", "openai-chat-tokens": "0.2.8", "pagefind": "1.2.0", "pino": "9.5.0", @@ -3499,6 +3502,36 @@ "node": ">= 8" } }, + "node_modules/@nosecone/next": { + "version": "1.0.0-alpha.34", + "resolved": "https://registry.npmjs.org/@nosecone/next/-/next-1.0.0-alpha.34.tgz", + "integrity": "sha512-4KXgjR580QTsdbM/F9WoLR/AQxJD48na27XnS9De5LIFBemDZ5ObC6L901WrBF3EJGz1M0E9AFQ0nKGUh+ascQ==", + "license": "Apache-2.0", + "dependencies": { + "nosecone": "1.0.0-alpha.34" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "next": ">=14" + } + }, + "node_modules/@nosecone/sveltekit": { + "version": "1.0.0-alpha.34", + "resolved": "https://registry.npmjs.org/@nosecone/sveltekit/-/sveltekit-1.0.0-alpha.34.tgz", + "integrity": "sha512-PkgVsYCkK1XrdkiKx57Uf6M7FK/XxQdB35rj8GScmZwiXcAnffPEndw/yepp4yNcetnm6u2ueuwUi8CuB04pwA==", + "license": "Apache-2.0", + "dependencies": { + "nosecone": "1.0.0-alpha.34" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@sveltejs/kit": ">=2" + } + }, "node_modules/@nuxtjs/opencollective": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz", @@ -11527,6 +11560,15 @@ "node": ">=6" } }, + "node_modules/nosecone": { + "version": "1.0.0-alpha.34", + "resolved": "https://registry.npmjs.org/nosecone/-/nosecone-1.0.0-alpha.34.tgz", + "integrity": "sha512-GPqypMOeGXjZXHS+I9jTBFB12GNlAmC21LRRhAKuc4v2beMDzW/ChYSQ8sMSr0f7/Ov4ffQJH0i84iAny5Y5fg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, "node_modules/npmlog": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", diff --git a/package.json b/package.json index e28ca0b2..90906188 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,8 @@ "@nestjs/config": "3.3.0", "@nestjs/core": "10.4.13", "@nestjs/platform-express": "10.4.13", + "@nosecone/next": "1.0.0-alpha.34", + "@nosecone/sveltekit": "1.0.0-alpha.34", "@remix-run/node": "2.15.0", "@sveltejs/kit": "2.9.0", "ai": "4.0.10", @@ -60,6 +62,7 @@ "nanostores": "0.11.3", "next": "14.2.15", "next-auth": "4.24.10", + "nosecone": "1.0.0-alpha.34", "openai-chat-tokens": "0.2.8", "pagefind": "1.2.0", "pino": "9.5.0", diff --git a/src/components/SDKVersionNosecone.astro b/src/components/SDKVersionNosecone.astro new file mode 100644 index 00000000..3f1f1f67 --- /dev/null +++ b/src/components/SDKVersionNosecone.astro @@ -0,0 +1,4 @@ + + + npm badge + \ No newline at end of file diff --git a/src/components/SDKVersionNoseconeNext.astro b/src/components/SDKVersionNoseconeNext.astro new file mode 100644 index 00000000..fbb9dd20 --- /dev/null +++ b/src/components/SDKVersionNoseconeNext.astro @@ -0,0 +1,4 @@ + + + npm badge + \ No newline at end of file diff --git a/src/components/SDKVersionNoseconeSvelteKit.astro b/src/components/SDKVersionNoseconeSvelteKit.astro new file mode 100644 index 00000000..ac3d6354 --- /dev/null +++ b/src/components/SDKVersionNoseconeSvelteKit.astro @@ -0,0 +1,4 @@ + + + npm badge + \ No newline at end of file diff --git a/src/content/docs/nosecone/quick-start.mdx b/src/content/docs/nosecone/quick-start.mdx new file mode 100644 index 00000000..9651be8e --- /dev/null +++ b/src/content/docs/nosecone/quick-start.mdx @@ -0,0 +1,169 @@ +--- +title: "Arcjet Nosecone: Security headers for JS frameworks" +description: "How to use the open source Arcjet Nosecone library to set security headers (CSP, HSTS, and others) in your Bun, Deno, Next.js, Node.js, or SvelteKit app." +prev: false +next: false +frameworks: + - bun + - deno + - next-js + - node-js + - sveltekit +ajToc: + - text: "Supported headers" + anchor: "supported-headers" + - text: "Quick start" + anchor: "quick-start" + children: + - text: 1. Install Nosecone + anchor: "1-install-nosecone" + - text: 2. Configure your application + anchor: "2-configure-your-application" + - text: 3. Run your application + anchor: "3-run-your-application" + - text: 4. Inspect the headers + anchor: "4-inspect-the-headers" + - text: "What next?" + anchor: "what-next" + - text: "Get help" + anchor: "get-help" +--- + +import WhatAreArcjetUtilities from "@/components/WhatAreArcjetUtilities.astro"; +import FrameworkName from "@/components/FrameworkName"; +import SDKVersionNosecone from "@/components/SDKVersionNosecone.astro"; +import SlotByFramework from "@/components/SlotByFramework"; +import { LinkCard, CardGrid } from "@astrojs/starlight/components"; +import Comments from "/src/components/Comments.astro"; + +import BunStep1 from "@/snippets/nosecone/quick-start/bun/Step1.mdx"; +import BunStep2 from "@/snippets/nosecone/quick-start/bun/Step2.mdx"; +import BunStep3 from "@/snippets/nosecone/quick-start/bun/Step3.mdx"; +import BunStep4 from "@/snippets/nosecone/quick-start/bun/Step4.mdx"; + +import DenoStep1 from "@/snippets/nosecone/quick-start/deno/Step1.mdx"; +import DenoStep2 from "@/snippets/nosecone/quick-start/deno/Step2.mdx"; +import DenoStep3 from "@/snippets/nosecone/quick-start/deno/Step3.mdx"; +import DenoStep4 from "@/snippets/nosecone/quick-start/deno/Step4.mdx"; + +import NextJsStep1 from "@/snippets/nosecone/quick-start/next-js/Step1.mdx"; +import NextJsStep2 from "@/snippets/nosecone/quick-start/next-js/Step2.mdx"; +import NextJsStep3 from "@/snippets/nosecone/quick-start/next-js/Step3.mdx"; +import NextJsStep4 from "@/snippets/nosecone/quick-start/next-js/Step4.mdx"; + +import NodeJsStep1 from "@/snippets/nosecone/quick-start/node-js/Step1.mdx"; +import NodeJsStep2 from "@/snippets/nosecone/quick-start/node-js/Step2.mdx"; +import NodeJsStep3 from "@/snippets/nosecone/quick-start/node-js/Step3.mdx"; +import NodeJsStep4 from "@/snippets/nosecone/quick-start/node-js/Step4.mdx"; + +import SvelteKitStep1 from "@/snippets/nosecone/quick-start/sveltekit/Step1.mdx"; +import SvelteKitStep2 from "@/snippets/nosecone/quick-start/sveltekit/Step2.mdx"; +import SvelteKitStep3 from "@/snippets/nosecone/quick-start/sveltekit/Step3.mdx"; +import SvelteKitStep4 from "@/snippets/nosecone/quick-start/sveltekit/Step4.mdx"; + +[](https://www.npmjs.com/package/nosecone) + +Arcjet Nosecone is an [open source library](https://github.com/arcjet/arcjet-js) +that helps set security headers such as `Content-Security-Policy` (CSP), +`Strict-Transport-Security` (HSTS), and `X-Content-Type-Options` in JS +applications built with Bun, Deno, Next.js, Node.js, or SvelteKit. + + + +## Supported headers + +Nosecone makes it easy to add and configure these headers: + +- `Content-Security-Policy` (CSP) +- `Cross-Origin-Embedder-Policy` (COEP) +- `Cross-Origin-Opener-Policy` +- `Cross-Origin-Resource-Policy` +- `Origin-Agent-Cluster` +- `Referrer-Policy` +- `Strict-Transport-Security` (HSTS) +- `X-Content-Type-Options` +- `X-DNS-Prefetch-Control` +- `X-Download-Options` +- `X-Frame-Options` +- `X-Permitted-Cross-Domain-Policies` +- `X-XSS-Protection` + +See the [reference guide](/nosecone/reference) for full details on each option. + +:::note +If you are using Express, NestJS, or Remix we recommend using the excellent +[Helmet](https://helmetjs.github.io/) library, which informed much of our work +on Nosecone. +::: + +## Quick start + +This guide will show you how to add our recommended +default security headers. + +### 1. Install Nosecone + +In your project root, run the following command to install the Arcjet Nosecone +library for your framework: + + + + + + + + + +### 2. Configure your application + + + + + + + + + +### 3. Run your application + + + + + + + + + +### 4. Inspect the headers + +The default headers apply a pragmatic set of security headers to your +application, but may break things (particularly the CSP header). + +We recommend you test your application thoroughly and tweak the settings to +ensure it continues to work as expected. + + + + + + + + + +## What next? + + + + + +## Get help + +Need help with anything? Email support@arcjet.com to get support from our +engineering team, [join our Discord](https://arcjet.com/discord), or [open an +issue on GitHub](https://github.com/arcjet/arcjet-js). + + diff --git a/src/content/docs/nosecone/reference.mdx b/src/content/docs/nosecone/reference.mdx new file mode 100644 index 00000000..8ac0a434 --- /dev/null +++ b/src/content/docs/nosecone/reference.mdx @@ -0,0 +1,636 @@ +--- +title: "Arcjet Nosecone reference" +description: "Reference for the Nosecone library showing how to configure security headers (CSP, HSTS, and others) in your Bun, Deno, Next.js, Node.js, or SvelteKit app." +--- + +import SDKVersionNosecone from "@/components/SDKVersionNosecone.astro"; +import SDKVersionNoseconeNext from "@/components/SDKVersionNoseconeNext.astro"; +import SDKVersionNoseconeSvelteKit from "@/components/SDKVersionNoseconeSvelteKit.astro"; +import WhatAreArcjetUtilities from "@/components/WhatAreArcjetUtilities.astro"; +import SelectableContent from "@/components/SelectableContent"; +import DisplayType from "@/components/DisplayType.astro"; + +[](https://www.npmjs.com/package/nosecone) + +Arcjet Nosecone is an [open source library](https://github.com/arcjet/arcjet-js) +that helps set security headers such as `Content-Security-Policy` (CSP), +`Strict-Transport-Security` (HSTS), and `X-Content-Type-Options` in JS +applications built with Bun, Deno, Next.js, Node.js, or SvelteKit. + + + +## Quick start + +To get started, follow our [quick start guide](/nosecone/quick-start). + +## Next.js security headers middleware + +[](https://www.npmjs.com/package/@nosecone/next) + +Next.js security headers can be set using the `@nosecone/next` adapter. + +{/* prettier-ignore */} + +
+ +```sh +npm i @nosecone/next +``` + +
+
+ +```sh +pnpm add @nosecone/next +``` + +
+
+ +```sh +yarn add @nosecone/next +``` + +
+
+ +This provides defaults to ensure Next.js applications work in production & +development environments and the `createMiddleware(options?: NoseconeOptions)` +API to create a Next.js middleware that runs on every request. + +import Middleware from "@/snippets/nosecone/reference/next-js/Middleware.mdx"; + + + +If the `Content-Security-Policy` header is specified via middleware, Next.js +will look for a `script-src` that starts with `nonce-` and apply it for each +`