DocumentsKubb's Space
How can you extend Kubb's generated code to access OpenAPI security schemes inside fetch functions, so each generated client knows which security scheme it requires?
How can you extend Kubb's generated code to access OpenAPI security schemes inside fetch functions, so each generated client knows which security scheme it requires?
Type
Answer
Status
Published
Created
Mar 19, 2026
Updated
Mar 29, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

To extend Kubb's generated code with security scheme awareness, you need to create a custom Kubb generator. The security data is accessible via the @kubb/adapter-oas package but is not used by default plugins.

Accessing Security Data in Generators#

Inside a custom generator, you can access:

  • Operation-level security: node.security
  • Global security schemes: via the adapter's document field

The Adapter<AdapterOas> exposes the raw OpenAPI document as a typed, first-class field that is populated after parse() is called. Starting in @kubb/adapter-oas@5.0.0-alpha.24, document is type-safe and includes the full OpenAPI Document type. You access it through adapter.document (passed as a direct prop to generators).

Example: Security-Aware Client Generator#

import { defineGenerator } from '@kubb/core'
import { File, Function } from '@kubb/react-fabric'
import type { Adapter } from '@kubb/core'
import type { AdapterOas } from '@kubb/adapter-oas'

export const securityAwareClientGenerator = defineGenerator({
  name: 'security-client',
  type: 'react',
  Operation({ node, adapter, driver, config, resolver, options }) {
    const security = node.security || []
    const typedAdapter = adapter as Adapter<AdapterOas>
    const document = typedAdapter.document
    const securitySchemes = document?.components?.securitySchemes || {}

    // Build security metadata
    const requiredAuth = security.flatMap(req =>
      Object.entries(req).map(([schemeName, scopes]) => ({
        name: schemeName,
        type: securitySchemes[schemeName]?.type,
        in: securitySchemes[schemeName]?.in,
        paramName: securitySchemes[schemeName]?.name,
        scopes: scopes,
      }))
    )

    return (
      <File baseName={`${node.operationId}.ts`} path="./clients">
        <File.Source>
          {`export const ${node.operationId}Security = ${JSON.stringify(requiredAuth)} as const\n\n`}
          {`export function ${node.operationId}(params: Params, config?: RequestConfig) {
            // Security metadata available: ${requiredAuth.map(a => a.name).join(', ') || 'none'}
            return client({ method: '${node.method}', url: '${node.path}', ...config })
          }`}
        </File.Source>
      </File>
    )
  }
})

Wiring It Into Your Config#

// kubb.config.ts
import { pluginClient } from '@kubb/plugin-client'

export default defineConfig({
  plugins: [
    pluginClient({
      generators: [securityAwareClientGenerator]
    })
  ]
})

Generated Output Example#

export const getPetByIdSecurity = [
  { name: "api_key", type: "apiKey", in: "header", paramName: "api_key" }
] as const

This typed security metadata is exported alongside each client function, allowing you to import it and use it for auth routing at runtime (e.g., choosing between API key, Bearer token, or OAuth based on scheme type).

Note: The type-safe document field on Adapter<AdapterOas> is available in @kubb/adapter-oas@5.0.0-alpha.24 and later. TDocument is now the 4th generic parameter in AdapterFactoryOptions, making document access fully type-safe.
v5 Generator API: In v5, use defineGenerator with type: 'react' instead of createReactGenerator. The generator function receives { node, adapter, options, config, driver, resolver } props directly (where node replaces the previous operation parameter). This reflects the v5 architecture where generators use @kubb/ast + @kubb/core instead of @kubb/plugin-oas.

Working examples are available in the examples/generators directory, and the custom generators documentation covers both low-level and React-based generator APIs.