feat(examples): migrate unique examples from arcjet-js - #193
Conversation
Consolidates the remaining unique examples from the `arcjet/arcjet-js` `examples/` directory into this repository, rebuilt to the canonical example pattern (canonical metadata, README, Dockerfile, compose.yaml, devcontainer, LICENSE) with Arcjet packages pinned to published versions. Examples added: - bun — canonical Bun runtime example (mirrors the Deno example) - express-newman — testing Arcjet-protected Express routes with Newman - nextjs-bot-categories — advanced bot category allow/deny + filtering - react-router-middleware — React Router v8 middleware pattern - nextjs-ai-agent — Arcjet Guard AI agent guardrails - nextjs-sensitive-info — sensitive info detection incl. Rampart NER backend - nextjs-guard-policy — remotely-configured Guard policy for AI tool calls - node-guard-policy — Guard policy on a plain Node.js server The first four are wired into the root `compose.yaml` and the Docker build CI matrix. The Guard/AI examples are standalone (they need an AI gateway key, dashboard policy config, or a native NER backend) and are excluded from the default compose/CI run. Note: nextjs-guard-policy and node-guard-policy depend on the Arcjet Guard remote-policy API which is not yet published to npm; they are pinned to 1.10.0-rc.0 and documented as not building until that API ships. nextjs-ai-agent is pinned to 1.10.0-rc.0 (first release with the agent guardrail API) and nextjs-sensitive-info to 1.9.1 (Rampart's earliest release). All examples are registered in scripts/prepare-to-publish.ts for publishing to their own repositories. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub. |
|
All alerts resolved. Learn more about Socket for GitHub. This PR previously contained dependency changes with security issues that have been resolved, removed, or ignored. Ignoring alerts on:
|
|
@SocketSecurity ignore-all |
There was a problem hiding this comment.
Arcjet Review — 🔴 High Risk
Decision: Needs Review
Rationale: This PR adds many new runnable examples, new public API endpoints, multiple new dependency sets, Dockerfiles, root compose wiring, and CI matrix changes. Multiple escalation triggers fire, and the diff is far above the automated review size threshold. The most immediate correctness concern is that several Dockerfiles and READMEs use npm ci, but the diff does not include corresponding lockfiles for the new npm examples, so the newly added Docker CI matrix entries are likely to fail. Security review also found public AI/model-triggering endpoints without authentication, rate limiting, or request-size limits, plus demo endpoints exposing policy/tool trace details and bot-detection internals. These may be acceptable for isolated examples, but they need human review before merge.
Summary of Changes
Adds eight Arcjet examples for Bun, Express/Newman, Next.js bot categories, React Router middleware, AI agent guardrails, sensitive info detection, and Guard policy demos; wires four into root compose and Docker build CI; updates README and publishing script registrations.
Escalation Triggers
- Dependency Changes: The PR adds multiple new
package.jsonfiles with new runtime, AI, Arcjet, Next.js, React Router, Rampart, Newman, and workflow dependencies. - CI/CD Pipeline: The PR modifies
.github/workflows/docker-build.ymland adds many Dockerfiles/devcontainer Dockerfiles. - Authentication & Authorization: The diff introduces public endpoints handling API keys, AI gateway access, policy actors, guard decisions, and token/rate-limit terminology; content trigger patterns matched and the authorization posture needs review.
Security Flags
- [MEDIUM] Abuse prevention / access control (examples/nextjs-ai-agent/app/api/agent/route.ts:34): New AI/model-triggering endpoints can be called anonymously and do not apply request rate limiting, authentication, or input length limits before starting workflows or model calls. If deployed publicly, this can be abused to consume AI gateway credits or create background workload.
- [LOW] Data exposure (examples/nextjs-guard-policy/app/api/context/route.ts:12): The Guard policy demo returns full demo client records and later returns tool traces/results to the browser. The data appears synthetic and the README warns this is a demo, but hosted versions should avoid returning raw records, tool inputs, tool outputs, prompts, or sensitive-looking fields to untrusted clients.
- [LOW] Security information disclosure (examples/nextjs-bot-categories/app/api/arcjet/route.ts:18): The bot-categories API returns headers that disclose which bot identifiers were allowed or denied. The inline comment correctly warns that this can aid evasion; reviewers should confirm this is acceptable for a public example or gate it behind a debug/demo mode.
- [LOW] Supply chain (examples/bun/.devcontainer/Dockerfile:4): The Bun devcontainer installs Bun by piping a remote install script into
bashwithout pinning or verifying the downloaded script. This is lower risk for a devcontainer, but it is still a supply-chain pattern reviewers should explicitly accept or replace with a pinned package/image.
Review Focus Areas
- Do all new npm-based examples that use
npm ciinclude committedpackage-lock.jsonfiles, or should the Dockerfiles/READMEs use a different install command?
npm cirequires a lockfile. The new CI matrix builds examples such asexpress-newman,nextjs-bot-categories, andreact-router-middleware; without lockfiles those Docker builds will fail. - Does the React Router dev server actually listen on the container port exposed by compose?
The README points to port 5173, the Dockerfile exposes 4321, and compose exposes 3000. This mismatch can make the newly root-included compose service unreachable. - Should the AI examples add explicit rate limiting, authentication guidance, and request body/field length limits before starting workflows or model calls?
The endpoint triggers background workflow/model work from unauthenticated user input; examples are often copied into production. - Can the Guard policy demo return only non-sensitive fixture labels/context instead of complete records, and keep raw trace output clearly demo-only?
Even synthetic sensitive-looking records and raw tool traces normalize returning data that production systems should not expose. - Please verify the
ArcjetAgentContextpassed into the workflow is fully serializable and replay-safe under the installed Workflow DevKit version.
Workflow inputs and step return values must be serializable for durable replay; passing non-plain context objects can break workflow execution. - Please review new dependency versions, overrides, native Rampart dependencies, pre-release Arcjet Guard packages, and any semver ranges before merge.
This PR introduces many dependencies and some pre-release/native components. Lockfiles and exact versions are important for reproducible example publishing and CI.
Notes
The diff is far above the 1000-line automated review threshold, so this review should be treated as a high-level risk scan rather than exhaustive validation. Human reviewers should verify generated/example files, lockfiles, CI behavior, and the intended demo-versus-production security posture.
Path filtering: 7 files excluded by ignore paths. 137 of 144 files included in review.
Review: 97442b64 | Model: openai/gpt-5.5 | Powered by Arcjet Review
| EXPOSE 8080 | ||
|
|
||
| COPY package*.json ./ | ||
| RUN npm ci |
There was a problem hiding this comment.
Please add a committed package-lock.json for this example or change the install command. npm ci fails when no lockfile is present, and this example is now in the Docker build CI matrix.
| EXPOSE 3000 | ||
|
|
||
| COPY package*.json ./ | ||
| RUN npm ci |
There was a problem hiding this comment.
Please add the corresponding package-lock.json or avoid npm ci here. This example is included in the new Docker CI matrix, so a missing lockfile will break the CI build.
| EXPOSE 4321 | ||
|
|
||
| COPY package*.json ./ | ||
| RUN npm ci |
There was a problem hiding this comment.
Please add a lockfile or use an install command that does not require one. The Dockerfile currently uses npm ci, but no package-lock.json is shown in the diff.
| labels: | ||
| - dev.orbstack.domains=react-router-middleware.arcjet-examples.orb.local | ||
| ports: | ||
| - 3000 |
There was a problem hiding this comment.
Please align this exposed port with the actual dev-server port. The README says to open localhost:5173, while this compose file exposes container port 3000 and the Dockerfile exposes 4321.
| }), | ||
| }); | ||
|
|
||
| const run = await start(supportAgentWorkflow, [{ question, ctx }]); |
There was a problem hiding this comment.
Please add abuse controls before starting the workflow, such as an Arcjet rate limit and a maximum question length. As written, an unauthenticated caller can trigger background AI work repeatedly.
| const headers = new Headers(); | ||
| if (decision.reason.isBot()) { | ||
| // WARNING: This is illustrative! Don't share this metadata with users; | ||
| // otherwise they may use it to subvert bot detection! |
There was a problem hiding this comment.
Can you gate these diagnostic bot headers behind an explicit demo/debug flag or remove them from the default response? Exposing allow/deny classifications can help clients tune bot evasion.
|
|
||
| export function GET() { | ||
| return NextResponse.json({ | ||
| clients, |
There was a problem hiding this comment.
Please consider returning only display labels and scenario metadata from this endpoint, or add a stronger code-level guard/comment explaining that the full records are synthetic demo fixtures and must not be copied into production.
| async function readJson(request: IncomingMessage): Promise<unknown> { | ||
| const chunks: Buffer[] = []; | ||
| for await (const chunk of request) { | ||
| chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)); |
There was a problem hiding this comment.
Please add a maximum request body size while reading JSON. Accumulating the entire request stream without a cap allows a client to consume memory with a large POST body.
Migrates the Vercel Eve agent example from arcjet-js, demonstrating Arcjet Guard AI guardrails (guardTool, guardApproval, guardInbound) on a Vercel Eve agent. Standalone example (not wired into compose/CI). Pinned to @arcjet/guard@1.10.0-rc.0; the Eve integration subpath (@arcjet/guard/vercel-eve) is not yet published to npm, so the README notes it will not build until that API ships. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Consolidates the remaining unique examples from the
arcjet/arcjet-jsexamples/directory into this repository, rebuilt to the canonical example pattern (canonicalpackage.jsonmetadata, templated README, Dockerfile,compose.yaml, devcontainer, LICENSE) with Arcjet packages pinned to published versions.Paired with the removal PR in arcjet-js: arcjet/arcjet-js#6217 (removes the examples from that repo).
Examples added (8)
bundeno)express-newmannextjs-bot-categoriesreact-router-middlewarenextjs-ai-agentnextjs-sensitive-infonextjs-guard-policynode-guard-policyThe first four are wired into the root
compose.yamland the Docker build CI matrix. The Guard/AI examples are standalone — they need an AI gateway key, dashboard policy config, or a native NER backend, so they are excluded from the default compose/CI run.nextjs-guard-policyandnode-guard-policydepend on the Arcjet Guard remote-policy API (policyInput,guardToolactor,launchArcjet({ sensitiveInfoBackend }),decision.policyResults) which is not yet published to npm. They are pinned to1.10.0-rc.0as the closest published release and carry a prominent README note thatnpm ci+ build will not succeed until that API ships.nextjs-ai-agentis pinned to1.10.0-rc.0(first release with the agent guardrail API);nextjs-sensitive-infoto1.9.1(Rampart's earliest release).Wiring
compose.yaml— includes the 4 non-AI examples.github/workflows/docker-build.yml— matrix updated with the 4 non-AI examplesscripts/prepare-to-publish.ts— all 8 registered for publishing to their own reposREADME.md— all 8 listedValidation
npm install+npm run build/typecheck pass for all buildable examples (bunverified by code review only — Bun isn't installed in the build environment; it builds viabun installin its Dockerfile). The two guard-policy examples build once the Guard remote-policy API is published.🤖 Generated with Claude Code