Auth

Authentication

Per-command auth levels and token verification

Authentication#

Surf supports per-command auth levels: none (public), optional, required, or hidden. Auth is advertised in the manifest so agents know what credentials to provide. Hidden commands are excluded from the manifest entirely unless the request includes a valid auth token.

typescript
import { createSurf } from '@surfjs/core'
ย 
const surf = await createSurf({
name: 'My Store',
auth: { type: 'bearer', description: 'JWT Bearer token' },
ย 
// Auth verifier โ€” called automatically for commands that need auth
authVerifier: async (token, command) => {
const decoded = await verifyJWT(token)
if (!decoded) return { valid: false, reason: 'Invalid token' }
return { valid: true, claims: { userId: decoded.sub, role: decoded.role } }
},
ย 
commands: {
// Public โ€” no auth needed
search: {
description: 'Search products',
auth: 'none', // default
params: { query: { type: 'string', required: true } },
run: async ({ query }) => db.search(query),
},
ย 
// Auth required โ€” returns 401 if no token, 403 if invalid
'order.create': {
description: 'Create a new order',
auth: 'required',
run: async (params, ctx) => {
// ctx.claims is populated by authVerifier
return orders.create(ctx.claims!.userId, params)
},
},
ย 
// Auth optional โ€” works without token, enriched with token
recommendations: {
description: 'Get recommendations',
auth: 'optional',
run: async (_, ctx) => {
if (ctx.claims) return personalized(ctx.claims.userId)
return popular()
},
},
ย 
// Hidden โ€” not in manifest unless authed
'admin.analytics': {
description: 'Dashboard analytics',
auth: 'hidden',
run: async (_, ctx) => getAnalytics(ctx.claims!.role),
},
},
})

Surf also provides a built-in bearerVerifier for simple token validation:

typescript
import { createSurf, bearerVerifier } from '@surfjs/core'
ย 
const surf = await createSurf({
name: 'My API',
authVerifier: bearerVerifier(['sk-secret-token-1', 'sk-secret-token-2']),
commands: { /* ... */ },
})