[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined) - #23782

Merged
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all
May 13, 2026
Merged

[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)#23782
wing328 merged 1 commit into
OpenAPITools:masterfrom
Ignacio-Vidal:quarkus-permit-all

Conversation

@Ignacio-Vidal

@Ignacio-VidalIgnacio-Vidal commented May 12, 2026

Copy link
Copy Markdown
Contributor

This is part 4 of #23691 to improve authentication and authorisation support in the jaxrs-spec/quarkus server generator, building on #23680 and #23752.

What this PR does

Extends the useJakartaSecurityAnnotations flag (Quarkus library only, requires useJakartaEe=true) to emit @jakarta.annotation.security.PermitAll on JAX-RS interface methods and implementation stubs for operations whose OpenAPI security requirements mean no authentication is required.

This PR covers the unauthenticated case (@PermitAll). The generator has 3 mutually exclusive emission per operation:

  • `@RolesAllowed({"**}): Any authentication is required
  • `@RolesAllowed({"scope"}): Specific scope is required
  • @PermitAll: No authentication is required

Semantic rules

When @PermitAll is emitted

ConditionResult
Op-level security: [] (explicit opt-out)@PermitAll — overrides any global setting
No op-level security AND global security: []@PermitAll — inherits empty list
No op-level security AND no global security block at all@PermitAll — entire API is unauthenticated
OR list contains an anonymous alternative - {}@PermitAll — least-restrictive alternative wins
Mixed-scope AND group / undefined scheme / other ambiguous caseNo annotation + WARN log (does not fall through to @PermitAll)

Anonymous OR alternative (- {}) — least restrictive wins

OpenAPI 3 allows an empty SecurityRequirement inside the OR list to indicate anonymous access is acceptable alongside other alternatives. When present, the least-restrictive alternative is "no auth required":

security:
- oauth2: [admin]
- {} # anonymous allowed → @PermitAll emitted

This was previously deferred (PR #23680 left these operations unannotated). They now emit @PermitAll.

Global vs per-operation security

Op-level securityGlobal securityResult
[] (empty)anything@PermitAll
absentabsent@PermitAll
absent[] (empty)@PermitAll
absentnon-emptyinherits global — falls through to @RolesAllowed paths
non-emptyanythinguses op-level — falls through to @RolesAllowed paths

Why mixed-scope AND groups do not fall through

PR #23752 already returns null and logs a WARN for AND groups with more than one scoped scheme — Jakarta annotations cannot express AND-of-different-scope-sets. Silently emitting @PermitAll in that case would turn an authorisation gap into a security hole, so the processor explicitly evaluates only the unauthenticated cases above and leaves the operation unannotated otherwise.

Implementation notes

New vendor extension. The processor sets x-jakarta-permit-all = true (mutually exclusive with x-jakarta-roles-allowed) on qualifying operations. The shared partial jakartaSecurityAnnotations.mustache (and the equivalent blocks in apiInterface.mustache / apiMethod.mustache) gains a section guarded by the new extension to emit @jakarta.annotation.security.PermitAll.

Processor changes in JakartaSecurityAnnotationProcessor:

  • Added qualifiesForPermitAll(rawOp, openAPI, effectiveRequirements) that inspects the raw op-level and global security fields (not the already-resolved effective list) so it can distinguish explicit op-level opt-out from inherited global. This is necessary because the resolved list collapses op.security == [] and "no op.security, inherits global == []" into the same value.
  • applyTo now has three short-circuit branches: wildcard @RolesAllowed({"**"}) → scoped @RolesAllowed({scopes})@PermitAll. The first match wins; subsequent branches are skipped.
  • Mutual exclusion is enforced by the data shape: at most one of x-jakarta-roles-allowed and x-jakarta-permit-all is ever set on a given operation.

No changes to JavaJAXRSSpecServerCodegen. The existing fromOperation override from #23680 already delegates to the processor.

CI sample fixturebin/configs/jaxrs-spec-quarkus-security.yaml and samples/server/petstore/jaxrs-spec/quarkus-security/ (added in #23752) gain a PublicApi endpoint that exercises the @PermitAll path end-to-end alongside the existing scoped and wildcard endpoints, so the four annotation outcomes (@PermitAll, @RolesAllowed({"**"}), @RolesAllowed({scope}), @RolesAllowed({scope1,scope2})) all render in the committed sample.

Test coverage

The existing quarkusJakartaSecurityCases data provider (introduced in #23680) is extended with 10 new rows covering the four @PermitAll cases across interfaceOnly={true,false} and useJakartaSecurityAnnotations={true,false}:

ScenarioFixture
Op-level security: [] (overrides non-empty global)quarkus-permit-all-op-empty-security.yaml
Op-level security: [] AND global security: []quarkus-permit-all-op-empty-global-empty.yaml
Op-level security: [] AND non-empty global (per-op opt-out only)quarkus-permit-all-op-empty-global-non-empty.yaml
No security field anywhere in the specquarkus-permit-all-no-security-defined.yaml

Plus targeted tests:

  • quarkusGlobalEmptySecurityListEmitsPermitAll — global security: [] inheritance.
  • quarkusOrAnonymousAlternativeEmitsPermitAll — OR list containing - {}.
  • quarkusNoSecurityDefinedAnywhereEmitsPermitAll — entire spec unauthenticated.
  • quarkusMixedAndGroupDoesNotFallThroughToPermitAll — guards the security-hole regression: mixed-scope AND groups must emit nothing, not @PermitAll.
  • quarkusPermitAllCoexistsWithMicroProfileAnnotations@PermitAll renders alongside MicroProfile @SecurityRequirement annotations on the same method (quarkus-permit-all-microprofile-coexist.yaml).
  • quarkusMixedSecuritySampleEmitsAllExpectedAnnotations — end-to-end check against the committed CI sample asserting all four annotation outcomes render in PublicApi, AuthenticatedApi, AdminApi, AdminOrUserApi, AnonymousOrAuthenticatedApi.

All test rows from #23680 and #23752 continue to pass unchanged.

Closes#23691

PR checklist

  • Read the contribution guidelines.
  • Pull Request title clearly describes the work in the pull request and Pull Request description provides details about how to validate the work. Missing information here may result in delayed response from the community.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    Commit all changed files.
    This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
    These must match the expectations made by your contribution.
    You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example ./bin/generate-samples.sh bin/configs/java*.
    IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
  • File the PR against the correct branch: master (upcoming 7.x.0 minor release - breaking changes with fallbacks), 8.0.x (breaking changes without fallbacks)
  • If your PR solves a reported issue, reference it using GitHub's linking syntax (e.g., having "fixes #123" present in the PR description)
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

Summary by cubic

Generate @PermitAll for unauthenticated endpoints in the jaxrs-specquarkus generator, and keep Jakarta security annotations mutually exclusive with wildcard or scoped @RolesAllowed. Generated APIs now cleanly mirror OpenAPI security: public, any-authenticated, or role-scoped.

  • New Features
    • Emit @PermitAll when an operation is unauthenticated: op-level security: [], global security: [], no security anywhere, or an OR list with {}.
    • Keep @RolesAllowed({"**"}) for “any authenticated user”; emit scoped @RolesAllowed({"admin","user"}) when all OR alternatives are scoped (unioned/deduped/sorted). For mixed-scope AND groups, log and emit nothing.
    • Enforce mutual exclusion between @PermitAll, wildcard @RolesAllowed, and scoped @RolesAllowed, driven by x-jakarta-permit-all and x-jakarta-roles-allowed. Updated apiInterface.mustache and apiMethod.mustache to render them.
    • Add sample AnonymousOrAuthenticatedApi and new test fixtures to cover global empty security, op-level opt-out, anonymous OR alternatives, “no security defined,” and coexistence with MicroProfile annotations.

Written for commit 27b61d5. Summary will update on new commits.

@Ignacio-VidalIgnacio-Vidal changed the title [jaxrs-spec][quarkus] Emit @PermitAll for endpoints with no security requirement[jaxrs-spec][quarkus] Emit @PermitAll for unauthenticated operations (op/global empty security, anonymous OR alternative, no security defined)May 12, 2026
@Ignacio-Vidal
Ignacio-Vidal marked this pull request as ready for review May 12, 2026 22:45

@cubic-dev-aicubic-dev-aiBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 37 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native">
<violation number="1" location="samples/server/petstore/jaxrs-spec/quarkus-security/src/main/docker/Dockerfile.native:17">
P1: Container runs as root because no non-root `USER` is set. The sibling `Dockerfile.jvm` in the same directory explicitly uses `USER 1001`, but this native Dockerfile is missing the non-root user hardening.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

…e security handling for unauthenticated operations
@Ignacio-Vidal

Ignacio-Vidal commented May 13, 2026

Copy link
Copy Markdown
ContributorAuthor

@wing328 - This is the final MR for #23691. Whilst technically it doesn't have any functional impact because emits a no-op annotation @PermitAll, it completes the loop to emit jakarta annotations for all security scenarios [no-authentication, any-authentication,role-authorisation]

Tested in a separate project:

  • See the api spec with all cases covered in this MR
  • See the adapter implementing the generated interface
  • See the integration tests using the generated client with microprofile library
image

@wing328
wing328 merged commit a3d7b47 into OpenAPITools:masterMay 13, 2026
37 checks passed
@wing328

Copy link
Copy Markdown
Member

@Ignacio-Vidal just merged. Thanks for all your contributions 👍

@Ignacio-Vidal

Copy link
Copy Markdown
ContributorAuthor

Perfect, thank you for the quick reviews

@wing328wing328 added this to the 7.23.0 milestone Jun 1, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[jaxrs-spec][quarkus] - Emit Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes

2 participants

@Ignacio-Vidal@wing328