diff --git a/package-lock.json b/package-lock.json
index 96be2b73..ce946248 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,21 +9,21 @@
"version": "0.0.1",
"dependencies": {
"@ai-sdk/openai": "1.0.6",
- "@arcjet/body": "1.0.0-alpha.33",
- "@arcjet/bun": "1.0.0-alpha.33",
- "@arcjet/decorate": "1.0.0-alpha.33",
- "@arcjet/deno": "1.0.0-alpha.33",
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/eslint-config": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/nest": "1.0.0-alpha.33",
- "@arcjet/next": "1.0.0-alpha.33",
- "@arcjet/node": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/redact": "1.0.0-alpha.33",
- "@arcjet/remix": "^1.0.0-alpha.33",
- "@arcjet/sveltekit": "1.0.0-alpha.33",
- "@arcjet/tsconfig": "1.0.0-alpha.33",
+ "@arcjet/body": "1.0.0-alpha.34",
+ "@arcjet/bun": "1.0.0-alpha.34",
+ "@arcjet/decorate": "1.0.0-alpha.34",
+ "@arcjet/deno": "1.0.0-alpha.34",
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/eslint-config": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/nest": "1.0.0-alpha.34",
+ "@arcjet/next": "1.0.0-alpha.34",
+ "@arcjet/node": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/redact": "1.0.0-alpha.34",
+ "@arcjet/remix": "^1.0.0-alpha.34",
+ "@arcjet/sveltekit": "1.0.0-alpha.34",
+ "@arcjet/tsconfig": "1.0.0-alpha.34",
"@astrojs/check": "0.9.4",
"@astrojs/react": "3.6.3",
"@astrojs/starlight": "0.29.2",
@@ -47,7 +47,7 @@
"@remix-run/node": "2.15.0",
"@sveltejs/kit": "2.9.0",
"ai": "4.0.10",
- "arcjet": "1.0.0-alpha.33",
+ "arcjet": "1.0.0-alpha.34",
"astro": "4.16.16",
"astro-embed": "0.9.0",
"astro-robots-txt": "1.0.0",
@@ -209,91 +209,91 @@
}
},
"node_modules/@arcjet/analyze": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/analyze/-/analyze-1.0.0-alpha.33.tgz",
- "integrity": "sha512-FKYZJfAnbwN1MGJruMl11SCRoidezUpKt6iRwd1rLRZZds8NWkHTgBgQ1+K36Eo866OWPj/z2eeUnw/GJolZ+Q==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/analyze/-/analyze-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-dF08Y7usSqFWkgX8MiX9tvGfuQEuH9alVuOJkrFTVZEPPqx7PxvWYbOyXP1U4sW0eIS0A+Dr6XXGcvuMXt8kpA==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/protocol": "1.0.0-alpha.33"
+ "@arcjet/protocol": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/body": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/body/-/body-1.0.0-alpha.33.tgz",
- "integrity": "sha512-utVORbD75edUBzFyDKjwKE6qMEGqrqCn9KHW7NoLqgbqSbHDcBX/VA7EnwtRdjsXh41Ksj73s+WpREeU3HxHlQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/body/-/body-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-ZWvbsWQzpf0NngVSD1asEsDQ5R525VYUt2+3PmfvvuMVrROYzIzkeXLs57VjEcwAdy7iEeItcaAPnSCivDPXkw==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/bun": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/bun/-/bun-1.0.0-alpha.33.tgz",
- "integrity": "sha512-MbXuhQUZe3/PuWrq73DbiekUQpu83v/FdE8a4pirXY2LwrbVE5Onr41yux88EGlXH095Ekwv1+uuw6zEIbaqDA==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/bun/-/bun-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-H/k+ZNmHPFNrexk/l5S8drFt/eJb9BSbgMx2CgYtkpqB7o7LT1dyAegf32nlAB/Fa8VCjMV8usLRZiEIFhSQqQ==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/ip": "1.0.0-alpha.33",
- "@arcjet/logger": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/transport": "1.0.0-alpha.33",
- "arcjet": "1.0.0-alpha.33"
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/ip": "1.0.0-alpha.34",
+ "@arcjet/logger": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/transport": "1.0.0-alpha.34",
+ "arcjet": "1.0.0-alpha.34"
}
},
"node_modules/@arcjet/decorate": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/decorate/-/decorate-1.0.0-alpha.33.tgz",
- "integrity": "sha512-0znEhq7m4+LsWnfPBiu5XecwPn2vfV52RJXv2aqkVMMffEfJQcySZytNKNnJwy1Tsu92JWfl7mKlFE9jZEYsJw==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/decorate/-/decorate-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-KoZk0jm9xdn5KCIL/DfcbVsOa5taAwsSmDQdxk9dNmGTEqzK4C+U4uGl/47RcThoHKoxnIJtdPbGVKgqnAvpvA==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/sprintf": "1.0.0-alpha.33"
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/sprintf": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/deno": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/deno/-/deno-1.0.0-alpha.33.tgz",
- "integrity": "sha512-Tr7vAavi21HyoXu+Z/2g5Z1aeCjqVvkWBulEQtYwxxtcGSELca9sUzPLLYCjkWn1IQPdoD+mC6YS6GXe7k/TOQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/deno/-/deno-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-AS6P5DD4ehrhWoWKWwmlcV+J71XHE0TKnKmuCQZ7SD8Cke5E35ftmC6JdQJR4Swc048kMtzxkZozEBBqHQrtCA==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/ip": "1.0.0-alpha.33",
- "@arcjet/logger": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/transport": "1.0.0-alpha.33",
- "arcjet": "1.0.0-alpha.33"
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/ip": "1.0.0-alpha.34",
+ "@arcjet/logger": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/transport": "1.0.0-alpha.34",
+ "arcjet": "1.0.0-alpha.34"
}
},
"node_modules/@arcjet/duration": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/duration/-/duration-1.0.0-alpha.33.tgz",
- "integrity": "sha512-FZDU9y4vI5AKc37QTZANVzogcMIx33PZ6OuhMTMQgceWtnrDPXvcs/GuIrXK2Pff84mlwNbfchApBA/s6ZujTA==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/duration/-/duration-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-G4VHK7/Kd3+yaBM3r3NUwQKy8oCNHOm/Rmo+GgLiFoU/AIFBILmz4M7SN2PGDXWjkQVYTut0y+tiVSWL/Aae5w==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/env": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/env/-/env-1.0.0-alpha.33.tgz",
- "integrity": "sha512-Xbv0/vYlAdTIHps1n0QApY72Jt2a9YPxx7awaEr/PpGIk9cgSPuz2Hh75RIr+9t80+aE8CneyaPQbWRCXwtgvw==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/env/-/env-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-iUuoybzv0HgCCuk37F7n9iDJq65LyUB3TUNPFLu4xWRsc3/DAbcuBIbuEbNfJMDmo4waPMwh5n3pRUa4IQ8xPw==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/eslint-config": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/eslint-config/-/eslint-config-1.0.0-alpha.33.tgz",
- "integrity": "sha512-2TLFNGHTe47PL3ljxG056uBGH5kIf3i59rNfzt+J0K4L9c0Pzy+RgFRfGrj4vUo/CeX/wMFt0aZ0arpLp4/dVA==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/eslint-config/-/eslint-config-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-5aDE5PNMTMpWsLO4OzpVIup3Gs7o5uksaiOGZIq2VN5zmdOwnBKYJE869zTfCFTVtugGcSVLtRR9sTMbzq53ZA==",
"license": "Apache-2.0",
"dependencies": {
"@typescript-eslint/eslint-plugin": "7.18.0",
@@ -309,49 +309,49 @@
}
},
"node_modules/@arcjet/headers": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/headers/-/headers-1.0.0-alpha.33.tgz",
- "integrity": "sha512-Rg8XA9fZFPbreibuqV6U1t7bLY5fuXrh3OWlBvqXxmHjcYu5h+gyRfgjKtQvRtv2a6lP4h37ljmK0B0k/eLKgQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/headers/-/headers-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-B5YivO0/ibTHWtb//BascF0jbqGsJF/y3uMs9Lh87Z7eFWf6pVhSE06fgunTuzgPrmtsx9dj6/a20msIS4+gUw==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/ip": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/ip/-/ip-1.0.0-alpha.33.tgz",
- "integrity": "sha512-GPZTpsRfwQvPKdxgznQ4mYUZ6rWRjy6L7RR1mHTOv3RBWvRLgcTaPDPAJekgoXD9by0Jz1DwKenNSaDNOmLnnQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/ip/-/ip-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-jeETf8zGqcFxhrkAs4WkVAZzchI5Ssjh1sEjMQyd5zruTKxVylD0e+gntuGwTJjU4g50nYD2AT5oqfxLZ2Cvjg==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/logger": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/logger/-/logger-1.0.0-alpha.33.tgz",
- "integrity": "sha512-vm3cFtPU0nJJjs8eN+MFqsriUH0lQ6zJHDuv0nA7+8QXr9BzRjXv8utPD/3sTDJVA7PL5Fm33puF8MHRZCPdjg==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/logger/-/logger-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-c8ZpPY88cYXgNoe4j4yKVTBZ9bgvFARYN6a2C1w3HsM35MyQtsZwgHyA7Pxkio3YK/OTBiCpW9oZhIXHpfMqdw==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/sprintf": "1.0.0-alpha.33"
+ "@arcjet/sprintf": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/nest": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/nest/-/nest-1.0.0-alpha.33.tgz",
- "integrity": "sha512-uB8+Nn8WjrtDxLHBBJYaxMw6gVdzL8nIoakNFO7ubnGzQEio4Fs2hnrXKTeEJ1JyqAA2vkNLga/1OUDCMdYgHQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/nest/-/nest-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-wa3W680ZWkYzijfKyH5DYEMO2iib7AUueaMMGlEl1snNJ5A8TgaxNVDFG+LryZXrEXJoez6U0lw0ip5aCydwCg==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/body": "1.0.0-alpha.33",
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/ip": "1.0.0-alpha.33",
- "@arcjet/logger": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/transport": "1.0.0-alpha.33",
- "arcjet": "1.0.0-alpha.33"
+ "@arcjet/body": "1.0.0-alpha.34",
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/ip": "1.0.0-alpha.34",
+ "@arcjet/logger": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/transport": "1.0.0-alpha.34",
+ "arcjet": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
@@ -362,18 +362,18 @@
}
},
"node_modules/@arcjet/next": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/next/-/next-1.0.0-alpha.33.tgz",
- "integrity": "sha512-3aKS/TbqHabTAFLUak1emuasrk/6CnXPhNcrQT0zcQiuLh9UUgQnIgH7P4eVJZp7awe5bBq0Zzl7lnFc8ydTzg==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/next/-/next-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-IQReKR3aDWwXI0X2Tet5CoOj2wPHvqbxJ8rXzznpDyvjU5dTx9Dk8QdEMIl8m0zqgJqGVwPOdI72KiruSBgpkw==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/ip": "1.0.0-alpha.33",
- "@arcjet/logger": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/transport": "1.0.0-alpha.33",
- "arcjet": "1.0.0-alpha.33"
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/ip": "1.0.0-alpha.34",
+ "@arcjet/logger": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/transport": "1.0.0-alpha.34",
+ "arcjet": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
@@ -383,28 +383,28 @@
}
},
"node_modules/@arcjet/node": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/node/-/node-1.0.0-alpha.33.tgz",
- "integrity": "sha512-04KfftUJ13AEsYAtC0n/qLmh8+oNJkijRVxfycs2WmN7OeonnQyVo79YyZGyssigXXYSBOw7G7Iq9m+BOwmsOQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/node/-/node-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-7KNlUhF2VuFWyrVeUgLyVOKHls0SntCYcz2CGEldhioqYOcppGEj9ugVNylV2IBep68Yn9xzZ9vD/tX6HnbTvQ==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/body": "1.0.0-alpha.33",
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/ip": "1.0.0-alpha.33",
- "@arcjet/logger": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/transport": "1.0.0-alpha.33",
- "arcjet": "1.0.0-alpha.33"
+ "@arcjet/body": "1.0.0-alpha.34",
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/ip": "1.0.0-alpha.34",
+ "@arcjet/logger": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/transport": "1.0.0-alpha.34",
+ "arcjet": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/protocol": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/protocol/-/protocol-1.0.0-alpha.33.tgz",
- "integrity": "sha512-UPlqcjRWiq6Tj48I6L+N64VYxGqoYMAWhB126wjUFElD2JjwdHh0Qpp5vElOTgQayMAhamUcoMFiNfTkrIQXmQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/protocol/-/protocol-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-9Z+l58ru/cYl/IYzeBW7FX0KwGwjGTz/rM3p10358IYthMrerQqrEBawb+hHpaWrk/SZTOz0Ruk0PTFoYuP90g==",
"license": "Apache-2.0",
"dependencies": {
"@bufbuild/protobuf": "1.10.0",
@@ -416,81 +416,81 @@
}
},
"node_modules/@arcjet/redact": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/redact/-/redact-1.0.0-alpha.33.tgz",
- "integrity": "sha512-apTiSiueZf3ocLHG6co8CLzv/W3AQrG+qxjSn4qATpD+EJpOGFGy3z5GPhMZgQjF4V6x1gxQHn0e93IScu9nYg==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/redact/-/redact-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-esZ68hRKLqzt3vMOzNVT6UqFSCyXgQBKGUPIlTYInmXoJevu0iWMZRZgXncX5iYNY87XUWh+K1Cz4qWSu2HNfw==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/redact-wasm": "1.0.0-alpha.33"
+ "@arcjet/redact-wasm": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/redact-wasm": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/redact-wasm/-/redact-wasm-1.0.0-alpha.33.tgz",
- "integrity": "sha512-1ynlPZQrBaDobnDatObB8cFNwSAEH0bZPqhxWjalPzutHbNW7MMfFz5hRKUF2xIVgGtwg3hm83b/GAWPziypAQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/redact-wasm/-/redact-wasm-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-JPfK54XxyNiSwTyedCB80wD7rQCT+NzcCscLkjikOPUSkCX+PMkPexU5sxlldFK1I+HnrORAgdKS0lgoznuC3A==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/remix": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/remix/-/remix-1.0.0-alpha.33.tgz",
- "integrity": "sha512-JMv9wQCMsVh5kzQYMDhEoQP4BRk5yk87BW6zJSH9Kc0OQPS/ghHWJlkx42b2oVKJCS/SU+pj/N+7ZB1i2CBiaQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/remix/-/remix-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-Edx1FqIfThcCZJ5aViEhYQ/Lff0SYwDjajxnuq9g3WXgHsCahr+oqU63lZ51gSZ5J1MQVBTlhyw1DrXEVfmpuQ==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/ip": "1.0.0-alpha.33",
- "@arcjet/logger": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/transport": "1.0.0-alpha.33",
- "arcjet": "1.0.0-alpha.33"
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/ip": "1.0.0-alpha.34",
+ "@arcjet/logger": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/transport": "1.0.0-alpha.34",
+ "arcjet": "1.0.0-alpha.34"
}
},
"node_modules/@arcjet/runtime": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/runtime/-/runtime-1.0.0-alpha.33.tgz",
- "integrity": "sha512-spepzePStFBdH0siMoXj/sI2KhylluuLGfW+5vy8PDWbNTf/O2LLPu6ManVavPI4vApouSPMOlEYMgiN5LLd8w==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/runtime/-/runtime-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-9sMsJhs+OHw2BXZTaDCQOcI9mTBokeDT1xZ8igryeJ5lkTbzraVdPPcA27kCbRAQpI7JMqnwJ1nlsXn54/KBHQ==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/sprintf": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/sprintf/-/sprintf-1.0.0-alpha.33.tgz",
- "integrity": "sha512-rSqEnBAcjWkYMaz7/jnqmecR24vEEoM59YRjrUPwGxZFrJHmqlFb44OnDFPbrdy9S7s+H2qNCdwncSA1QD3MsQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/sprintf/-/sprintf-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-8jssxHlhG2OZSWWBVMCLXnxExz0q6Vo9cOxrbH04v9kNI/1ncb1BffK6XUyg5WjKflYEvmvkp6NZOwSylPdaCw==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/sveltekit": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/sveltekit/-/sveltekit-1.0.0-alpha.33.tgz",
- "integrity": "sha512-E3bBER4lUBHwO6kkNIN0FsMJilTJgoUgbMVc0VGxzZsPbN9S+ODNSaaQePs8OiIDI+WO1yYRKK4T2YOes4E8tQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/sveltekit/-/sveltekit-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-+bBBq3J6Njz67O3TjmixvaEkkcKS2yIvvKTG0QYum5kxPGeVvokRNQXymlGLwoYvcF9FE5cRdDCfdfcbWDecww==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/ip": "1.0.0-alpha.33",
- "@arcjet/logger": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/transport": "1.0.0-alpha.33",
- "arcjet": "1.0.0-alpha.33"
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/ip": "1.0.0-alpha.34",
+ "@arcjet/logger": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/transport": "1.0.0-alpha.34",
+ "arcjet": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
}
},
"node_modules/@arcjet/transport": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/transport/-/transport-1.0.0-alpha.33.tgz",
- "integrity": "sha512-cG5tLS30CEsSmpuQJn3oyCVlrHeriVrf+TxbFAJ9yd4ohvZGElK1d8NW1EJGu9oFWHL0h53qo90og2IT9zmTNQ==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/transport/-/transport-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-plcUZ75X99CHJsmWY50ZWcukmwIFISZZzKzlFk4cAiEabuAY5s6cCgTdlf2p82unYSV7VtgpQyTM2YURP+A5UQ==",
"license": "Apache-2.0",
"dependencies": {
"@connectrpc/connect-node": "1.6.1",
@@ -501,9 +501,9 @@
}
},
"node_modules/@arcjet/tsconfig": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/@arcjet/tsconfig/-/tsconfig-1.0.0-alpha.33.tgz",
- "integrity": "sha512-NvRysguyOJBu2RqmSMnf1ABP3lv3tPxNGybAYv/NXZ7plAGt5NRHLR4E8Vc9CH3ejfNeK6Ol+Zegj6ovfzByIA==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/@arcjet/tsconfig/-/tsconfig-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-xMT3tpXUfeWDxm0Bso1HaD9VgQ5pm5DHnRwE/tU9Zvv5mTDpluw+MwN/JZz7EMjOHsk9Hr70f1jxz5R4SIBm6A==",
"license": "Apache-2.0",
"engines": {
"node": ">=18"
@@ -5155,16 +5155,16 @@
"license": "ISC"
},
"node_modules/arcjet": {
- "version": "1.0.0-alpha.33",
- "resolved": "https://registry.npmjs.org/arcjet/-/arcjet-1.0.0-alpha.33.tgz",
- "integrity": "sha512-FPNDykCCqs7KO8X/8Bh5S9sg43z9UaBY5nbk8WxHQ5Z6c5eC8WKt1yNc87I+wGbo9TTHPs2ijUWOQ7yBOoennA==",
+ "version": "1.0.0-alpha.34",
+ "resolved": "https://registry.npmjs.org/arcjet/-/arcjet-1.0.0-alpha.34.tgz",
+ "integrity": "sha512-Zwmk8IfG48mM6FYPTOff3MZkAnxLJuANJRoQIsZY+/qDZ8sMJ65D991tybmzUMcZPx8evo8AC0fPN0lOyiJicw==",
"license": "Apache-2.0",
"dependencies": {
- "@arcjet/analyze": "1.0.0-alpha.33",
- "@arcjet/duration": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/runtime": "1.0.0-alpha.33"
+ "@arcjet/analyze": "1.0.0-alpha.34",
+ "@arcjet/duration": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/runtime": "1.0.0-alpha.34"
},
"engines": {
"node": ">=18"
diff --git a/package.json b/package.json
index 43fa5819..70c239e6 100644
--- a/package.json
+++ b/package.json
@@ -11,21 +11,21 @@
},
"dependencies": {
"@ai-sdk/openai": "1.0.6",
- "@arcjet/body": "1.0.0-alpha.33",
- "@arcjet/bun": "1.0.0-alpha.33",
- "@arcjet/decorate": "1.0.0-alpha.33",
- "@arcjet/deno": "1.0.0-alpha.33",
- "@arcjet/env": "1.0.0-alpha.33",
- "@arcjet/eslint-config": "1.0.0-alpha.33",
- "@arcjet/headers": "1.0.0-alpha.33",
- "@arcjet/nest": "1.0.0-alpha.33",
- "@arcjet/next": "1.0.0-alpha.33",
- "@arcjet/node": "1.0.0-alpha.33",
- "@arcjet/protocol": "1.0.0-alpha.33",
- "@arcjet/redact": "1.0.0-alpha.33",
- "@arcjet/remix": "^1.0.0-alpha.33",
- "@arcjet/sveltekit": "1.0.0-alpha.33",
- "@arcjet/tsconfig": "1.0.0-alpha.33",
+ "@arcjet/body": "1.0.0-alpha.34",
+ "@arcjet/bun": "1.0.0-alpha.34",
+ "@arcjet/decorate": "1.0.0-alpha.34",
+ "@arcjet/deno": "1.0.0-alpha.34",
+ "@arcjet/env": "1.0.0-alpha.34",
+ "@arcjet/eslint-config": "1.0.0-alpha.34",
+ "@arcjet/headers": "1.0.0-alpha.34",
+ "@arcjet/nest": "1.0.0-alpha.34",
+ "@arcjet/next": "1.0.0-alpha.34",
+ "@arcjet/node": "1.0.0-alpha.34",
+ "@arcjet/protocol": "1.0.0-alpha.34",
+ "@arcjet/redact": "1.0.0-alpha.34",
+ "@arcjet/remix": "^1.0.0-alpha.34",
+ "@arcjet/sveltekit": "1.0.0-alpha.34",
+ "@arcjet/tsconfig": "1.0.0-alpha.34",
"@astrojs/check": "0.9.4",
"@astrojs/react": "3.6.3",
"@astrojs/starlight": "0.29.2",
@@ -49,7 +49,7 @@
"@remix-run/node": "2.15.0",
"@sveltejs/kit": "2.9.0",
"ai": "4.0.10",
- "arcjet": "1.0.0-alpha.33",
+ "arcjet": "1.0.0-alpha.34",
"astro": "4.16.16",
"astro-embed": "0.9.0",
"astro-robots-txt": "1.0.0",
diff --git a/src/content/docs/reference/bun.mdx b/src/content/docs/reference/bun.mdx
index 8db85fb1..bab214d0 100644
--- a/src/content/docs/reference/bun.mdx
+++ b/src/content/docs/reference/bun.mdx
@@ -18,6 +18,7 @@ import MultipleRulesTS from "/src/snippets/reference/bun/MultipleRules.ts?raw";
import MultipleRulesJS from "/src/snippets/reference/bun/MultipleRules.js?raw";
import LoggerTS from "/src/snippets/reference/bun/Logger.ts?raw";
import LoggerJS from "/src/snippets/reference/bun/Logger.js?raw";
+import ProxiesTS from "/src/snippets/reference/bun/Proxies.ts?raw";
import ProtectTS from "/src/snippets/reference/bun/Protect.ts?raw";
import ProtectJS from "/src/snippets/reference/bun/Protect.js?raw";
import DecisionLogTS from "/src/snippets/reference/bun/DecisionLog.ts?raw";
@@ -76,6 +77,11 @@ The optional fields are:
- `characteristics` (`string[]`) - A list of
[characteristics](/architecture#built-in-characteristics) to be used to
uniquely identify clients.
+- `proxies` (`string[]`) - A list of one or more trusted proxies. These
+ addresses will be excluded when Arcjet is determining the client IP address.
+ This is useful if you are behind a load balancer or proxy that sets the client
+ IP address in a header. See [Load balancers &
+ proxies](#load-balancers--proxies) below for an example.
@@ -153,7 +159,7 @@ execution ordering is automatically optimized for performance.
-## Environment variables
+### Environment variables
- `ARCJET_BASE_URL` - Will override the decision API which the SDK communicates
with. This defaults to `https://decide.arcjet.com` and should only be changed
@@ -193,6 +199,40 @@ print in development:
+### Load balancers & proxies
+
+If your application is behind a load balancer, Arcjet will only see the IP
+address of the load balancer and not the real client IP address.
+
+To fix this, most load balancers will set the `X-Forwarded-For` header with the
+real client IP address plus a list of proxies that the request has passed
+through.
+
+The problem with is that the `X-Forwarded-For` header can be spoofed by the
+client, so you should only trust it if you are sure that the load balancer is
+setting it correctly. See [the MDN
+docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
+for more details.
+
+You can configure Arcjet to trust IP addresses in the `X-Forwarded-For` header
+by setting the `proxies` field in the configuration. This should be a list of
+the IP addresses of your load balancers to be removed, so that the last IP
+address in the list is the real client IP address.
+
+#### Example
+
+For example, if the load balancer is at `100.100.100.100` and the client IP
+address is `192.168.1.1`, the `X-Forwarded-For` header will be:
+
+```http
+X-Forwarded-For: 192.168.1.1, 100.100.100.100
+```
+
+You should set the `proxies` field to `["100.100.100.100"]` so Arcjet will use
+`192.168.1.1` as the client IP address.
+
+
+
## Protect
Arcjet provides a single `protect` function that is used to execute your
diff --git a/src/content/docs/reference/nestjs.mdx b/src/content/docs/reference/nestjs.mdx
index fc18c83c..3b4899e4 100644
--- a/src/content/docs/reference/nestjs.mdx
+++ b/src/content/docs/reference/nestjs.mdx
@@ -10,6 +10,7 @@ import SDKVersionNestjs from "/src/components/SDKVersionNestjs.astro";
import WhatIsArcjet from "/src/components/WhatIsArcjet.astro";
import LoggerTS from "/src/snippets/reference/nestjs/ClientLogger.ts?raw";
+import ProxiesTS from "/src/snippets/reference/nestjs/Proxies.ts?raw";
import ConfigurationTS from "/src/snippets/reference/nestjs/Configuration.ts?raw";
import IPLocationTS from "/src/snippets/reference/nestjs/IPLocation.ts?raw";
import NodeVersions from "/src/snippets/reference/node-versions.mdx";
@@ -76,6 +77,11 @@ The optional fields are:
- `characteristics` (`string[]`) - A list of
[characteristics](/architecture#built-in-characteristics) to be used to
uniquely identify clients.
+- `proxies` (`string[]`) - A list of one or more trusted proxies. These
+ addresses will be excluded when Arcjet is determining the client IP address.
+ This is useful if you are behind a load balancer or proxy that sets the client
+ IP address in a header. See [Load balancers &
+ proxies](#load-balancers--proxies) below for an example.
@@ -123,6 +129,40 @@ controllers.
+### Load balancers & proxies
+
+If your application is behind a load balancer, Arcjet will only see the IP
+address of the load balancer and not the real client IP address.
+
+To fix this, most load balancers will set the `X-Forwarded-For` header with the
+real client IP address plus a list of proxies that the request has passed
+through.
+
+The problem with is that the `X-Forwarded-For` header can be spoofed by the
+client, so you should only trust it if you are sure that the load balancer is
+setting it correctly. See [the MDN
+docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
+for more details.
+
+You can configure Arcjet to trust IP addresses in the `X-Forwarded-For` header
+by setting the `proxies` field in the configuration. This should be a list of
+the IP addresses of your load balancers to be removed, so that the last IP
+address in the list is the real client IP address.
+
+#### Example
+
+For example, if the load balancer is at `100.100.100.100` and the client IP
+address is `192.168.1.1`, the `X-Forwarded-For` header will be:
+
+```http
+X-Forwarded-For: 192.168.1.1, 100.100.100.100
+```
+
+You should set the `proxies` field to `["100.100.100.100"]` so Arcjet will use
+`192.168.1.1` as the client IP address.
+
+
+
## Decision
Arcjet can be integrated into NestJS in several places using NestJS
diff --git a/src/content/docs/reference/nextjs.mdx b/src/content/docs/reference/nextjs.mdx
index 9f9e27e6..e36eed30 100644
--- a/src/content/docs/reference/nextjs.mdx
+++ b/src/content/docs/reference/nextjs.mdx
@@ -18,6 +18,7 @@ import MultipleRulesTS from "/src/snippets/reference/nextjs/MultipleRules.ts?raw
import MultipleRulesJS from "/src/snippets/reference/nextjs/MultipleRules.js?raw";
import LoggerTS from "/src/snippets/reference/nextjs/Logger.ts?raw";
import LoggerJS from "/src/snippets/reference/nextjs/Logger.js?raw";
+import ProxiesTS from "/src/snippets/reference/nextjs/Proxies.ts?raw";
import ClientOverrideTS from "/src/snippets/reference/nextjs/ClientOverride.ts?raw";
import ClientOverrideJS from "/src/snippets/reference/nextjs/ClientOverride.js?raw";
import ProtectAppTS from "/src/snippets/reference/nextjs/ProtectApp.ts?raw";
@@ -107,6 +108,11 @@ The optional fields are:
- `characteristics` (`string[]`) - A list of
[characteristics](/architecture#built-in-characteristics) to be used to
uniquely identify clients.
+- `proxies` (`string[]`) - A list of one or more trusted proxies. These
+ addresses will be excluded when Arcjet is determining the client IP address.
+ This is useful if you are behind a load balancer or proxy that sets the client
+ IP address in a header. See [Load balancers &
+ proxies](#load-balancers--proxies) below for an example.
@@ -244,6 +250,40 @@ const nextConfig = {
module.exports = nextConfig;
```
+### Load balancers & proxies
+
+If your application is behind a load balancer, Arcjet will only see the IP
+address of the load balancer and not the real client IP address.
+
+To fix this, most load balancers will set the `X-Forwarded-For` header with the
+real client IP address plus a list of proxies that the request has passed
+through.
+
+The problem with is that the `X-Forwarded-For` header can be spoofed by the
+client, so you should only trust it if you are sure that the load balancer is
+setting it correctly. See [the MDN
+docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
+for more details.
+
+You can configure Arcjet to trust IP addresses in the `X-Forwarded-For` header
+by setting the `proxies` field in the configuration. This should be a list of
+the IP addresses of your load balancers to be removed, so that the last IP
+address in the list is the real client IP address.
+
+#### Example
+
+For example, if the load balancer is at `100.100.100.100` and the client IP
+address is `192.168.1.1`, the `X-Forwarded-For` header will be:
+
+```http
+X-Forwarded-For: 192.168.1.1, 100.100.100.100
+```
+
+You should set the `proxies` field to `["100.100.100.100"]` so Arcjet will use
+`192.168.1.1` as the client IP address.
+
+
+
## Protect
Arcjet provides a single `protect` function that is used to execute your
diff --git a/src/content/docs/reference/nodejs.mdx b/src/content/docs/reference/nodejs.mdx
index 096e4ccf..b1b6be56 100644
--- a/src/content/docs/reference/nodejs.mdx
+++ b/src/content/docs/reference/nodejs.mdx
@@ -12,6 +12,7 @@ import ProtectTS from "/src/snippets/reference/nodejs/Protect.ts?raw";
import ProtectJS from "/src/snippets/reference/nodejs/Protect.js?raw";
import LoggerTS from "/src/snippets/reference/nodejs/Logger.ts?raw";
import LoggerJS from "/src/snippets/reference/nodejs/Logger.js?raw";
+import ProxiesTS from "/src/snippets/reference/nodejs/Proxies.ts?raw";
import IPLocationTS from "/src/snippets/reference/nodejs/IPLocation.ts?raw";
import IPLocationJS from "/src/snippets/reference/nodejs/IPLocation.js?raw";
import WithRuleTS from "/src/snippets/reference/nodejs/WithRule.ts?raw";
@@ -84,6 +85,11 @@ The optional fields are:
- `characteristics` (`string[]`) - A list of
[characteristics](/architecture#built-in-characteristics) to be used to
uniquely identify clients.
+- `proxies` (`string[]`) - A list of one or more trusted proxies. These
+ addresses will be excluded when Arcjet is determining the client IP address.
+ This is useful if you are behind a load balancer or proxy that sets the client
+ IP address in a header. See [Load balancers &
+ proxies](#load-balancers--proxies) below for an example.
@@ -174,6 +180,40 @@ print in development:
+### Load balancers & proxies
+
+If your application is behind a load balancer, Arcjet will only see the IP
+address of the load balancer and not the real client IP address.
+
+To fix this, most load balancers will set the `X-Forwarded-For` header with the
+real client IP address plus a list of proxies that the request has passed
+through.
+
+The problem with is that the `X-Forwarded-For` header can be spoofed by the
+client, so you should only trust it if you are sure that the load balancer is
+setting it correctly. See [the MDN
+docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
+for more details.
+
+You can configure Arcjet to trust IP addresses in the `X-Forwarded-For` header
+by setting the `proxies` field in the configuration. This should be a list of
+the IP addresses of your load balancers to be removed, so that the last IP
+address in the list is the real client IP address.
+
+#### Example
+
+For example, if the load balancer is at `100.100.100.100` and the client IP
+address is `192.168.1.1`, the `X-Forwarded-For` header will be:
+
+```http
+X-Forwarded-For: 192.168.1.1, 100.100.100.100
+```
+
+You should set the `proxies` field to `["100.100.100.100"]` so Arcjet will use
+`192.168.1.1` as the client IP address.
+
+
+
## Protect
Arcjet provides a single `protect` function that is used to execute your
diff --git a/src/content/docs/reference/remix.mdx b/src/content/docs/reference/remix.mdx
index 9330a10a..05ec3df8 100644
--- a/src/content/docs/reference/remix.mdx
+++ b/src/content/docs/reference/remix.mdx
@@ -12,6 +12,7 @@ import ProtectTS from "/src/snippets/reference/remix/Protect.ts?raw";
import ProtectJS from "/src/snippets/reference/remix/Protect.js?raw";
import LoggerTS from "/src/snippets/reference/remix/Logger.ts?raw";
import LoggerJS from "/src/snippets/reference/remix/Logger.js?raw";
+import ProxiesTS from "/src/snippets/reference/remix/Proxies.ts?raw";
import IPLocationTS from "/src/snippets/reference/remix/IPLocation.ts?raw";
import IPLocationJS from "/src/snippets/reference/remix/IPLocation.js?raw";
import WithRuleTS from "/src/snippets/reference/remix/WithRule.ts?raw";
@@ -84,6 +85,11 @@ The optional fields are:
- `characteristics` (`string[]`) - A list of
[characteristics](/architecture#built-in-characteristics) to be used to
uniquely identify clients.
+- `proxies` (`string[]`) - A list of one or more trusted proxies. These
+ addresses will be excluded when Arcjet is determining the client IP address.
+ This is useful if you are behind a load balancer or proxy that sets the client
+ IP address in a header. See [Load balancers &
+ proxies](#load-balancers--proxies) below for an example.
@@ -174,6 +180,40 @@ print in development:
+### Load balancers & proxies
+
+If your application is behind a load balancer, Arcjet will only see the IP
+address of the load balancer and not the real client IP address.
+
+To fix this, most load balancers will set the `X-Forwarded-For` header with the
+real client IP address plus a list of proxies that the request has passed
+through.
+
+The problem with is that the `X-Forwarded-For` header can be spoofed by the
+client, so you should only trust it if you are sure that the load balancer is
+setting it correctly. See [the MDN
+docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
+for more details.
+
+You can configure Arcjet to trust IP addresses in the `X-Forwarded-For` header
+by setting the `proxies` field in the configuration. This should be a list of
+the IP addresses of your load balancers to be removed, so that the last IP
+address in the list is the real client IP address.
+
+#### Example
+
+For example, if the load balancer is at `100.100.100.100` and the client IP
+address is `192.168.1.1`, the `X-Forwarded-For` header will be:
+
+```http
+X-Forwarded-For: 192.168.1.1, 100.100.100.100
+```
+
+You should set the `proxies` field to `["100.100.100.100"]` so Arcjet will use
+`192.168.1.1` as the client IP address.
+
+
+
## Protect
Arcjet provides a single `protect` function that is used to execute your
diff --git a/src/content/docs/reference/sveltekit.mdx b/src/content/docs/reference/sveltekit.mdx
index ca0e3b1b..735d74bf 100644
--- a/src/content/docs/reference/sveltekit.mdx
+++ b/src/content/docs/reference/sveltekit.mdx
@@ -20,6 +20,7 @@ import ProtectTS from "/src/snippets/reference/sveltekit/Protect.ts?raw";
import ProtectJS from "/src/snippets/reference/sveltekit/Protect.js?raw";
import LoggerTS from "/src/snippets/reference/sveltekit/Logger.ts?raw";
import LoggerJS from "/src/snippets/reference/sveltekit/Logger.js?raw";
+import ProxiesTS from "/src/snippets/reference/sveltekit/Proxies.ts?raw";
import DecisionLogTS from "/src/snippets/reference/sveltekit/DecisionLog.ts?raw";
import DecisionLogJS from "/src/snippets/reference/sveltekit/DecisionLog.js?raw";
import ErrorHandlingTS from "/src/snippets/reference/sveltekit/ErrorHandling.ts?raw";
@@ -92,6 +93,11 @@ The optional fields are:
- `characteristics` (`string[]`) - A list of
[characteristics](/architecture#built-in-characteristics) to be used to
uniquely identify clients.
+- `proxies` (`string[]`) - A list of one or more trusted proxies. These
+ addresses will be excluded when Arcjet is determining the client IP address.
+ This is useful if you are behind a load balancer or proxy that sets the client
+ IP address in a header. See [Load balancers &
+ proxies](#load-balancers--proxies) below for an example.
@@ -212,6 +218,40 @@ print in development:
+### Load balancers & proxies
+
+If your application is behind a load balancer, Arcjet will only see the IP
+address of the load balancer and not the real client IP address.
+
+To fix this, most load balancers will set the `X-Forwarded-For` header with the
+real client IP address plus a list of proxies that the request has passed
+through.
+
+The problem with is that the `X-Forwarded-For` header can be spoofed by the
+client, so you should only trust it if you are sure that the load balancer is
+setting it correctly. See [the MDN
+docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For)
+for more details.
+
+You can configure Arcjet to trust IP addresses in the `X-Forwarded-For` header
+by setting the `proxies` field in the configuration. This should be a list of
+the IP addresses of your load balancers to be removed, so that the last IP
+address in the list is the real client IP address.
+
+#### Example
+
+For example, if the load balancer is at `100.100.100.100` and the client IP
+address is `192.168.1.1`, the `X-Forwarded-For` header will be:
+
+```http
+X-Forwarded-For: 192.168.1.1, 100.100.100.100
+```
+
+You should set the `proxies` field to `["100.100.100.100"]` so Arcjet will use
+`192.168.1.1` as the client IP address.
+
+
+
## Protect
Arcjet provides a single `protect` function that is used to execute your
diff --git a/src/snippets/bot-protection/reference/nestjs/GlobalGuard.ts b/src/snippets/bot-protection/reference/nestjs/GlobalGuard.ts
index 665eda30..abbbbcd6 100644
--- a/src/snippets/bot-protection/reference/nestjs/GlobalGuard.ts
+++ b/src/snippets/bot-protection/reference/nestjs/GlobalGuard.ts
@@ -1,8 +1,6 @@
import { ArcjetModule, detectBot } from "@arcjet/nest";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
-//import { AppController } from './app.controller.js';
-//import { AppService } from './app.service.js';
@Module({
imports: [
@@ -31,7 +29,5 @@ import { ConfigModule } from "@nestjs/config";
}),
// ... other modules
],
- //controllers: [AppController],
- //providers: [AppService],
})
export class AppModule {}
diff --git a/src/snippets/rate-limiting/reference/nestjs/ByAPIKeyHeader.ts b/src/snippets/rate-limiting/reference/nestjs/ByAPIKeyHeader.ts
index 73cb46c6..02a030ec 100644
--- a/src/snippets/rate-limiting/reference/nestjs/ByAPIKeyHeader.ts
+++ b/src/snippets/rate-limiting/reference/nestjs/ByAPIKeyHeader.ts
@@ -1,8 +1,6 @@
import { ArcjetModule, fixedWindow } from "@arcjet/nest";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
-//import { AppController } from './app.controller.js';
-//import { AppService } from './app.service.js';
@Module({
imports: [
@@ -24,7 +22,5 @@ import { ConfigModule } from "@nestjs/config";
}),
// ... other modules
],
- //controllers: [AppController],
- //providers: [AppService],
})
export class AppModule {}
diff --git a/src/snippets/rate-limiting/reference/nestjs/ByIP.ts b/src/snippets/rate-limiting/reference/nestjs/ByIP.ts
index 6174f267..844b9fa5 100644
--- a/src/snippets/rate-limiting/reference/nestjs/ByIP.ts
+++ b/src/snippets/rate-limiting/reference/nestjs/ByIP.ts
@@ -1,8 +1,6 @@
import { ArcjetModule, fixedWindow } from "@arcjet/nest";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
-//import { AppController } from './app.controller.js';
-//import { AppService } from './app.service.js';
@Module({
imports: [
@@ -25,7 +23,5 @@ import { ConfigModule } from "@nestjs/config";
}),
// ... other modules
],
- //controllers: [AppController],
- //providers: [AppService],
})
export class AppModule {}
diff --git a/src/snippets/rate-limiting/reference/nestjs/GlobalGuard.ts b/src/snippets/rate-limiting/reference/nestjs/GlobalGuard.ts
index e5127a03..4d29c9a2 100644
--- a/src/snippets/rate-limiting/reference/nestjs/GlobalGuard.ts
+++ b/src/snippets/rate-limiting/reference/nestjs/GlobalGuard.ts
@@ -1,8 +1,6 @@
import { ArcjetModule, fixedWindow } from "@arcjet/nest";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
-//import { AppController } from './app.controller.js';
-//import { AppService } from './app.service.js';
@Module({
imports: [
@@ -24,7 +22,5 @@ import { ConfigModule } from "@nestjs/config";
}),
// ... other modules
],
- //controllers: [AppController],
- //providers: [AppService],
})
export class AppModule {}
diff --git a/src/snippets/reference/bun/Proxies.ts b/src/snippets/reference/bun/Proxies.ts
new file mode 100644
index 00000000..0469c2f5
--- /dev/null
+++ b/src/snippets/reference/bun/Proxies.ts
@@ -0,0 +1,8 @@
+import arcjet from "@arcjet/bun";
+import { env } from "bun";
+
+const aj = arcjet({
+ key: env.ARCJET_KEY!,
+ rules: [],
+ proxies: ["100.100.100.100"],
+});
diff --git a/src/snippets/reference/nestjs/Configuration.ts b/src/snippets/reference/nestjs/Configuration.ts
index 13f8258e..e8ff316f 100644
--- a/src/snippets/reference/nestjs/Configuration.ts
+++ b/src/snippets/reference/nestjs/Configuration.ts
@@ -1,8 +1,6 @@
import { ArcjetModule } from "@arcjet/nest";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
-//import { AppController } from './app.controller.js';
-//import { AppService } from './app.service.js';
@Module({
imports: [
@@ -19,7 +17,5 @@ import { ConfigModule } from "@nestjs/config";
}),
// ... other modules
],
- //controllers: [AppController],
- //providers: [AppService],
})
export class AppModule {}
diff --git a/src/snippets/reference/nestjs/Proxies.ts b/src/snippets/reference/nestjs/Proxies.ts
new file mode 100644
index 00000000..90eeddd3
--- /dev/null
+++ b/src/snippets/reference/nestjs/Proxies.ts
@@ -0,0 +1,22 @@
+import { ArcjetModule } from "@arcjet/nest";
+import { Module } from "@nestjs/common";
+import { ConfigModule } from "@nestjs/config";
+
+@Module({
+ imports: [
+ ConfigModule.forRoot({
+ isGlobal: true,
+ envFilePath: ".env.local",
+ }),
+ ArcjetModule.forRoot({
+ isGlobal: true,
+ key: process.env.ARCJET_KEY!,
+ rules: [
+ // Rules set here will apply to every request
+ ],
+ proxies: ["100.100.100.100"],
+ }),
+ // ... other modules
+ ],
+})
+export class AppModule {}
diff --git a/src/snippets/reference/nextjs/Proxies.ts b/src/snippets/reference/nextjs/Proxies.ts
new file mode 100644
index 00000000..bfb0d749
--- /dev/null
+++ b/src/snippets/reference/nextjs/Proxies.ts
@@ -0,0 +1,7 @@
+import arcjet from "@arcjet/next";
+
+const aj = arcjet({
+ key: process.env.ARCJET_KEY!,
+ rules: [],
+ proxies: ["100.100.100.100"],
+});
diff --git a/src/snippets/reference/nodejs/Proxies.ts b/src/snippets/reference/nodejs/Proxies.ts
new file mode 100644
index 00000000..e2ba8c91
--- /dev/null
+++ b/src/snippets/reference/nodejs/Proxies.ts
@@ -0,0 +1,7 @@
+import arcjet from "@arcjet/node";
+
+const aj = arcjet({
+ key: process.env.ARCJET_KEY!,
+ rules: [],
+ proxies: ["100.100.100.100"],
+});
diff --git a/src/snippets/reference/remix/Proxies.ts b/src/snippets/reference/remix/Proxies.ts
new file mode 100644
index 00000000..c852c619
--- /dev/null
+++ b/src/snippets/reference/remix/Proxies.ts
@@ -0,0 +1,7 @@
+import arcjet from "@arcjet/remix";
+
+const aj = arcjet({
+ key: process.env.ARCJET_KEY!,
+ rules: [],
+ proxies: ["100.100.100.100"],
+});
diff --git a/src/snippets/reference/sveltekit/Proxies.ts b/src/snippets/reference/sveltekit/Proxies.ts
new file mode 100644
index 00000000..33cf3d39
--- /dev/null
+++ b/src/snippets/reference/sveltekit/Proxies.ts
@@ -0,0 +1,8 @@
+import { env } from "$env/dynamic/private";
+import arcjet from "@arcjet/sveltekit";
+
+const aj = arcjet({
+ key: env.ARCJET_KEY!,
+ rules: [],
+ proxies: ["100.100.100.100"],
+});
diff --git a/src/snippets/sensitive-info/reference/nestjs/GlobalGuard.ts b/src/snippets/sensitive-info/reference/nestjs/GlobalGuard.ts
index c5b728d6..a158a561 100644
--- a/src/snippets/sensitive-info/reference/nestjs/GlobalGuard.ts
+++ b/src/snippets/sensitive-info/reference/nestjs/GlobalGuard.ts
@@ -1,8 +1,6 @@
import { ArcjetModule, sensitiveInfo } from "@arcjet/nest";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
-//import { AppController } from './app.controller.js';
-//import { AppService } from './app.service.js';
@Module({
imports: [
@@ -24,7 +22,5 @@ import { ConfigModule } from "@nestjs/config";
}),
// ... other modules
],
- //controllers: [AppController],
- //providers: [AppService],
})
export class AppModule {}
diff --git a/src/snippets/shield/reference/nestjs/GlobalGuard.ts b/src/snippets/shield/reference/nestjs/GlobalGuard.ts
index e2a49f0e..b0e738c6 100644
--- a/src/snippets/shield/reference/nestjs/GlobalGuard.ts
+++ b/src/snippets/shield/reference/nestjs/GlobalGuard.ts
@@ -1,8 +1,6 @@
import { ArcjetModule, shield } from "@arcjet/nest";
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
-//import { AppController } from './app.controller.js';
-//import { AppService } from './app.service.js';
@Module({
imports: [
@@ -22,7 +20,5 @@ import { ConfigModule } from "@nestjs/config";
}),
// ... other modules
],
- //controllers: [AppController],
- //providers: [AppService],
})
export class AppModule {}