Skip to content

Inconsistent security scheme context keys across multiple specs when using shared YAML #2383

@brandesign

Description

@brandesign

PR #1187 introduced typed context keys for security scheme scopes.
In our setup, we split the API specification into multiple YAML files and share common definitions (including security schemes) via a shared.yaml. This approach works well for request and response objects: in the generated code, these types are properly referenced and aliased across the different generated packages.
However, this behavior does not apply to security scheme context keys. Previously, security schemes defined in the shared YAML were effectively shared because the context keys were simple strings with identical values. Since PR #1187, each generated server now defines its own distinct context key types for the same security schemes.
This creates issues in our authentication middleware. We use a shared middleware across multiple generated servers and rely on consistent context keys to determine whether to enforce or skip authentication. With different context key types per generated server, this becomes difficult to manage.

Expected behavior

Security scheme context keys defined in a shared OpenAPI YAML should be reusable across generated code, similar to how request and response objects are referenced and aliased.

Suggestion

It would be helpful if security scheme context keys could also be referenced/shared across generated packages when defined in a common YAML, instead of being generated independently for each server.

Example configuration:

# common.yaml
---
openapi: '3.0.1'
info:
  title: Common Types
  version: '1.0'
paths: {}
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

    BasicAuth:
      type: http
      scheme: basic
# user.yaml
---
openapi: 3.0.1
info:
  title: User API
  version: 1.0.0
security:
  - BearerAuth: []
paths:
  /user:
    get:
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: './common.yml#/components/schemas/User'
        '400':
          $ref: './common.yml#/components/responses/400'
        '401':
          $ref: './common.yml#/components/responses/401'
        '500':
          $ref: './common.yml#/components/responses/500'
components:
  securitySchemes:
    BearerAuth:
      $ref: './common.yml#/components/securitySchemes/BearerAuth'
# common/config.yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json
---
package: common
output-options:
  name-normalizer: ToCamelCase
  prefer-skip-optional-pointer: true
  prefer-skip-optional-pointer-with-omitzero: true
  prefer-skip-optional-pointer-on-container-types: true
  skip-prune: true
output: common.gen.go
generate:
  models: true
  strict-server: true
# user/config.yaml
# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json
---
package: user
output-options:
  name-normalizer: ToCamelCase
  prefer-skip-optional-pointer: true
  prefer-skip-optional-pointer-with-omitzero: true
  prefer-skip-optional-pointer-on-container-types: true
output: server.gen.go
generate:
  models: true
  chi-server: true
  strict-server: true
import-mapping:
  ./common.yml: 'my-project/common'

In the middleware then I would like to use ctx.Value(common.BearerAuthScopes).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions