PermDock
Decisions

0014: Target OpenAPI 3.2 with 3.1 fallbacks

Why PermDock emits OpenAPI 3.2 security objects and downgrades to 3.1 with x-oai-* extensions when a generator only speaks 3.1.

Status

Accepted, September 2026. The 3.1 fallback rule is amended by 0019: only the registered x-oai-deprecated, x-oai-deviceAuthorization and x-oai-deviceAuthorizationUrl are emitted; oauth2MetadataUrl falls back to x-permdock-oauth2MetadataUrl because no x-oai- name is registered for it, and --openapi-version became --target.

Context

No authorization library emits OpenAPI security from its permission model; every generator (@hono/zod-openapi, hono-openapi, @orpc/openapi, trpc-to-openapi, zod-to-openapi) makes developers attach security by hand per route. PermDock closes that gap: a permission's scope becomes an OAuth scope in securitySchemes, protect(permission) on a route becomes a per-operation security entry plus x-permdock-permissions, and an existing OpenAPI document can be imported into a catalog.

The plan originally said OpenAPI 3.1. OpenAPI 3.2 (September 2025) added exactly the security features the agent story needs: the OAuth 2.0 device authorization flow, oauth2MetadataUrl on OAuth security schemes (which points at the RFC 8414 metadata that MCP clients already discover), deprecated on security schemes, and security schemes referenced by URI. Most generators still emit 3.1 documents, and the OpenAPI Initiative documents x-oai-* extensions as the way to express 3.2 features inside a 3.1 document.

Decision

  • permdock/openapi and permdock openapi target OpenAPI 3.2 by default. Emitted objects use native deviceAuthorization flows, oauth2MetadataUrl and deprecated on security schemes.
  • When the host document or generator is 3.1, PermDock emits the same information as x-oai-* fallback extensions (for example x-oai-oauth2MetadataUrl, x-oai-deviceAuthorization) and leaves the rest of the document at 3.1. The choice is automatic from the document's openapi version and can be forced with --openapi-version.
  • PermDock-specific data always lives in x-permdock-permissions (an array of permission keys per operation) and x-permdock-catalog (document level) regardless of version.
  • Integration hooks target the generators' existing extension points: hono-openapi describeRoute, @hono/zod-openapi createRoute, oRPC oo.spec(middleware, ...), trpc-to-openapi protect.
  • Resource schemas are emitted through Standard JSON Schema (~standard.jsonSchema) with target: 'openapi-3.0' or draft-2020-12 as the document requires; no Zod-specific converter is used.

Consequences

  • Agent-facing APIs get machine-readable scopes and device-flow metadata, which MCP and CLI clients can use for step-up and headless login.
  • Deprecating a permission marks its scheme deprecated in the document, so API consumers see the change before the scope disappears.
  • Two output shapes must be tested; permdock openapi --check diffs both.
  • x-oai-* fallbacks are extensions, so 3.1-only tooling ignores them silently rather than failing; PermDock's own importer reads both.
  • Import (permdock openapi import) produces a definePermissions() file from security scopes and x-permdock-permissions, merging like any feature file.

Alternatives considered

  • Target 3.1 only. Rejected: loses device flow, oauth2MetadataUrl and deprecated, all relevant to agent clients.
  • Target 3.2 only, no fallbacks. Rejected: most generators and viewers still produce or expect 3.1 in 2026.
  • Custom x-permdock-* extensions for 3.2 features. Rejected in favour of the x-oai-* names the OpenAPI Initiative documents, so other tools recognise them.
  • Depend on Zod's OpenAPI converters. Rejected: Standard JSON Schema covers Zod, Valibot and ArkType with one code path and keeps core free of validator-specific dependencies.

On this page