# API Shield

> Generate OpenAPI for Cloudflare API Shield Schema Validation

Package: Koze
Canonical: https://kuratchi.dev/docs/koze/api-shield
Markdown: https://kuratchi.dev/docs/koze/api-shield.md

Koze treats Cloudflare API Shield as a route-adjacent API contract. Put an `*.api-shield.ts` file beside the API route it describes, and Koze generates the Cloudflare handoff files in a visible `_cloudflare/` folder:

```text
src/routes/api/v1/items/[id]/index.ts
src/routes/api/v1/items/[id]/index.api-shield.ts

_cloudflare/api-shield/openapi.json
_cloudflare/api-shield/api-shield.tf
_cloudflare/api-shield/README.md
```

Use those files with Cloudflare API Shield Schema Validation to protect your API routes with the same contract metadata you keep next to the route source.

## Route file

```ts
export async function GET() {
  return Response.json(await loadItem());
}
```

## API Shield file

```ts
// src/routes/api/v1/items/[id]/index.api-shield.ts
export default {
  GET: {
    operationId: 'getItem',
    summary: 'Read an item',
    auth: 'required',
    tags: ['items'],
    params: {
      id: { type: 'string', format: 'uuid' },
    },
    query: {
      include: { type: 'string' },
    },
    responses: {
      200: { description: 'Item found' },
      404: { description: 'Item not found' },
    },
  },
} as const;
```

The sidecar file name follows the route file name: `items.ts` uses `items.api-shield.ts`, and `index.ts` uses `index.api-shield.ts`. Koze adds the route pattern, exported methods, and file path automatically. Dynamic segments become OpenAPI parameters, so `/api/v1/items/:id` becomes `/api/v1/items/{id}`.

Route `manifest` exports still work for compatibility, but `*.api-shield.ts` is the recommended source because the file name says exactly what it feeds.

## Vite options

API Shield generation is enabled by default when API routes exist.

```ts
koze({
  apiShield: {
    title: 'Inventory API',
    version: '2026.05',
    servers: ['https://api.example.com'],
    include: ['/api/v1'],
    // outputPath: '_cloudflare/api-shield/openapi.json',
  },
});
```

Set `apiShield: false` to disable the artifact.

Use `include` when only part of your API route tree should be exported to an API Shield schema. For example, `include: ['/api/v1']` exports `/api/v1` and `/api/v1/items/{id}`, but leaves internal app routes like `/api/reports` out of the generated OpenAPI file.

## Cloudflare setup

Upload `_cloudflare/api-shield/openapi.json` in **Security > API Shield > Schema validation**, or apply the generated `_cloudflare/api-shield/api-shield.tf` helper after setting `zone_id` and `api_host`. Cloudflare's dashboard upload can add endpoints to Endpoint Management automatically; API/Terraform flows may require adding endpoints separately.

API Shield settings such as JWT validation rules, mTLS, rate limiting, and mitigation actions still live in Cloudflare. Koze's job is to make the schema and Endpoint Management source of truth native to the framework without hiding the handoff files inside compiled internals.

Related Cloudflare docs:

- [API Shield get started](https://developers.cloudflare.com/api-shield/get-started/)
- [Schema validation](https://developers.cloudflare.com/api-shield/security/schema-validation/)
- [JWT validation](https://developers.cloudflare.com/api-shield/security/jwt-validation/)
