API security
Run Glyphfield's public generation API safely with its input limits, remote URL rule, CORS headers and production rate limit, and verify each control.
POST /api/generate is public and unauthenticated by design. The application code validates every request, and the hosting edge limits request volume. A deployment needs both controls.
Risks and controls
| Risk | Application control | Deployment control |
|---|---|---|
| Oversized work | Request bodies are limited to 5,250,000 bytes and each image data URL to 5,000,000 characters. Background width and height run from 64 to 4096 px with at most 12,000,000 pixels | Proxy body limits should fail clearly before excessive serverless work |
| Unexpected request fields | Unknown top-level fields fail with 400 unknown_field | Log repeated invalid traffic without storing submitted assets |
| Remote file access | Custom images must be base64 data URLs (GIF, JPEG, PNG, SVG or WebP). Remote URLs are not fetched | An egress policy can add a second boundary where the host supports one |
| Repeated generation | Validation rejects bad requests before rendering | A rate limit per IP address on POST /api/generate before serverless execution |
| Exposure of browser-local data | The HTTP routes do not read Studio localStorage or IndexedDB | Serve the app from trusted HTTPS origins and control third-party scripts |
| Stale or shared responses | Generation responses send Cache-Control: no-store | Do not override that header with CDN caching |
Application validation
The generation route checks the request shape, size and generator limits:
- The request needs
Content-Type: application/json, or it fails with415 unsupported_media_type. - A body over 5,250,000 bytes fails with
413 request_too_large. The route checks the declaredContent-Lengthfirst and the received body second. - Background width and height must be integers from 64 to 4096, and their product cannot exceed 12,000,000 pixels.
- Remote URLs are not supported.
- Unknown top-level fields are rejected.
- Malformed or invalid requests return structured errors and do not change any browser project.
- The route processes submitted identity and asset data in memory and does not store it.
POST /api/brand/validate and POST /api/brand/kit apply the same media type and size rules. Read GET /api/generate and /openapi.json before sending a request. Do not relax a validator to make an outdated client work.
CORS
The agent routes send Access-Control-Allow-Origin: *, Access-Control-Allow-Methods: GET, POST, OPTIONS and Access-Control-Allow-Headers: Content-Type, Accept. These headers let pages on other origins call the public contract. They do not authenticate the caller, so do not treat any request as trusted.
If a private deployment needs authentication, add it as a deliberate change to the deployment and the application, and update:
- The OPTIONS behavior and the allowed headers.
- The security schemes in OpenAPI.
- The
/api/agentpolicies and examples. - The browser and server clients.
- The error handling and the documentation.
Do not add a cookie requirement to the public examples.
Production rate limit
The repository does not rate-limit requests itself. /openapi.json documents 429 for POST /api/generate as the production rate limit. The production deployment for glyphfield.com is expected to have an edge firewall rule that matches only POST /api/generate, counts requests per IP address in a fixed 60-second window, allows 10 requests, returns 429 after that and keeps the client limited for one minute.
The firewall rule is stored in the Vercel project, outside the repository. An administrator checks it with the Vercel CLI:
vercel firewall overview --project glyphfield --scope general-translation --json
vercel firewall rules list --project glyphfield --scope general-translation --json
vercel firewall diff --project glyphfield --scope general-translation --jsonIf the rule is missing, create it and review the diff before publishing:
vercel firewall rules add "Rate limit Glyphfield generation" \
--description "Bound unauthenticated generation before serverless execution." \
--condition '{"type":"path","op":"eq","value":"/api/generate"}' \
--condition '{"type":"method","op":"eq","value":"POST"}' \
--action rate_limit \
--rate-limit-algo fixed_window \
--rate-limit-keys ip \
--rate-limit-requests 10 \
--rate-limit-window 60 \
--rate-limit-action rate_limit \
--duration 1m \
--yes \
--project glyphfield \
--scope general-translationPublishing changes live infrastructure, so only an authorized administrator should do it. Afterward, confirm that the eleventh request from one client inside the window receives 429 and that requests succeed again after the window ends.
Other hosts need an equivalent limit that fits their traffic. The commands above apply only to Vercel.
Browser API boundary
The Browser API (window.glyphfield.studio) operates the active project in the visitor's browser. It reads and applies source, operates controls, accepts local files as authorized File objects and returns downloadable artifacts.
- Do not inject untrusted scripts into the Studio origin.
- Do not pass file path strings to file controls.
- Do not write to localStorage, IndexedDB or React internals directly.
- Share a returned Blob or copied source only with its authorized destination.
- Treat imported SVG, font, image, audio and Lottie files as user-supplied data.
The HTTP API has no access to this browser-local state.
Logging and privacy
Operational logs should record the route, status, duration and request kind. They should not store complete identities, embedded data URLs or generated artifact bodies. Redact authorization headers if a private deployment adds them.
A useful failure report contains:
- The request kind and the response error code.
- The dimensions and the approximate body size.
- The deployed commit or version and the route.
- Whether the failure happened during validation or during generation.
Do not paste proprietary source or binary data into a public issue.
Security checks
Before a release:
- Confirm that valid discovery and generation requests succeed.
- Confirm that malformed JSON returns
400. - Confirm that a wrong content type returns
415. - Confirm that an oversized body returns
413. - Confirm that unknown fields and remote URLs are rejected.
- Confirm that generation responses still send
no-store. - Confirm that the edge rate limit is active in production.
- Confirm that no HTTP route returns browser-local projects.
Errors and limits, Endpoint reference and Self-hosting cover the error codes and deployment.
Self-hosting
Install, build and deploy your own Glyphfield server with the right Node and pnpm versions, keep its dynamic routes working, and verify the deployment.
Troubleshooting and recovery
Diagnose Studio loading, saving, source, shader, asset, GIF, MP4 and export failures, and recover a draft without losing the active design.