• Product Introduction
  • Quick Start
    • Agent Development
    • Importing a Git Repository
    • Starting From a Template
    • Direct Upload
    • Start with AI
  • Framework Guide
    • Agent
    • Frontends
      • Vite
      • React
      • Vue
      • Hugo
      • Other Frameworks
    • Backends
    • Full-stack
      • Next.js
      • Nuxt
      • Astro
      • React Router
      • SvelteKit
      • TanStack Start
      • Vike
    • Custom 404 Page
  • Project Guide
    • Project Management
    • edgeone.json
    • Configuring Cache
    • Building Output Configuration
    • Error Codes
  • Build Guide
  • Deployment Guide
    • Overview
    • Create Deploys
    • Manage Deploys
    • Deploy Button
    • Using Github Actions
    • Using Gitlab CI/CD
    • Using CNB Plugin
    • Using IDE PlugIn
    • Using CodeBuddy IDE
  • Domain Management
    • Overview
    • Custom Domain
    • HTTPS Configuration
      • Overview
      • Apply for Free Certificate
      • Using Managed SSL Certificate
    • Configure DNS CNAME Record
  • Observability
    • Overview
    • Metric Analysis
    • Log Analysis
  • Functions
    • Overview
    • Edge Functions
    • Cloud Functions
      • Overview
      • Node.js
      • Python
      • Go
  • Agents
    • Overview
    • Quick Start
    • Conversation Storage
    • Observability
    • Sandbox Tool
      • Overview
      • Using the Agent Framework
      • Sandbox Atomic API
      • Network Search Tool
    • Agent Authentication
  • Models
    • Overview
    • Models and Vendors
      • Overview
      • Using Vendor Keys
        • OpenAI
        • Anthropic
        • Google AI Studio
        • DeepSeek
        • MiniMax
        • Hunyuan
        • Zhipu
        • MoonShot AI
    • FAQs
  • Storage
    • Overview
    • KV
    • Blob
  • Middleware
  • AI-Native Development
    • Skills
    • MCP
  • Copilot
    • Overview
    • Quick Start
  • API Token
  • EdgeOne CLI
  • Message Notification
  • Integration Guide
    • AI
      • Dialogue Large Models Integration
      • Large Models for Images Integration
    • Database
      • Supabase Integration
      • Pages KV Integration
    • Ecommerce
      • Shopify Integration
      • WooCommerce Integration
    • Payment
      • Stripe Integration
      • Integrating Paddle
    • CMS
      • WordPress Integration
      • Contentful Integration
      • Sanity Integration
      • Payload Integration
    • Authentication
      • Supabase Integration
      • Clerk Integration
  • Best Practices
    • Adding an AI Chat Assistant to a Website
    • AI Dialogue Deployment: Deploy Project with One Sentence Using Skill
    • Using General Large Model to Quickly Build AI Application
    • Use the DeepSeek model to quickly build a conversational AI site
    • Building an Ecommerce Platform with Shopify
    • Building a SaaS Site Using Supabase and Stripe
    • Building a Company Brand Site Quickly
    • How to Quickly Build a Blog Site
  • Migration Guides
    • Migrating from Vercel to EdgeOne Pages
    • Migrating from Cloudflare Pages to EdgeOne Pages
    • Migrating from Netlify to EdgeOne Pages
  • Troubleshooting
  • FAQs
  • Limits
  • Pricing
  • Contact Us
  • Release Notes

Agent Authentication

An Agent application typically invokes models and tools. Without login authentication, anyone can directly access the Agent API, which may lead to the following issues:
Resource abuse: Unauthenticated users can also consume LLM and tool invocation quotas.
APIs are vulnerable to bypassing: Attackers can skip the frontend page and directly request APIs such as /agents/*.
This document uses an actual project as an example to illustrate how to build a login authentication flow based on Makers platform capabilities: Cloud Functions handles user sign-up and JWT issuance, while the platform middleware intercepts unauthenticated requests at the edge nodes in advance.

Project Key Files and Responsibilities

File / Module
Main Responsibility
middleware.js
Platform middleware. When a protected path is accessed, it first validates the Cookie JWT. If validation fails, it directly returns a 401 status. If successful, it calls next().
cloud-functions/auth/*
Handles user login, sign up, logout, and current user queries. It is responsible for validating account credentials and issuing JWTs.
agents/chat/index.ts
Agent example entry point, demonstrating authentication and streaming responses.
db/migrations/users.sql
Neon database table schema

Implementation Principles

Core Model

User browser
│ Log In / Sign Up
cloud-functions/auth/*
│ Verify the account and password
│ Write to / Query Neon
│ Issue JWT
The HttpOnly Cookie named jwt_token is saved by the browser.
│ Invoke Agent
middleware.js
│ JWT from the pre-existing Cookie
│ Invalid: A 401 status is returned directly.
│ Valid: The result of next() is passed through.
Agent Runtime
│ Call requireAuth(context) again.
Return the SSE / Agent response.

JWT Content Conventions

interface JwtPayload {
sub: string; // users.id,UUID v4
username: string; // Username
iat: number; // Issuance time, a timestamp in seconds
exp: number; // Expiration time, a timestamp in seconds
}

Implementation Process

Sign-In / Sign-Up Process

Browser
│ ① POST /auth/login or /auth/register
middleware.js
│ ② If /auth/* is not in the matcher, it is passed through directly.
cloud-functions/auth/*
│ ③ Verify the username / password.
│ ④ Query or write to the Neon users table.
│ ⑤ Verify or generate a password_hash using bcrypt.
│ ⑥ Issue a JWT using JWT_SECRET.
Browser
│ ⑦ Set-Cookie: jwt_token=...
Login completed.
Key Points:
/auth/login and /auth/register must be public APIs.
Do not include them in middleware.config.matcher.
Upon successful login, the token is saved only via HttpOnly Cookie and is not exposed to frontend JS.

Agent Invocation Process

Browser
│ ⑧ POST /chat, automatically including the Cookie: jwt_token=...
middleware.js
│ ⑨ Verify JWT using Web Crypto.
│ Failure: 401
│ Success: next()
Agent Runtime
│ ⑩ Verify JWT again using requireAuth(context).
Browser
│ ⑪ Stream back the Agent response via SSE.
Key Points:
After the middleware successfully verifies the signature, it only forwards the original request.
The Agent reads the JWT from the Cookie and independently verifies the signature (optional).

Key Implementation of Platform Middleware

File: middleware.js
Responsibility: When a protected path is accessed, verify the JWT from the Cookie. If verification fails, return a 401 status / if successful, call next().

Configuring Protected Paths

export const config = {
matcher: [
'/chat/:path*',
'/stop/:path*',
'/history/:path*',
'/agents/:path*',
],
};
Note:
matcher is the sole source for the middleware's protection scope.
Do not include /auth/* in the matcher.
Static resources and frontend page routes generally do not need to be added to the matcher.

Main Logic

export async function middleware(context) {
const { request, next, env } = context;

const token = readCookie(request.headers, 'jwt_token');
if (!token) return unauthorized('no auth cookie');

try {
await verifyJwt(token, env.JWT_SECRET);
} catch (e) {
return unauthorized(e.message || 'verify failed');
}

return next();
}

Key Points for Signature Verification

The middleware runs in the edge V8 environment and uses Web Crypto:
const key = await crypto.subtle.importKey(
'raw',
utf8ToBytes(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['sign', 'verify'],
);
During signature verification, you must check:
Check Item
Purpose
Verify whether the token is in three-part format.
Prevent malformed tokens.
header.alg === 'HS256'
Prevent alg=none and algorithm confusion.
Verify whether the HMAC signature is consistent.
Confirm that the token has not been tampered with.
Verify whether payload.exp is expired.
Prevent old tokens from remaining valid indefinitely.

Key Implementation of Cloud Functions

Directory: cloud-functions/
Responsibilities: Sign Up / Log In / Current User Information / Log Out

File Structure

File
Feature
auth/register/index.ts
Registers users, writes to Neon, and issues JWTs
auth/login/index.ts
Validates passwords and issues JWTs.
auth/user/index.ts
Determines the currently logged-in user from the Cookie.
auth/logout/index.ts
Clears cookies.

Key Implementation on the Agent Side

File example: agents/chat/index.ts

First-Step Signature Verification at the Entry Point (Optional)

The value of the middleware is early rejection: it blocks unauthenticated requests at the edge node to reduce costs for Agent Runtime, Sandbox, and LLM. However, the middleware is not the ultimate security boundary. You can perform an additional signature verification on the Agent side.
import { requireAuth, AuthError, unauthorizedResponse } from '../_jwt';
export async function onRequest(context: any) {
let auth;
try {
auth = requireAuth(context);
} catch (e) {
if (e instanceof AuthError) {
return unauthorizedResponse(e.reason);
}
throw e;
}
// Only from this point onward can the Agent business logic be executed.
}

Database Configuration and Implementation

Neon is Serverless Postgres. This solution uses it to store user tables and accesses it via @neondatabase/serverless over HTTPS. Alternatively, you can choose other third-party databases.

Configuration Steps

1. Create a project in the Neon console.
2. Obtain the connection string. The format should be similar to:
postgresql://<user>:<password>@<host>/<db>?sslmode=require
3. Configure it in the EdgeOne Makers project environment variables:
Variable
Required
Description
DATABASE_URL
Yes
Neon connection string. It is recommended to include ?sslmode=require.
JWT_SECRET
Yes
JWT signing key, which must be consistent across all three tiers.
During local development, configure the variable with the same name in .env.

Database Table Structure

CREATE EXTENSION IF NOT EXISTS pgcrypto;

CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username VARCHAR(64) NOT NULL,
password_hash VARCHAR(255) NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

CREATE UNIQUE INDEX IF NOT EXISTS users_username_lower_uniq
ON users (LOWER(username));
Note:
id is automatically generated by the Postgres gen_random_uuid() function.
Only the bcrypt hash is stored in password_hash, and plaintext passwords are not stored.
The LOWER(username) unique index is used to prevent Alice and alice from signing up simultaneously.

Integration Steps

If you want to integrate this solution into your own Agent project, follow these steps in order:
1. Create a Neon database and execute db/migrations/users.sql.
2. Configure DATABASE_URL and JWT_SECRET.
3. Copy cloud-functions/auth/*, cloud-functions/_jwt.ts, cloud-functions/_db.ts, and cloud-functions/_validate.ts.
4. Configure the matcher in middleware.js to cover all protected Agent paths.
5. Add requireAuth(context) as the first step in each Agent entry.


ai-agent
You can ask me like
What types of applications can I deploy?