Daoyou Hono API、认证、授权、Better Auth、Turnstile、admin、internal cron、LLM header 安全和服务端输入校验指南。Use when adding or modifying src/server routes, middleware, auth, admin endpoints, cron/internal endpoints, shared contracts, LLM provider handling, API validation, or security-relevant frontend auth/admin loaders in this repo. For ordinary admin pages, navigation, and UI state, use daoyou-frontend-routing-state.
Instalación
Instalar con Codex o Claude Copia este prompt, pégalo en Codex, Claude u otro asistente, y deja que revise la página de la skill y la instale por ti.
Daoyou Hono API、认证、授权、Better Auth、Turnstile、admin、internal cron、LLM header 安全和服务端输入校验指南。Use when adding or modifying src/server routes, middleware, auth, admin endpoints, cron/internal endpoints, shared contracts, LLM provider handling, API validation, or security-relevant frontend auth/admin loaders in this repo. For ordinary admin pages, navigation, and UI state, use daoyou-frontend-routing-state.
Daoyou Backend API Security
Read First
src/server/app.ts
src/server/routes/api/index.ts
src/server/routes/internal/cron.router.ts
src/server/lib/hono/middleware.ts
src/server/lib/auth/auth.ts
src/server/lib/auth/hono.ts
src/server/lib/llm/allowedHosts.ts
src/shared/config/llmProviders.ts
src/shared/contracts
Existing route/service tests near the target endpoint
API Boundary Facts
API server is Hono.
/api/auth/* is handled by Better Auth through src/server/lib/auth/hono.ts.
jsonError() handles Zod errors and uncaught API errors for /api/* and /internal/*, but auth is registered before that middleware.
Frontend route loaders are UX guards only. Backend handlers are the security boundary.
Existing auth middleware:
requireUser() for logged-in users.
requireActiveCultivator() for logged-in users with an active cultivator; it sets user, cultivator, and executor.
requireAdmin() for ADMIN_EMAILS allowlist.
validateJson() and validateQuery() for Zod parsing.
Admin subroutes currently apply requireAdmin() explicitly inside handlers.
/internal/cron/* uses Authorization: Bearer ${CRON_SECRET}, not user sessions. In production, missing CRON_SECRET returns 500.
LLM Security Facts
The browser patches window.fetch in src/react-app/main.tsx to add x-llm-* headers for /api/ requests.
Server LLM calls should use src/server/utils/aiClient.ts (text, stream_text, object, objectArray, tool) so provider resolution, metrics, schema prompt injection, retry, and jsonrepair stay in one path.
Server accepts user LLM config only when provider, apiKey, model, and fastModel are present.
Non-empty x-llm-base-url must pass HTTPS and hostname whitelist validation in src/server/lib/llm/allowedHosts.ts.
The whitelist source of truth is src/shared/config/llmProviders.ts; do not add a second server-only allowlist.
LLM metrics use in-memory fallback plus Redis key admin:llm-metrics:events:v1; do not add a parallel metrics store.
Prompt files under src/server/prompts/*.md have id: headers. New prompt scenes usually also need LlmSceneId, caller sceneId, schema/constraint, and tests.
Treat LLM output as untrusted input. Numeric state changes need Zod bounds and service/resource-layer guards.
docs/llm-security-defense.md contains useful historical risk analysis, but parts are stale relative to current code.
External Service Facts
Redis access must go through src/server/lib/redis; do not instantiate new Redis() in feature code.
Redis is not optional for many runtime paths even though health-check reports disabled when REDIS_URL is absent.
SMTP mail uses src/server/lib/admin/smtp.ts; required env includes SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, and MAIL_FROM.
Workflow
Classify the endpoint: public, logged-in, active-cultivator, admin, or internal cron.
Reuse the existing middleware. Do not hand-roll session parsing.
Add or reuse Zod schemas for request bodies and query strings.
Register new API routes in src/server/routes/api/index.ts; register internal jobs in src/server/routes/internal.
If the route changes shared request/response shape, update src/shared/contracts or src/shared/types.
If the route calls LLM or consumes LLM output, check prompt/schema bounds and service-layer guards.
If adding a prompt scene, update prompt id, LlmSceneId, caller sceneId, schema/constraint, and tests together.
Add focused route/service tests.
Do Not
Do not rely on React loaders for authorization.
Do not bypass src/server/lib/auth/hono.ts for login, signup, reset, OTP, or Turnstile-protected flows.
Do not add admin files under /api/admin without explicit admin authorization.
Do not read x-llm-base-url directly in business code; use the validated context config.
Do not make public list/ranking/community endpoints private without checking frontend/product usage.
Do not assume src/shared/api exists; shared contracts live under src/shared/contracts.
Do not bypass aiClient.ts for LLM calls.
Do not create feature-local Redis clients or SMTP transports.
Verify
Route/middleware changes: run the nearest route test.
Auth changes: run auth-related tests and manually check cookie/header behavior when relevant.
LLM provider changes: run src/server/lib/llm/allowedHosts.test.ts.
Cron changes: test the route and verify secret behavior for production and non-production assumptions.