@argushq/agent
v0.1.0
Published
Argus drop-in agent for Next.js / React apps — edge WAF middleware, security headers/CSP, telemetry, managed heartbeat + policy, signed command receiver, and the `argus` CLI. The web-app equivalent of the Argus WordPress plugin.
Maintainers
Readme
@argushq/agent
The Argus drop-in security agent for Next.js / React apps — the web-app twin of the Argus WordPress plugin. Add one package, wire one line of middleware, pair with one command, and your app reports security telemetry to Argus, hardens its response headers, heartbeats to stay live, and can receive signed remediation commands.
pnpm add @argushq/agentNeed a custom integration for a non-Next runtime? Use the lower-level
@argushq/agent-sdk.
Day-0 quickstart
1. Add the middleware
// middleware.ts
import { withArgus } from '@argushq/agent/middleware'
export default withArgus()
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon).*)'],
}withArgus() inspects requests for suspicious patterns (SQLi/XSS/traversal/recon),
applies a per-IP rate limit, sets a CSP nonce, and — on a throttle — heartbeats so your
target flips active in the Argus console.
2. Pair the site
npx argus pair <PAIRING_KEY> # paste a key from the Argus dashboard
# or
npx argus login # browser "Connect to Argus" flowargus pair redeems the one-time key server-side and writes the server-scoped
credentials — in dev it appends them to .env.local (gitignored); in prod/CI it prints
the env vars to set on your platform:
ARGUS_SITE_ID=site_…
ARGUS_HMAC_SECRET=… # ← a server secret. NEVER expose it to the browser / NEXT_PUBLIC_.
ARGUS_INGEST_URL=https://api.argusmesh.app/ingest
ARGUS_API_BASE=https://api.argusmesh.app3. Verify
npx argus doctorChecks the env, sends a signed test event, and reports the result. That's the whole happy path.
Optional, higher-signal pieces
Security headers + CSP
// next.config.mjs
import { withArgusHeaders } from '@argushq/agent/next-config'
export default withArgusHeaders(
{ /* your existing next config */ },
{ cspMode: 'report-only', firebaseAuth: true },
)Adds HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy,
Permissions-Policy, and a Content-Security-Policy (start in report-only, then flip to
enforce). CSP violations report to your beacon route.
Managed loop (long-running servers)
// instrumentation.ts
export { register } from '@argushq/agent/server'On a Node server (Cloud Run, a self-host, a container) this keeps a 15-minute heartbeat and pulls policy. Serverless / zero-traffic sites should add the cron route instead (below), because the throttled middleware heartbeat only fires on a request.
Signed command receiver (remote remediation)
// app/api/__argus/command/route.ts
import { createArgusCommandHandler } from '@argushq/agent/server'
export const POST = createArgusCommandHandler({
block_ip: async ({ ip }) => blocklist.add(ip as string),
unblock_ip: async ({ ip }) => blocklist.delete(ip as string),
force_logout: async ({ uid }) => revokeSessions(uid as string),
})HMAC verification (signature, ±300s replay, constant-time, site match) is handled for you; you implement only the actions that fit your app.
Browser telemetry (secure)
// app/api/__argus/beacon/route.ts
import { createArgusBeaconHandler } from '@argushq/agent/server'
export const POST = createArgusBeaconHandler()The client beacon (used by ArgusBoundary and useArgusAuth from @argushq/agent/react)
posts unsigned events to this same-origin proxy, which signs them server-side. The
HMAC secret never reaches the browser bundle.
Cron heartbeat (serverless low-traffic)
// app/api/__argus/cron/route.ts
import { heartbeatNow } from '@argushq/agent/server'
export async function GET() { return Response.json(await heartbeatNow()) }Point a Vercel Cron / Netlify Scheduled Function at it (e.g. every 15 min) so a quiet serverless deployment still flips and stays active.
Deploy manifest (SBOM)
// package.json
{ "scripts": { "postbuild": "argus manifest upload" } }CLI
| Command | What it does |
|---|---|
| argus pair <key> [--url <u>] [--print] | Pair with a dashboard key → wire credentials |
| argus login [--url <u>] | Browser "Connect to Argus" linking |
| argus doctor [--url <u>] | Verify env, transport, response headers |
| argus manifest upload [--cwd .] | Build + upload a deploy manifest |
| argus version | Print the agent version |
Environment
All server-scoped — never NEXT_PUBLIC_:
| Var | Meaning |
|---|---|
| ARGUS_SITE_ID | Your site's opaque id (x-argus-site) |
| ARGUS_HMAC_SECRET | Per-site signing secret — keep server-only |
| ARGUS_INGEST_URL | Telemetry endpoint, e.g. https://api.argusmesh.app/ingest |
| ARGUS_API_BASE | Agent plane, e.g. https://api.argusmesh.app |
Security model
- One per-site HMAC secret signs outbound telemetry and verifies inbound commands.
- The secret is a server secret. The edge middleware and Node server use it; the browser never does (client beacons go through the server proxy).
- Signing:
x-argus-sig: v1=hex(HMAC_SHA256("${ts}.${rawBody}", secret)), ±300s replay. See Docs/agent-protocol-v1.md.
Links
- Web-app onboarding runbook
- Agent Protocol v1
- OpenAPI: agent plane · ingest
@argushq/agent-sdk— build a custom integration
License
MIT © Mind Hack, Inc.
