Skip to content

fix: allow anonymous security alternatives#2432

Merged
mromaszewicz merged 6 commits into
oapi-codegen:mainfrom
kriptoburak:codex/optional-security-anonymous
Jul 7, 2026
Merged

fix: allow anonymous security alternatives#2432
mromaszewicz merged 6 commits into
oapi-codegen:mainfrom
kriptoburak:codex/optional-security-anonymous

Conversation

@kriptoburak

Copy link
Copy Markdown
Contributor

Summary

  • Treat an empty security requirement as an anonymous alternative when describing operation security.
  • Regenerate the issue 518 fixture so optional bearer auth does not emit per-operation scopes.

Validation

  • go test ./issues/issue518 from internal/test.
  • go test ./pkg/codegen.
  • Diff whitespace check passed.

@kriptoburak
kriptoburak requested a review from a team as a code owner July 2, 2026 21:51
@greptile-apps

greptile-apps Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes DescribeSecurityDefinition in pkg/codegen/operations.go so that an empty {} security alternative causes the function to return nil, preventing any named scheme's scopes from being embedded in the request context for that operation. The fiber test fixture and its spec are updated to match.

  • operations.go: adds a len(sr) == 0 early-return inside the security-requirements loop so operations with an anonymous alternative no longer emit per-operation scope context keys.
  • middleware.gen.go: regenerated — BearerAuthScopes constant and SetUserValue call are dropped from the AuthCheck wrapper; bearerAuthContextKey type declaration remains but is now unused.
  • main_test.go: test cases updated to reflect the new allow-anonymous behavior; a new snapshot test asserts SetUserValue is absent from the committed generated file.

Confidence Score: 5/5

Safe to merge; the logic change is a one-liner with correct OpenAPI semantics and is covered by tests.

The fix is narrow and correct — an empty security requirement is the standard OpenAPI way to declare an anonymous alternative, and returning nil from DescribeSecurityDefinition is the right response. All changed files are internally consistent: spec, generator logic, generated fixture, and tests all agree.

No files require special attention beyond the orphaned bearerAuthContextKey type in the generated file, which is cosmetic.

Important Files Changed

Filename Overview
pkg/codegen/operations.go Adds early-return in DescribeSecurityDefinition when an empty security requirement is found, making the whole operation anonymous. Correct OpenAPI semantics; order-dependence of the early-return is noted in a prior thread.
internal/test/servers/middleware/fiber/middleware.gen.go Regenerated: removes BearerAuthScopes const and SetUserValue call from AuthCheck wrapper. bearerAuthContextKey type is now an orphan, but Go does not error on unused types so it compiles fine.
internal/test/servers/middleware/fiber/main_test.go Tests updated to reflect anonymous alternative behaviour; new snapshot test checks generated file omits SetUserValue. assert.True for runtime.Caller and the assert/require pattern discussed in previous thread.
internal/test/servers/middleware/fiber/spec.yaml Adds empty {} security alternative before bearerAuth on /auth-check, triggering the new early-return path.
README.md Adds documentation about empty-security-alternative behaviour; removes stale 'future plan' sentence about server-side validation.

Reviews (2): Last reviewed commit: "Update Readme" | Re-trigger Greptile

Comment thread internal/test/servers/middleware/fiber/main_test.go
Comment thread pkg/codegen/operations.go
@mromaszewicz mromaszewicz added the bug Something isn't working label Jul 7, 2026
@mromaszewicz

Copy link
Copy Markdown
Member

This PR kind of relates to #1524

I think that putting the scopes into the generated code was a mistake, and auth middleware should use the OpenAPI spec, rather than the generated code, to make the authentication decision.

Our own middleware already doesn't touch the generated scope keys. That being said, the presence of the anonymous scope hides the presence of other required scopes. In an ideal world, you'd have both of those pieces of information available; the required scopes, and the presence of the anonymous scope.

I need to think about this a little.

I'm honestly leaning towards removing scopes altogether from the generated code (and adding a backward compatibility flag to put them back), and encouraging people never to use this. It was a mistake.

@mromaszewicz

Copy link
Copy Markdown
Member

I will fix up and merge this PR, mostly as-is, but add an additional commit myself which will deprecate the API scope keys, and put them behind a compatibility flag. This mistake needs to go away. It leads to insecure, fragile code, even though it was convenient when I originally wrote it many years ago.

# Conflicts:
#	internal/test/servers/middleware/fiber/main_test.go
…rnatives

Specs that already list an empty `{}` security alternative alongside named
schemes previously still had the scheme's scopes context key (such as
`BearerAuthScopes`) set by generated middleware. After regenerating, that key
is no longer set for such operations, so authentication middleware that
enforces auth based on its presence will treat those requests as anonymous.
Call this out explicitly in the security documentation.
@mromaszewicz mromaszewicz added the notable changes Used for release notes to highlight these more highly label Jul 7, 2026
@mromaszewicz

Copy link
Copy Markdown
Member

Note to self: Document in the release notes the behavior change around {}. It is, I believe, correct behavior within the incorrect framework of these context embedded scopes.

@mromaszewicz
mromaszewicz merged commit 0169838 into oapi-codegen:main Jul 7, 2026
15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working notable changes Used for release notes to highlight these more highly

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants