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

Description

@Ignacio-Vidal

Problem Description

The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

As a result, the developer must manually add Quarkus security annotations after generation.

This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

Once agreed, I'm happy to contribute the PRs listed below.

Benefits of emitting Authenticaion & Authorisation annotations

  • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
  • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
  • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
  • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

Solution

Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

AnnotationPackageDescription
@Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
@RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
@PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
@DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
@PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

Annotation placement

Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

Interaction with security configuration in application.yaml

quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

Mapping table

OpenAPI security requirementQuarkus annotationRationale
Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

  • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
  • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

Delivery Plan

List of PRs to incrementally add the security annotations support:

1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

  • http: basic authentication
  • apiKey authentication
  • http: bearer authentication
  • oauth2 or openIdConnect with empty scopes ([])
  • an OR list where at least one alternative has empty scopes
security:
- oauth2_read: [read:items]
- oauth2_admin: []
@io.quarkus.security.Authenticated@GET@Path("/items")
ResponselistItems();

3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

security:
- oauth2_read: [read:items]
- oauth2_admin: [admin]
@jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
@GET@Path("/items")
ResponselistItems();

Also when there is joint set of security schemes and one of them has a role in scopes:

security:
- oauth2_read: []opendIdConent: [admin]
@jakarta.annotation.security.RolesAllowed({"admin"})
@GET@Path("/items")
ResponselistItems();

4: Emit @PermitAll for operations with no security requirement

@jakarta.annotation.security.PermitAll@GET@Path("/health")
ResponsehealthCheck();

Considerations:

  • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
  • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
  • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
  • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
  • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

Alternatives considered

The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

Open Questions:

  • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

Labels

enhancement, jaxrs-spec, quarkus, security

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      , '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 Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes #23691

      Description

      @Ignacio-Vidal

      Problem Description

      The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

      As a result, the developer must manually add Quarkus security annotations after generation.

      This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

      Once agreed, I'm happy to contribute the PRs listed below.

      Benefits of emitting Authenticaion & Authorisation annotations

      • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
      • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
      • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
      • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

      Solution

      Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

      AnnotationPackageDescription
      @Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
      @RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
      @PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
      @DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
      @PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

      Annotation placement

      Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

      Interaction with security configuration in application.yaml

      quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

      The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

      Mapping table

      OpenAPI security requirementQuarkus annotationRationale
      Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
      http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
      http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
      apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
      oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
      openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
      oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
      openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
      OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
      OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

      Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

      OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

      This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

      • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
      • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

      Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

      Delivery Plan

      List of PRs to incrementally add the security annotations support:

      1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

      2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

      • http: basic authentication
      • apiKey authentication
      • http: bearer authentication
      • oauth2 or openIdConnect with empty scopes ([])
      • an OR list where at least one alternative has empty scopes
      security:
      - oauth2_read: [read:items]
      - oauth2_admin: []
      @io.quarkus.security.Authenticated@GET@Path("/items")
      ResponselistItems();

      3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

      security:
      - oauth2_read: [read:items]
      - oauth2_admin: [admin]
      @jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
      @GET@Path("/items")
      ResponselistItems();

      Also when there is joint set of security schemes and one of them has a role in scopes:

      security:
      - oauth2_read: []opendIdConent: [admin]
      @jakarta.annotation.security.RolesAllowed({"admin"})
      @GET@Path("/items")
      ResponselistItems();

      4: Emit @PermitAll for operations with no security requirement

      @jakarta.annotation.security.PermitAll@GET@Path("/health")
      ResponsehealthCheck();

      Considerations:

      • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
      • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
      • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
      • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
      • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

      Alternatives considered

      The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

      Open Questions:

      • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

      Labels

      enhancement, jaxrs-spec, quarkus, security

      Metadata

      Metadata

      Assignees

      No one assigned

        Type

        No type

        Projects

        No projects

          Milestone

          No milestone

          Relationships

          None yet

          Development

          No branches or pull requests

          Issue actions

          , '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 Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes #23691

          Description

          @Ignacio-Vidal

          Problem Description

          The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

          As a result, the developer must manually add Quarkus security annotations after generation.

          This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

          Once agreed, I'm happy to contribute the PRs listed below.

          Benefits of emitting Authenticaion & Authorisation annotations

          • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
          • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
          • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
          • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

          Solution

          Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

          AnnotationPackageDescription
          @Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
          @RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
          @PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
          @DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
          @PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

          Annotation placement

          Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

          Interaction with security configuration in application.yaml

          quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

          The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

          Mapping table

          OpenAPI security requirementQuarkus annotationRationale
          Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
          http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
          http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
          apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
          oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
          openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
          oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
          openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
          OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
          OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

          Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

          OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

          This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

          • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
          • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

          Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

          Delivery Plan

          List of PRs to incrementally add the security annotations support:

          1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

          2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

          • http: basic authentication
          • apiKey authentication
          • http: bearer authentication
          • oauth2 or openIdConnect with empty scopes ([])
          • an OR list where at least one alternative has empty scopes
          security:
          - oauth2_read: [read:items]
          - oauth2_admin: []
          @io.quarkus.security.Authenticated@GET@Path("/items")
          ResponselistItems();

          3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

          security:
          - oauth2_read: [read:items]
          - oauth2_admin: [admin]
          @jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
          @GET@Path("/items")
          ResponselistItems();

          Also when there is joint set of security schemes and one of them has a role in scopes:

          security:
          - oauth2_read: []opendIdConent: [admin]
          @jakarta.annotation.security.RolesAllowed({"admin"})
          @GET@Path("/items")
          ResponselistItems();

          4: Emit @PermitAll for operations with no security requirement

          @jakarta.annotation.security.PermitAll@GET@Path("/health")
          ResponsehealthCheck();

          Considerations:

          • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
          • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
          • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
          • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
          • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

          Alternatives considered

          The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

          Open Questions:

          • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

          Labels

          enhancement, jaxrs-spec, quarkus, security

          Metadata

          Metadata

          Assignees

          No one assigned

            Type

            No type

            Projects

            No projects

              Milestone

              No milestone

              Relationships

              None yet

              Development

              No branches or pull requests

              Issue actions

              , '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 Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes #23691

              Description

              @Ignacio-Vidal

              Problem Description

              The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

              As a result, the developer must manually add Quarkus security annotations after generation.

              This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

              Once agreed, I'm happy to contribute the PRs listed below.

              Benefits of emitting Authenticaion & Authorisation annotations

              • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
              • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
              • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
              • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

              Solution

              Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

              AnnotationPackageDescription
              @Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
              @RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
              @PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
              @DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
              @PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

              Annotation placement

              Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

              Interaction with security configuration in application.yaml

              quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

              The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

              Mapping table

              OpenAPI security requirementQuarkus annotationRationale
              Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
              http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
              http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
              apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
              oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
              openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
              oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
              openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
              OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
              OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

              Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

              OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

              This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

              • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
              • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

              Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

              Delivery Plan

              List of PRs to incrementally add the security annotations support:

              1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

              2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

              • http: basic authentication
              • apiKey authentication
              • http: bearer authentication
              • oauth2 or openIdConnect with empty scopes ([])
              • an OR list where at least one alternative has empty scopes
              security:
              - oauth2_read: [read:items]
              - oauth2_admin: []
              @io.quarkus.security.Authenticated@GET@Path("/items")
              ResponselistItems();

              3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

              security:
              - oauth2_read: [read:items]
              - oauth2_admin: [admin]
              @jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
              @GET@Path("/items")
              ResponselistItems();

              Also when there is joint set of security schemes and one of them has a role in scopes:

              security:
              - oauth2_read: []opendIdConent: [admin]
              @jakarta.annotation.security.RolesAllowed({"admin"})
              @GET@Path("/items")
              ResponselistItems();

              4: Emit @PermitAll for operations with no security requirement

              @jakarta.annotation.security.PermitAll@GET@Path("/health")
              ResponsehealthCheck();

              Considerations:

              • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
              • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
              • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
              • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
              • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

              Alternatives considered

              The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

              Open Questions:

              • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

              Labels

              enhancement, jaxrs-spec, quarkus, security

              Metadata

              Metadata

              Assignees

              No one assigned

                Type

                No type

                Projects

                No projects

                  Milestone

                  No milestone

                  Relationships

                  None yet

                  Development

                  No branches or pull requests

                  Issue actions

                  , '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 Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes #23691

                  Description

                  @Ignacio-Vidal

                  Problem Description

                  The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

                  As a result, the developer must manually add Quarkus security annotations after generation.

                  This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

                  Once agreed, I'm happy to contribute the PRs listed below.

                  Benefits of emitting Authenticaion & Authorisation annotations

                  • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
                  • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
                  • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
                  • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

                  Solution

                  Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

                  AnnotationPackageDescription
                  @Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
                  @RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
                  @PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
                  @DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
                  @PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

                  Annotation placement

                  Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

                  Interaction with security configuration in application.yaml

                  quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

                  The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

                  Mapping table

                  OpenAPI security requirementQuarkus annotationRationale
                  Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
                  http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
                  http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
                  apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
                  oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
                  openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
                  oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
                  openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
                  OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
                  OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

                  Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

                  OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

                  This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

                  • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
                  • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

                  Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

                  Delivery Plan

                  List of PRs to incrementally add the security annotations support:

                  1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

                  2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

                  • http: basic authentication
                  • apiKey authentication
                  • http: bearer authentication
                  • oauth2 or openIdConnect with empty scopes ([])
                  • an OR list where at least one alternative has empty scopes
                  security:
                  - oauth2_read: [read:items]
                  - oauth2_admin: []
                  @io.quarkus.security.Authenticated@GET@Path("/items")
                  ResponselistItems();

                  3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

                  security:
                  - oauth2_read: [read:items]
                  - oauth2_admin: [admin]
                  @jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
                  @GET@Path("/items")
                  ResponselistItems();

                  Also when there is joint set of security schemes and one of them has a role in scopes:

                  security:
                  - oauth2_read: []opendIdConent: [admin]
                  @jakarta.annotation.security.RolesAllowed({"admin"})
                  @GET@Path("/items")
                  ResponselistItems();

                  4: Emit @PermitAll for operations with no security requirement

                  @jakarta.annotation.security.PermitAll@GET@Path("/health")
                  ResponsehealthCheck();

                  Considerations:

                  • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
                  • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
                  • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
                  • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
                  • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

                  Alternatives considered

                  The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

                  Open Questions:

                  • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

                  Labels

                  enhancement, jaxrs-spec, quarkus, security

                  Metadata

                  Metadata

                  Assignees

                  No one assigned

                    Type

                    No type

                    Projects

                    No projects

                      Milestone

                      No milestone

                      Relationships

                      None yet

                      Development

                      No branches or pull requests

                      Issue actions

                      , '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 Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes #23691

                      Description

                      @Ignacio-Vidal

                      Problem Description

                      The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

                      As a result, the developer must manually add Quarkus security annotations after generation.

                      This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

                      Once agreed, I'm happy to contribute the PRs listed below.

                      Benefits of emitting Authenticaion & Authorisation annotations

                      • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
                      • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
                      • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
                      • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

                      Solution

                      Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

                      AnnotationPackageDescription
                      @Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
                      @RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
                      @PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
                      @DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
                      @PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

                      Annotation placement

                      Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

                      Interaction with security configuration in application.yaml

                      quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

                      The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

                      Mapping table

                      OpenAPI security requirementQuarkus annotationRationale
                      Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
                      http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
                      http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
                      apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
                      oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
                      openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
                      oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
                      openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
                      OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
                      OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

                      Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

                      OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

                      This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

                      • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
                      • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

                      Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

                      Delivery Plan

                      List of PRs to incrementally add the security annotations support:

                      1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

                      2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

                      • http: basic authentication
                      • apiKey authentication
                      • http: bearer authentication
                      • oauth2 or openIdConnect with empty scopes ([])
                      • an OR list where at least one alternative has empty scopes
                      security:
                      - oauth2_read: [read:items]
                      - oauth2_admin: []
                      @io.quarkus.security.Authenticated@GET@Path("/items")
                      ResponselistItems();

                      3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

                      security:
                      - oauth2_read: [read:items]
                      - oauth2_admin: [admin]
                      @jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
                      @GET@Path("/items")
                      ResponselistItems();

                      Also when there is joint set of security schemes and one of them has a role in scopes:

                      security:
                      - oauth2_read: []opendIdConent: [admin]
                      @jakarta.annotation.security.RolesAllowed({"admin"})
                      @GET@Path("/items")
                      ResponselistItems();

                      4: Emit @PermitAll for operations with no security requirement

                      @jakarta.annotation.security.PermitAll@GET@Path("/health")
                      ResponsehealthCheck();

                      Considerations:

                      • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
                      • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
                      • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
                      • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
                      • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

                      Alternatives considered

                      The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

                      Open Questions:

                      • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

                      Labels

                      enhancement, jaxrs-spec, quarkus, security

                      Metadata

                      Metadata

                      Assignees

                      No one assigned

                        Type

                        No type

                        Projects

                        No projects

                          Milestone

                          No milestone

                          Relationships

                          None yet

                          Development

                          No branches or pull requests

                          Issue actions

                          , '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 Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes #23691

                          Description

                          @Ignacio-Vidal

                          Problem Description

                          The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

                          As a result, the developer must manually add Quarkus security annotations after generation.

                          This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

                          Once agreed, I'm happy to contribute the PRs listed below.

                          Benefits of emitting Authenticaion & Authorisation annotations

                          • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
                          • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
                          • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
                          • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

                          Solution

                          Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

                          AnnotationPackageDescription
                          @Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
                          @RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
                          @PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
                          @DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
                          @PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

                          Annotation placement

                          Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

                          Interaction with security configuration in application.yaml

                          quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

                          The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

                          Mapping table

                          OpenAPI security requirementQuarkus annotationRationale
                          Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
                          http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
                          http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
                          apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
                          oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
                          openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
                          oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
                          openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
                          OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
                          OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

                          Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

                          OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

                          This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

                          • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
                          • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

                          Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

                          Delivery Plan

                          List of PRs to incrementally add the security annotations support:

                          1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

                          2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

                          • http: basic authentication
                          • apiKey authentication
                          • http: bearer authentication
                          • oauth2 or openIdConnect with empty scopes ([])
                          • an OR list where at least one alternative has empty scopes
                          security:
                          - oauth2_read: [read:items]
                          - oauth2_admin: []
                          @io.quarkus.security.Authenticated@GET@Path("/items")
                          ResponselistItems();

                          3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

                          security:
                          - oauth2_read: [read:items]
                          - oauth2_admin: [admin]
                          @jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
                          @GET@Path("/items")
                          ResponselistItems();

                          Also when there is joint set of security schemes and one of them has a role in scopes:

                          security:
                          - oauth2_read: []opendIdConent: [admin]
                          @jakarta.annotation.security.RolesAllowed({"admin"})
                          @GET@Path("/items")
                          ResponselistItems();

                          4: Emit @PermitAll for operations with no security requirement

                          @jakarta.annotation.security.PermitAll@GET@Path("/health")
                          ResponsehealthCheck();

                          Considerations:

                          • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
                          • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
                          • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
                          • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
                          • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

                          Alternatives considered

                          The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

                          Open Questions:

                          • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

                          Labels

                          enhancement, jaxrs-spec, quarkus, security

                          Metadata

                          Metadata

                          Assignees

                          No one assigned

                            Type

                            No type

                            Projects

                            No projects

                              Milestone

                              No milestone

                              Relationships

                              None yet

                              Development

                              No branches or pull requests

                              Issue actions

                              , '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 Authentication & Authorisation annotations (@Authenticated, @RolesAllowed, @PermitAll) from Security Schemes #23691

                              Description

                              @Ignacio-Vidal

                              Problem Description

                              The [jaxrs-spec][quarkus] library already emits MicroProfile OpenAPI security scheme annotations (@Securityscheme, @securityrequirement) on API interfaces. However, these annotations have no effect at runtime, and are for documentation-only purpose in Swagger UI.

                              As a result, the developer must manually add Quarkus security annotations after generation.

                              This is a proposal to agree the mapping from OpenAPI Security Schemes to Quarkus Authentication/Authorisation mechanisms to emit the annotations during code generation.

                              Once agreed, I'm happy to contribute the PRs listed below.

                              Benefits of emitting Authenticaion & Authorisation annotations

                              • Security by default: generated stubs are immediately deployable with correct access control; developers do not have to remember to add annotations manually
                              • Spec as the source of truth: when the OpenAPI document changes (e.g., a scope is added or removed), regenerating the client automatically updates the security annotations
                              • Quarkus-native developer experience: generated code uses idiomatic Quarkus/Jakarta EE security annotations that developers already know, rather than requiring them to understand how to translate OpenAPI security schemes into Quarkus constructs
                              • Reduced security misconfigurations: missing or incorrect hand-written security annotations are a common source of accidental endpoint exposure; generator-driven annotations eliminate this class of mistake

                              Solution

                              Quarkus implements security based on Jakarta EE security annotations jakarta.annotation.security and its own extensions in io.quarkus.security. These annotations are enforced by Quarkus interceptors at request time.

                              AnnotationPackageDescription
                              @Authenticatedio.quarkus.securityPermits any authenticated user. Equivalent to @RolesAllowed("**").
                              @RolesAllowed({"role1", "role2"})jakarta.annotation.securityPermits users that have at least one of the listed roles (OR semantics within the annotation).
                              @PermitAlljakarta.annotation.securityPermits all users, including unauthenticated ones. Used to mark explicitly public endpoints.
                              @DenyAlljakarta.annotation.securityDenies all access regardless of identity. Used to mark endpoints that must never be called directly via HTTP.
                              @PermissionsAllowedio.quarkus.securityFine-grained permission check against SecurityIdentity permissions. Beyond the scope of generator support.

                              Annotation placement

                              Annotations can be placed on JAX-RS interface methods or on implementation classes. Method-level annotations take precedence over class-level annotations. Quarkus supports annotations on the interface when the implementation class is not directly annotated.

                              Interaction with security configuration in application.yaml

                              quarkus.http.auth.*configuration-based policies (application.yaml) are evaluated before the security annotations. This means @PermitAll does not bypass HTTP-level security configurations from the application.yaml configuration

                              The generator focuses on annotation-based security, which is the standard approach for JAX-RS endpoint security in Quarkus.

                              Mapping table

                              OpenAPI security requirementQuarkus annotationRationale
                              Operation has no security requirement@PermitAllExplicitly marks the endpoint as public so auditors and tooling can identify intentionally open endpoints.
                              http scheme, basic@RolesAllowed({"**"})Basic authentication validates identity; there are no roles or scopes to check. Any valid credential grants access.
                              http scheme, bearer@RolesAllowed({"**"})A Bearer token (e.g., JWT) validates identity. Role/scope enforcement is handled by the OIDC/JWT extension separately; the annotation marks the intent.
                              apiKey@RolesAllowed({"**"})An API key validates identity only. No role check is applicable.
                              oauth2 with empty scopes ([])@RolesAllowed({"**"})An empty scope list means "any authenticated user" — no specific authorization is required beyond a valid token.
                              openIdConnect with empty scopes ([])@RolesAllowed({"**"})Same reasoning as OAuth2 with empty scopes.
                              oauth2 with explicit scopes@RolesAllowed({"scope1", "scope2"})In Quarkus, OAuth2/OIDC token scopes are mapped to SecurityIdentity roles. @RolesAllowed receives the scopes as role names.
                              openIdConnect with explicit scopes@RolesAllowed({"scope1"})Same as OAuth2 with scopes.
                              OR list with at least one empty-scope scheme@RolesAllowed({"**"})The least restrictive alternative dominates: if any scheme allows any authenticated user, the effective gate is authentication only.
                              OR list where all alternatives have scopes@RolesAllowed(union_of_all_scopes)The union of scopes across all OR-alternatives is passed to @RolesAllowed. Since @RolesAllowed itself uses OR semantics (user needs any listed role), this correctly allows a user to satisfy any one of the OR-alternatives.

                              Limitation: OpenAPI OR semantics vs. Quarkus AND annotations

                              OpenAPI's security array is OR: a request is authorized if any one of the listed security alternatives is satisfied. Quarkus standard annotations use AND semantics when stacked: @Authenticated + @RolesAllowed("admin") requires the user to be both authenticated and have the admin role.

                              This means the two models cannot always be reconciled. The generator's strategy is to emit the least restrictive annotation that is still correct for the OR group:

                              • If any alternative has empty scopes → @Authenticated (any authenticated user passes; specific scopes in other alternatives are not enforced at the annotation level)
                              • If all alternatives have explicit scopes → @RolesAllowed(union_of_all_scopes) (user needs any one of the scopes, matching any one alternative)

                              Never emit both @Authenticated and @RolesAllowed on the same method: Quarkus would apply both interceptors, creating AND semantics stricter than the spec intends.

                              Delivery Plan

                              List of PRs to incrementally add the security annotations support:

                              1: Add CLI flag (useQuarkusSecurityAnnotations) to enable emitting security annotation (@authenticated, @RolesAllowed, @permitAll)

                              2: Emit @io.quarkus.security.Authenticated` on JAX-RS interface methods and implementation stubs when an operation's security has:

                              • http: basic authentication
                              • apiKey authentication
                              • http: bearer authentication
                              • oauth2 or openIdConnect with empty scopes ([])
                              • an OR list where at least one alternative has empty scopes
                              security:
                              - oauth2_read: [read:items]
                              - oauth2_admin: []
                              @io.quarkus.security.Authenticated@GET@Path("/items")
                              ResponselistItems();

                              3: Emit @RolesAllowed for operations where all OR-alternatives have explicit scopes. Example:

                              security:
                              - oauth2_read: [read:items]
                              - oauth2_admin: [admin]
                              @jakarta.annotation.security.RolesAllowed({"read:items", "admin"})
                              @GET@Path("/items")
                              ResponselistItems();

                              Also when there is joint set of security schemes and one of them has a role in scopes:

                              security:
                              - oauth2_read: []opendIdConent: [admin]
                              @jakarta.annotation.security.RolesAllowed({"admin"})
                              @GET@Path("/items")
                              ResponselistItems();

                              4: Emit @PermitAll for operations with no security requirement

                              @jakarta.annotation.security.PermitAll@GET@Path("/health")
                              ResponsehealthCheck();

                              Considerations:

                              • @PermissionsAllowed: Quarkus's io.quarkus.security.PermissionsAllowed supports fine-grained permission checks beyond role names. Mapping OpenAPI scopes to permissions (as opposed to roles) requires knowing how the application configures its identity provider. This is out of scope for the generator and left to the developer.
                              • quarkus.security.jaxrs.deny-unannotated-endpoints: The generator could emit a reminder comment or a documentation note suggesting users enable this property alongside the generated annotations for defense-in-depth.
                              • Multi-tenant OIDC: Quarkus supports multi-tenant OIDC (quarkus-oidc). The mapping from an OpenAPI openIdConnect scheme to a specific tenant is not expressible in annotations alone; this is a known limitation.
                              • Global security overrides: OpenAPI allows a global security block at the document level, with per-operation overrides. The generator should ensure it resolves effective security for each operation (global default minus per-operation override) before applying annotation logic. This needs verification in the existing implementation.
                              • @DenyAll: No mapping is proposed from OpenAPI constructs to @DenyAll. If needed, it could be expressed via a vendor extension (x-quarkus-deny-all: true) for operations that should be unreachable via HTTP.

                              Alternatives considered

                              The only alternative is to keep the status quo where developers need to add the Authentication and Authorisation annotations post code generation

                              Open Questions:

                              • Should it introduce a new generator flag to enable/disable emitting the security annotations? This avoids breaking changes for teams already manually managing the security annotations separately from the code generation

                              Labels

                              enhancement, jaxrs-spec, quarkus, security

                              Metadata

                              Metadata

                              Assignees

                              No one assigned

                                Type

                                No type

                                Projects

                                No projects

                                  Milestone

                                  No milestone

                                  Relationships

                                  None yet

                                  Development

                                  No branches or pull requests

                                  Issue actions