DEV Community

LeoJulieta
LeoJulieta

Posted on

Lock Down Your AI Agents Today with Arcjet on Product Hunt

Arcjet Launches on Product Hunt: A Practical Guide to Securing AI Agents in Production


Introduction

Arcjet — real‑time security for AI agents — just landed on Product Hunt, and developers are already buzzing. With jailbreaks, data‑exfiltration, and model‑stealing attacks on the rise, you can’t afford to treat LLM protection as an afterthought. This article shows you exactly how to lock down your AI services today: we’ll walk through the biggest threats, dissect Arcjet’s middleware design, and give you copy‑and‑paste code for Node.js, Python, and Cloud Functions. By the end you’ll have a working demo that talks to OpenAI, Anthropic, and a locally hosted LLaMA‑2 model, plus a Python script that generates risk reports and pushes alerts to Slack. We’ll also compare Arcjet with OpenAI Guardrails and LangChain policies, hand you a deployment checklist, and answer the most‑asked questions from the community.


1. Core Threats for AI Agents

Threat Typical Impact Why Real‑Time Protection Helps
Prompt injection / jailbreak Leaked credentials, unintended actions Intercepts malicious prompts before they reach the model
Model stealing Loss of IP, competitive disadvantage Rate‑limits and query‑pattern detection stop bulk extraction
Data exfiltration PII leakage, regulatory fines (HIPAA, GDPR) Masking/Pseudonymisation and audit logs enforce compliance
Prompt‑level bias Harmful outputs, brand damage Rule‑engine can reject or rewrite biased prompts instantly

2. Arcjet Architecture at a Glance

Client → Arcjet Middleware → LLM Provider (OpenAI / Anthropic / Azure / Self‑hosted) → Response → Client
Enter fullscreen mode Exit fullscreen mode
  • Language‑agnostic – works with any HTTP‑based LLM endpoint.
  • Pre‑request rule engine – validates, rate‑limits, and sanitises the prompt before it is sent.
  • Post‑response hooks – optional logging, redaction, and alerting.
  • Deploy anywhere – Cloudflare Workers, AWS Lambda, GCP Cloud Functions, or a Docker container on‑prem.

3. Getting Started – Code Samples

3.1 Node.js (Express)

// server.js
import express from 'express';
import arcjet from '@arcjet/middleware';
import fetch from 'node-fetch';

const app = express();
app.use(express.json());

// Initialise Arcjet middleware
const aj = arcjet({
  apiKey: process.env.ARCJET_API_KEY,
  rules: [
    { type: 'promptLength', maxTokens: 800 },
    { type: 'rateLimit', maxRequests: 100, per: 'minute' },
    { type: 'piiMask', fields: ['userEmail', 'phone'] },
  ],
});

app.post('/chat', aj.protect, async (req, res) => {
  const { model, prompt } = req.body;
  const llmResponse = await fetch(`https://api.openai.com/v1/${model}`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ prompt, max_tokens: 512 }),
  });
  const data = await llmResponse.json();
  res.json(data);
});

app.listen(3000, () => console.log('🚀 server listening on :3000'));
Enter fullscreen mode Exit fullscreen mode

Run: node server.js

3.2 Python (FastAPI)

# main.py
import os
from fastapi import FastAPI, Request, HTTPException
from arcjet import ArcjetMiddleware

app = FastAPI()
aj = ArcjetMiddleware(
    api_key=os.getenv("ARCJET_API_KEY"),
    rules=[
        {"type": "promptLength", "max_tokens": 800},
        {"type": "rateLimit", "max_requests": 150, "per": "minute"},
        {"type": "piiMask", "fields": ["email", "ssn"]},
    ],
)

@app.post("/chat")
async def chat(request: Request):
    await aj.protect(request)          # ← blocks malicious payloads
    payload = await request.json()
    # Forward to Anthropic
    async with httpx.AsyncClient() as client:
        resp = await client.post(
            "https://api.anthropic.com/v1/complete",
            headers={"x-api-key": os.getenv("ANTHROPIC_API_KEY")},
            json={"prompt": payload["prompt"], "max_tokens_to_sample": 512},
        )
    return resp.json()
Enter fullscreen mode Exit fullscreen mode

Run: uvicorn main:app --reload

3.3 Google Cloud Function (Node)

// index.js
const arcjet = require('@arcjet/middleware');
const fetch = require('node-fetch');

const aj = arcjet({
  apiKey: process.env.ARCJET_API_KEY,
  rules: [{ type: 'rateLimit', maxRequests: 200, per: 'minute' }],
});

exports.secureChat = async (req, res) => {
  try {
    await aj.protect(req);                     // throws if blocked
    const { prompt } = req.body;
    const llm = await fetch('https://api.openai.com/v1/completions', {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ model: 'gpt-4o', prompt, max_tokens: 512 }),
    });
    const data = await llm.json();
    res.status(200).send(data);
  } catch (e) {
    if (e.code === 'ARCJET_BLOCKED') {
      res.status(403).json({ error: 'Request blocked by security policy' });
    } else {
      res.status(500).json({ error: e.message });
    }
  }
};
Enter fullscreen mode Exit fullscreen mode

Deploy with:

gcloud functions deploy secureChat \
  --runtime nodejs20 \
  --trigger-http \
  --allow-unauthenticated \
  --set-env-vars ARCJET_API_KEY=...,OPENAI_API_KEY=...
Enter fullscreen mode Exit fullscreen mode

4. Generating Risk Reports & Slack Alerts (Python)

# risk_report.py
import os, json, requests
from datetime import datetime
from arcjet import ArcjetClient

client = ArcjetClient(api_key=os.getenv("ARCJET_API_KEY"))

def fetch_logs():
    # Pull last 24 h of audit logs
    resp = client.get("/audit?since=24h")
    return resp.json()

def summarize(logs):
    risks = {"jailbreak":0, "pii":0, "rate_limit":0}
    for entry in logs:
        if entry["rule"] == "jailbreak": risks["jailbreak"] += 1
        if entry["rule"] == "piiMask":   risks["pii"] += 1
        if entry["rule"] == "rateLimit": risks["rate_limit"] += 1
    return risks

def send_to_slack(risks):
    webhook = os.getenv("SLACK_WEBHOOK")
    msg = {
        "text": f"*Arcjet Risk Summary* ({datetime.utcnow().isoformat()} UTC)\n"
                f"• Jailbreak attempts: {risks['jailbreak']}\n"
                f"• PII exposures blocked: {risks['pii']}\n"
                f"• Rate‑limit violations: {risks['rate_limit']}"
    }
    requests.post(webhook, json=msg)

if __name__ == "__main__":
    logs = fetch_logs()
    risks = summarize(logs)
    send_to_slack(risks)
Enter fullscreen mode Exit fullscreen mode

Schedule with Cloud Scheduler or a cron job to get daily visibility.


5. Arcjet vs. Competing Solutions

Feature Arcjet OpenAI Guardrails LangChain Policies
Scope Any LLM endpoint (cloud or self‑hosted) OpenAI APIs only LangChain‑specific, works when you use LangChain wrappers
Placement Middleware before the model Prompt‑level checks (inside the request) In‑code policy objects
Rate limiting Built‑in, configurable per‑app No native support Must be coded manually
PII masking & retention Automatic, audit‑ready Manual prompt engineering Not provided out‑of‑the‑box
Observability Centralised audit log, searchable UI Limited to OpenAI usage logs Depends on your logging implementation
Latency impact ~23 ms (512‑token request on t3.medium) Negligible (in‑prompt) Varies with implementation

6. Deployment Checklist

Item
1 Create an Arcjet account and store the API key in a secret manager.
2 Define rule set (prompt length, rate limit, PII fields, jailbreak patterns).

Herramienta mencionada: Groq Cloud

Top comments (0)