@foruai/gatekeeper-server
v0.2.0
Published
Server-side HMAC-SHA256 token signer for the ForU Gatekeeper AI API
Downloads
201
Maintainers
Readme
@foruai/gatekeeper-server
Server-side HMAC-SHA256 token signer for the ForU Gatekeeper AI API. Generate short-lived, one-time-use authentication tokens that your frontend can safely use to call the API directly.
Installation
npm install @foruai/gatekeeper-server
# or
pnpm add @foruai/gatekeeper-server
# or
bun add @foruai/gatekeeper-serverHow It Works
The Gatekeeper API supports HMAC-SHA256 authentication so you never expose your secret key to the browser:
1. Frontend requests a signed token from YOUR backend
2. Your backend generates: nonce + timestamp + HMAC-SHA256(nonce:timestamp, SECRET)
3. Frontend sends the signed token to the Gatekeeper API
4. Gatekeeper verifies signature, checks expiry (5 min) + nonce uniqueness
5. Nonce is consumed (one-time use, replay-safe)Browser → Your Backend (holds HMAC_SECRET) → returns signed token
Browser → Gatekeeper API (verifies HMAC) → returns responseQuick Start
Generate a token (server-side)
import { GatekeeperSigner } from '@foruai/gatekeeper-server'
const signer = new GatekeeperSigner({
secret: process.env.HMAC_SECRET!, // your shared secret
})
// Option 1: Get a token object (pass to frontend)
const token = await signer.createToken()
// => { nonce: "a1b2c3...", timestamp: 1708000000000, signature: "deadbeef..." }
// Option 2: Get a ready-to-use Authorization header
const header = await signer.createAuthHeader()
// => "HMAC a1b2c3...:1708000000000:deadbeef..."Example: Express/Hono endpoint
import express from 'express'
import { GatekeeperSigner } from '@foruai/gatekeeper-server'
const app = express()
const signer = new GatekeeperSigner({ secret: process.env.HMAC_SECRET! })
// Frontend calls this to get a signed token
app.get('/api/gatekeeper-token', async (req, res) => {
const token = await signer.createToken()
res.json(token)
})Example: Next.js API Route
// app/api/gatekeeper-token/route.ts
import { GatekeeperSigner } from '@foruai/gatekeeper-server'
const signer = new GatekeeperSigner({ secret: process.env.HMAC_SECRET! })
export async function GET() {
const token = await signer.createToken()
return Response.json(token)
}Using the token from the frontend
// Frontend: get token from your backend, then call Gatekeeper
const tokenRes = await fetch('/api/gatekeeper-token')
const token = await tokenRes.json()
const res = await fetch('https://gatekeeper.foruai.io/v1/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `HMAC ${token.nonce}:${token.timestamp}:${token.signature}`,
},
body: JSON.stringify({ message: 'check badges for 0x123...' }),
})Or use @foruai/gatekeeper-client which handles this automatically:
import { GatekeeperClient } from '@foruai/gatekeeper-client'
const client = new GatekeeperClient({
baseUrl: 'https://gatekeeper.foruai.io',
})
const reply = await client.chat('check badges for 0x123...', { token })API Reference
new GatekeeperSigner(options)
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| secret | string | Yes | Your HMAC shared secret |
signer.createToken(): Promise<HmacToken>
Returns an HmacToken object:
interface HmacToken {
nonce: string // 32-char hex random nonce
timestamp: number // Unix timestamp in milliseconds
signature: string // HMAC-SHA256 hex digest of "nonce:timestamp"
}Tokens expire after 5 minutes and are single-use (replay protection).
signer.createAuthHeader(): Promise<string>
Returns a ready-to-use Authorization header value:
HMAC <nonce>:<timestamp>:<signature>Runtime Compatibility
Works in all JavaScript runtimes:
| Runtime | Crypto Backend |
|---------|---------------|
| Node.js 18+ | crypto.createHmac() |
| Bun | Web Crypto API |
| Deno | Web Crypto API |
| Browsers | Web Crypto API (crypto.subtle) |
| Edge (Cloudflare Workers, Vercel Edge) | Web Crypto API |
Companion Packages
@foruai/shared— Shared types and constants@foruai/gatekeeper-client— Full API client for browser & Node.js
License
MIT
