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: { /* ... */ },})