Skip to content

Conversation

@zibet27
Copy link
Collaborator

@zibet27 zibet27 commented Dec 10, 2025

OpenAPI Security. KTOR-9085 Infer security schemes from the Authentication plugin.

Subsystem
Server OpeAPI.

Motivation
KTOR-9085 Read OpenAPI security details from authentication plugin

Solution
New API:

  • Introduced securitySchemes as an OpenAPI Spec component. It has all implementations described in the spec
  • Added application attribute to store all security schemes globally.
  • Security schemes can be added manually or inferred from the Authentication plugin (we allow combining these approaches, manual has higher priority).
  • :ktor-server-routine-annotate now depends on ktor-server-auth via compileTime. If a developer tries to infer smth from the auth plugin that isn't installed, it should throw a runtime error. It seems to be working, but I'm not sure about non-JVM platforms.
  • Not sure if security schema description should be null or "general" by default(see code).

Changes to old API:

  • Added optional description field toAuthenticationProvider and its descendants with new helper functions. Used for API docs only.
  • Added settings property inside OAuthAuthenticationProvider, which works like providerLookup but static, allows generating OpenAPI docs and should be a bit faster.
  • Added OAuth2ServerSettings.refreshUrl and defaultScopeDescriptions for docs purposes.
  • Made some auth plugin API public with @InternalAPI instead of internal.

@zibet27 zibet27 requested review from bjhham, e5l and marychatte December 10, 2025 14:42
@zibet27 zibet27 self-assigned this Dec 10, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 10, 2025

Walkthrough

Adds optional provider descriptions and description-aware overloads across authentication providers, exposes provider/session keys and provider listings, makes OAuth providerLookup nullable with settings fallback, introduces OpenAPI security-scheme model and registration/inference APIs, and adds related tests and synthetic API entries.

Changes

Cohort / File(s) Summary
Auth: provider description plumbing
ktor-server/ktor-server-plugins/ktor-server-auth/.../AuthenticationProvider.kt, .../DynamicProviderConfig.kt, .../BasicAuth.kt, .../BearerAuth.kt, .../FormAuth.kt, .../DigestAuth.kt, .../SessionAuth.kt, .../JWTAuth.kt, .../OAuthProcedure.kt, .../apikey/*
Add description: String? to provider Config constructors and AuthenticationConfig helper overloads (basic, bearer, form, digest, session, oauth, apiKey, jwt); propagate to AuthenticationProvider.description; add new overloads and synthetic default methods.
Auth core & routing interceptors
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt, .../AuthenticationInterceptors.kt, .../AuthenticationRouteSelector.kt
Add provider(name, description, ...) overload; introduce Authentication.configuration() extension; expose AuthenticationConfig.allProviders(); promote AuthenticateProvidersRegistration and AuthenticateProvidersKey (annotated @InternalAPI); add AuthenticationRouteSelector.DEFAULT_NAME companion and adjust Route.authenticate overloads.
OAuth & OAuth2 settings
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt, .../OAuthProcedure.kt, .../jvm/src/io/ktor/server/auth/OAuth.kt
Add refreshUrl and defaultScopeDescriptions to OAuth2ServerSettings; make OAuthAuthenticationProvider.Config accept description, expose nullable providerLookup and settings, validate build() requires one, add staticSettings() helper, and resolve with providerLookup?.invoke(call) ?: settings.
Sessions: keys & opt-in
ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt, .../SessionTrackerById.kt, .../api/ktor-server-sessions.api, .../klib.api
Expose SessionProvidersKey as public annotated @InternalAPI; add @OptIn(InternalAPI::class) where required; annotate sessionId accessors; update api/klib entries to expose session-related keys and accessors.
OpenAPI security schemes & model
ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt, .../OpenApiSpecification.kt, .../JsonSchema.kt, .../api/*.api, .../klib.api
Introduce SecurityScheme interface, concrete schemes (HttpSecurityScheme, ApiKeySecurityScheme, OAuth2SecurityScheme, OpenIdConnectSecurityScheme), enums (SecuritySchemeIn, SecuritySchemeType), OAuthFlows/OAuthFlow, serializers/Companions, add securitySchemes to Components, and related serializer/annotation adjustments.
Routing-annotate: registration & inference
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt, .../jvm/src/.../SecuritySchemeAnnotation.jvm.kt, .../nonJvm/src/.../SecuritySchemeAnnotation.nonJvm.kt, .../build.gradle.kts
Add Application-level APIs to register/find security schemes, attribute keys for schemes and cache, inference from Authentication providers with platform hooks (JVM adds Digest/JWT inference), registration helpers, tests, and dependency updates.
Tests: security scheme inference & auth adjustments
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/.../SecuritySchemeInferenceTest.kt, .../jvm/test/.../JvmSecuritySchemeInferenceTest.kt, .../RouteAnnotationApiTest.kt, various auth tests
Add tests covering inference and registration for multiple provider types, JVM-specific tests for Digest/JWT, update some test wiring (explicit settings references), and opt-in InternalAPI where needed.
Api-surface / synthetic entries & misc
ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api, ktor-server/ktor-server-plugins/ktor-server-auth-api-key/api/*.api, other api/klib.api files
Generated API entries for new overloads and getters (e.g., jwt/apiKey synthetic defaults, ApiKeyAuthenticationProvider.headerName, AuthenticateProvidersRegistration, session/provider keys), KDoc and header updates, minor exception-name adjustments.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Points to focus on:

  • OAuth: OAuthAuthenticationProvider.Config.build() validation, providerLookup nullable vs settings fallback, and staticSettings() semantics.
  • Ensure description is consistently propagated across helper overloads, provider constructors, and synthetic/default method signatures.
  • Visibility/annotation changes for promoted internals (AuthenticateProvidersKey, SessionProvidersKey) and correct @OptIn(InternalAPI::class) placements.
  • OpenAPI: serializer/Companion implementations and Components.securitySchemes integration across api/klib.
  • Platform-specific inference: JVM digest/JWT inference vs non-JVM stub behavior.

Possibly related PRs

Suggested reviewers

  • bjhham
  • marychatte

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 41.75% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: inferring security schemes from the Authentication plugin, addressing KTOR-9085.
Description check ✅ Passed The pull request description covers all required template sections and provides comprehensive details about the subsystem, motivation, and solution with clear explanations of API changes.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch zibet27/open-api-auth

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@zibet27 zibet27 force-pushed the zibet27/open-api-auth branch from c528817 to e248449 Compare December 10, 2025 14:47
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Nitpick comments (11)
ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt (1)

13-14: Consider adding KDoc for the newly public API.

The @InternalAPI annotation is correctly applied per coding guidelines. However, since this is now a public API (even if internal), consider adding brief documentation explaining its purpose and warning about stability.

+/**
+ * Attribute key used to store session providers in the application attributes.
+ * Can be used to retrieve registered session providers for documentation generation.
+ */
 @InternalAPI
 public val SessionProvidersKey: AttributeKey<List<SessionProvider<*>>> = AttributeKey("SessionProvidersKey")
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1)

11-14: LGTM! No-op implementation is appropriate for non-JVM platforms.

The implementation correctly returns null for non-JVM platforms where platform-specific metadata isn't available for inferring security schemes from authentication providers. This aligns with the comment and is the expected behavior for platforms without JVM reflection capabilities.

Optional improvement: Consider adding KDoc to document this platform-specific behavior, even though it's an internal function. This would help clarify the multiplatform contract, especially since the PR objectives note that "behavior on non-JVM platforms is uncertain."

Example KDoc:

+/**
+ * Infers a security scheme from the authentication provider using platform-specific metadata.
+ * @return null on non-JVM platforms as platform-specific metadata is not available.
+ */
 internal actual fun Application.inferPlatformSpecificSecurityScheme(provider: AuthenticationProvider): SecurityScheme? {
     // No platform-specific metadata for authentication providers on non-JVM platforms.
     return null
 }
ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt (1)

7-10: InternalAPI import is correct; consider aligning with star-import convention

Importing io.ktor.utils.io.InternalAPI is correct for using the opt‑in annotation. If ./gradlew formatKotlin doesn’t already normalize this, consider switching to import io.ktor.utils.io.* to match the “use star imports for io.ktor.* packages” guideline.

ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt (1)

92-130: Add KDoc for OAuth2SecurityScheme and OpenIdConnectSecurityScheme

Unlike the other new public types, OAuth2SecurityScheme and OpenIdConnectSecurityScheme lack KDoc. To comply with the guideline that all public APIs be documented, consider adding brief class-level docs (and, if useful, property tags) mirroring the style used for HttpSecurityScheme and ApiKeySecurityScheme.

ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api (1)

416-429: Clarify expectations around OAuth static settings and nullability

OAuthAuthenticationProvider.Config now exposes settings and OAuthProcedureKt.staticSettings(provider) returns a non-null OAuthServerSettings, while provider lookup is also still configurable. To avoid surprising runtime behavior:

  • Ensure it is clearly documented whether settings is required (and whether staticSettings throws if it’s missing) versus optional.
  • Consider validating configuration eagerly (e.g., at provider installation) so a misconfigured provider (no settings and no providerLookup, or incompatible type) fails fast rather than leading to silent skips at use sites.
    These semantics are important now that OpenAPI inference depends on static settings.

Also applies to: 479-486, 505-526

ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth.kt (1)

10-17: Handle misconfigured OAuth providers more explicitly

Using providerLookup?.invoke(call) ?: settings makes sense, but if both are null or yield a non-OAuth1a settings instance, oauth1a will just return without issuing a challenge, effectively disabling auth on that route. If that scenario is considered misconfiguration rather than “no auth”, consider failing fast (e.g., throwing during provider setup or logging a warning) so it’s detectable instead of silently skipping authentication.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (2)

197-258: HttpClient instances are not closed after use.

The HttpClient() instances created at lines 210 and 225 are never closed, which can cause resource leaks. While this may be acceptable in test code since the JVM terminates, it's a good practice to close clients.

Consider closing the clients or using testApplication's client:

-            oauth("oauth-no-desc") {
-                urlProvider = { "http://localhost/callback" }
-                settings = OAuthServerSettings.OAuth2ServerSettings(
-                    name = "test",
-                    authorizeUrl = "https://auth.example.com/authorize",
-                    accessTokenUrl = "https://auth.example.com/token",
-                    clientId = "client",
-                    clientSecret = "secret",
-                    defaultScopes = listOf("profile", "email")
-                )
-                client = HttpClient()
-            }
+            oauth("oauth-no-desc") {
+                urlProvider = { "http://localhost/callback" }
+                settings = OAuthServerSettings.OAuth2ServerSettings(
+                    name = "test",
+                    authorizeUrl = "https://auth.example.com/authorize",
+                    accessTokenUrl = "https://auth.example.com/token",
+                    clientId = "client",
+                    clientSecret = "secret",
+                    defaultScopes = listOf("profile", "email")
+                )
+                client = this@testApplication.client
+            }

109-113: Consider moving test data classes to a shared location or making them private.

The UserSession and ApiSession classes are defined inside the test class but are public. If they're only used within this test file, consider making them private to reduce unnecessary public API surface in test code.

-    @Serializable
-    data class UserSession(val userId: String)
-
-    @Serializable
-    data class ApiSession(val token: String)
+    @Serializable
+    private data class UserSession(val userId: String)
+
+    @Serializable
+    private data class ApiSession(val token: String)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt (1)

212-215: Missing KDoc documentation for newly public API.

The allProviders() function is now public but lacks KDoc documentation. As per coding guidelines, all public APIs should include documentation with parameters, return types, and exceptions.

+/**
+ * Returns all registered authentication providers.
+ *
+ * @return A map of provider names to their [AuthenticationProvider] instances,
+ *         where `null` key represents the default provider.
+ */
 @OptIn(InternalAPI::class)
 public fun AuthenticationConfig.allProviders(): Map<String?, AuthenticationProvider> {
     return providers
 }
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (2)

31-38: Variable shadowing reduces clarity.

The local providerName shadows the parameter with the same name. Consider using a distinct name.

 public fun Application.registerSecurityScheme(
     providerName: String?,
     securityScheme: SecurityScheme
 ) {
-    val providerName = providerName ?: AuthenticationRouteSelector.DEFAULT_NAME
+    val resolvedName = providerName ?: AuthenticationRouteSelector.DEFAULT_NAME
     val existingSchemes = attributes.getOrNull(AuthenticationSecuritySchemesAttributeKey) ?: emptyMap()
-    attributes.put(AuthenticationSecuritySchemesAttributeKey, existingSchemes + (providerName to securityScheme))
+    attributes.put(AuthenticationSecuritySchemesAttributeKey, existingSchemes + (resolvedName to securityScheme))
 }

102-121: Minor code duplication in transport handling.

The transport type is checked twice - once for keyLocation and once for keyName. Consider consolidating.

         is SessionAuthenticationProvider<*> -> {
             val sessionProvider =
                 attributes.getOrNull(SessionProvidersKey)?.firstOrNull { it.type == provider.type } ?: return null
-            val keyLocation = when (sessionProvider.transport) {
-                is SessionTransportCookie -> SecuritySchemeIn.COOKIE
-                is SessionTransportHeader -> SecuritySchemeIn.HEADER
-                else -> return null
-            }
-            val keyName = when (val t = sessionProvider.transport) {
-                is SessionTransportCookie -> t.name
-                is SessionTransportHeader -> t.name
-                else -> return null
-            }
+            val (keyLocation, keyName) = when (val t = sessionProvider.transport) {
+                is SessionTransportCookie -> SecuritySchemeIn.COOKIE to t.name
+                is SessionTransportHeader -> SecuritySchemeIn.HEADER to t.name
+                else -> return null
+            }
             ApiKeySecurityScheme(
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between de5c910 and c528817.

📒 Files selected for processing (33)
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (6 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api (15 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api (15 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt (3 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt (9 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt (5 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt (5 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (7 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt (3 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt (6 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth.kt (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.klib.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt (3 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt (3 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api (9 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api (7 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt (2 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt (6 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Follow Kotlin official style guide (https://kotlinlang.org/docs/coding-conventions.html)
Use star imports for io.ktor.* packages
Document all public APIs including parameters, return types, and exceptions
Mark internal APIs with @InternalAPI annotation
Run ./gradlew lintKotlin and fix all linting issues before giving control back to the user
Use ./gradlew formatKotlin to automatically fix formatting issues
Run ./gradlew updateLegacyAbi after making ABI changes to update ABI signature files
Binary compatibility is enforced - all public API changes must be tracked in the /api/ directories
Validate ABI with ./gradlew checkLegacyAbi and update with ./gradlew updateLegacyAbi
API changes must be intentional and well-documented
Error handling follows Kotlin conventions with specific Ktor exceptions

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
**/test/**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

Follow test naming pattern: DescribeWhatIsBeingTested

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
🧠 Learnings (20)
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Mark internal APIs with `InternalAPI` annotation

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
📚 Learning: 2025-05-14T18:05:02.321Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.klib.api:334-336
Timestamp: 2025-05-14T18:05:02.321Z
Learning: Breaking changes in constructor parameter order are acceptable for the ktor-server-di module when the code hasn't been released yet, as confirmed by the development team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-06-23T12:49:56.883Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-06-23T12:49:56.883Z
Learning: Error handling should follow Kotlin conventions and use specific Ktor exceptions.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Error handling follows Kotlin conventions with specific Ktor exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : API changes must be intentional and well-documented

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/test/**/*.kt : Follow test naming pattern: `DescribeWhatIsBeingTested`

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
📚 Learning: 2025-06-16T17:03:45.729Z
Learnt from: tre3p
Repo: ktorio/ktor PR: 4936
File: ktor-utils/jvm/src/io/ktor/util/ZstdEncoding.kt:28-35
Timestamp: 2025-06-16T17:03:45.729Z
Learning: In the Ktor codebase, encoder implementations consistently use GlobalScope.writer and GlobalScope.reader patterns for compression/decompression operations. This is the established architectural pattern used throughout the codebase for byte channel transformations.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Use star imports for `io.ktor.*` packages

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: The headersOf() function from io.ktor.http package is available through wildcard imports like `import io.ktor.http.*`, so no explicit import statement is needed when using wildcard imports from that package.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
📚 Learning: 2025-05-16T13:11:28.416Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4860
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.api:24-26
Timestamp: 2025-05-16T13:11:28.416Z
Learning: Binary incompatible changes (such as constructor signature changes) are acceptable in the ktor-server-di module when the version is not yet released, as confirmed by the development team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Cargo plugin (dev.gobley.cargo) used in the Ktor WebRTC RS module depends on the kotlin("plugin.atomicfu") plugin, so atomicfu should not be removed even if there are no direct kotlinx.atomicfu imports in the module's source code.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Binary compatibility is enforced - all public API changes must be tracked in the `/api/` directories

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Gobley Cargo plugin (dev.gobley.cargo) used in the Ktor WebRTC RS module requires the kotlin("plugin.atomicfu") plugin as a dependency, so the atomicfu plugin should not be removed even if there are no direct kotlinx.atomicfu imports in the module's source code.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-05-08T09:52:11.723Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4836
File: build-logic/src/main/kotlin/ktorbuild.project.server-plugin.gradle.kts:12-12
Timestamp: 2025-05-08T09:52:11.723Z
Learning: In the Ktor project's flattened Gradle structure, projects are declared using a custom DSL with the unary plus operator inside specialized blocks. For example, server projects are declared with `+"project-name"` inside a `server {}` block within the main `projects {}` block. When verifying project declarations, search for `+"project-name"` rather than traditional `include(":project-name")` statements.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Document all public APIs including parameters, return types, and exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-05-07T13:42:29.388Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4822
File: ktor-server/ktor-server-plugins/ktor-server-i18n/build.gradle.kts:13-17
Timestamp: 2025-05-07T13:42:29.388Z
Learning: In Kotlin build scripts (build.gradle.kts), the preferred syntax for declaring dependencies is using the dot notation like `jvmTest.dependencies { ... }` rather than the nested version `jvmTest { dependencies { ... } }` as it reduces the nesting level by one and improves readability.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-10-15T16:47:28.272Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:442-444
Timestamp: 2025-10-15T16:47:28.272Z
Learning: In the ktor-openapi-schema module, the maintainer prefers to keep certain properties mutable (using `var` instead of `val`) in data classes like Response, even when they are part of the public API, to allow flexibility during construction and modification.

Applied to files:

  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-11-26T11:34:00.471Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5206
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt:150-150
Timestamp: 2025-11-26T11:34:00.471Z
Learning: In OpenAPI 3.1.1 specification, the Components.schemas field is defined as Map[string, Schema Object] and does NOT allow Reference Objects at the top level, unlike other component fields (responses, parameters, examples, requestBodies, headers, links, callbacks) which are defined as Map[string, <Type> | Reference Object].

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
📚 Learning: 2025-10-15T16:46:27.493Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:43-43
Timestamp: 2025-10-15T16:46:27.493Z
Learning: In the ktor-openapi-schema module, Operation objects (and related OpenAPI objects) are designed to be composable and can be combined from multiple sources. Therefore, properties like `responses` should remain nullable to support intermediate states during object composition/merging.

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-05-13T10:24:59.359Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4849
File: ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DependencyRegistry.kt:114-115
Timestamp: 2025-05-13T10:24:59.359Z
Learning: The `provide` function in DependencyRegistry intentionally accepts `DependencyResolver.() -> T?` (nullable return) while passing it to `set` which expects `DependencyResolver.() -> T` (non-nullable return). This is a deliberate design choice to support Java interoperability through Kotlin's flexible types system.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
🧬 Code graph analysis (4)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1)
  • registerSecurityScheme (31-38)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (5)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt (2)
  • basic (112-117)
  • basic (126-134)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt (2)
  • bearer (120-125)
  • bearer (134-141)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt (2)
  • form (140-145)
  • form (154-161)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (2)
  • oauth (110-115)
  • oauth (125-132)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (3)
  • registerOpenIdConnectSecurityScheme (224-230)
  • registerBearerAuthSecurityScheme (173-182)
  • registerBasicAuthSecurityScheme (159-164)
ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt (1)
ktor-utils/common/src/io/ktor/util/Attributes.kt (1)
  • AttributeKey (19-21)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (3)
ktor-utils/common/src/io/ktor/util/Attributes.kt (1)
  • AttributeKey (19-21)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1)
  • inferPlatformSpecificSecurityScheme (14-27)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1)
  • inferPlatformSpecificSecurityScheme (11-14)
🪛 ast-grep (0.40.0)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt

[warning] 20-20: A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive data, can be leaked and used by internal or external malicious actors. It is recommended to rotate the secret and retrieve them from a secure secret vault or Hardware Security Module (HSM), alternatively environment variables can be used if allowed by your company policy.
Context: Algorithm.HMAC256(jwtSecret)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A03:2021]: Identification and Authentication Failures [REFERENCES]
- https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures

(jwt-hardcode-kotlin)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (5)
ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api (1)

1604-1812: Address the Schema vs JsonSchema duplication.

The Schema class (lines 1604-1812) appears to be a complete duplicate of JsonSchema with identical structure (39 properties, same nested types). This duplication needs clarification:

  1. If intentional, document the purpose and when to use Schema vs JsonSchema
  2. If unintended, remove the duplicate from the public API

This is particularly concerning given that SchemaInferenceKt.buildJsonSchema() at line 1810-1812 returns Schema instead of JsonSchema.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1)

106-124: Align default digest description across tests.

testInferDigestAuthenticationProvider (Line 23) asserts the default digest description as "HTTP Digest Authentication" (Line 52), but testRegisterDigestAuthSecurityScheme here expects "Http Digest Authentication" (Line 117). Unless registerDigestAuthSecurityScheme is intentionally using a different default text than the inference path, these two tests cannot both be correct.

Recommend asserting against the same default as the inference test, ideally via the shared constant:

-        assertEquals("Http Digest Authentication", scheme1.description)
+        assertEquals(HttpSecurityScheme.DEFAULT_DIGEST_DESCRIPTION, scheme1.description)

(or update both tests to a common string) so the contract is consistent between inference and explicit registration.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1)

123-129: Form authentication mapped to non-standard HTTP scheme "form".

FormAuthenticationProvider is turned into an HttpSecurityScheme with scheme = "form". In OpenAPI, for type: "http" the scheme value is expected to be an HTTP authentication scheme token (typically an IANA-registered scheme like basic, bearer, digest), and "form" is not one of them. Using a non-standard scheme here is likely to confuse tooling or violate validators.

Given that form auth is body/parameter-based rather than an Authorization header scheme, it may be safer to omit automatic inference for FormAuthenticationProvider and require users to register an appropriate security scheme manually (e.g., via registerApiKeySecurityScheme or custom docs), rather than emitting a non-standard "form" scheme.

ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (1)

102-102: Minor grammatical error in documentation.

The doc comment reads "or null it is unavailable" but should be "or null if it is unavailable".

-     * @return a claim's value, or null it is unavailable or not a string
+     * @return a claim's value, or null if it is unavailable or not a string
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (1)

67-72: Incorrect KDoc @fqname reference.

The @fqname in the "Report a problem" link for settings incorrectly references providerLookup instead of settings.

         /**
          * Static OAuth server settings. Either this or [providerLookup] should be specified.
          *
-         * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAuthenticationProvider.Config.providerLookup)
+         * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.OAuthAuthenticationProvider.Config.settings)
          */
         public var settings: OAuthServerSettings? = null
🧹 Nitpick comments (2)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1)

16-144: Test naming vs. repository convention.

The test methods follow the testXyz... pattern (e.g., testInferDigestAuthenticationProvider, testRegisterJWTSecurityScheme), while the stated guideline for tests is DescribeWhatIsBeingTested. This is not a functional issue, but if you want strict consistency with that guideline you might consider renaming to more descriptive phrases (e.g., inferDigestAuthenticationProviderRegistersHttpDigestScheme).

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (1)

197-258: OAuth inference test creates HttpClient instances without cleanup.

The HttpClient() instances created in the OAuth tests are never closed, which could cause resource leaks. While this may be acceptable in test contexts, explicitly closing them would be cleaner.

Consider using use or storing the client to close it:

-                client = HttpClient()
+                client = HttpClient().also { /* closed by test framework or use autoCloseable */ }

Alternatively, since testApplication may handle cleanup, verify if this is an issue in practice.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c528817 and e248449.

📒 Files selected for processing (33)
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (6 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api (15 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api (15 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt (3 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt (9 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt (5 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt (5 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (7 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt (3 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt (6 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth.kt (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.klib.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt (3 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt (3 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api (9 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api (7 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt (2 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt (6 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/OAuth.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/SessionTrackerById.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt
🧰 Additional context used
📓 Path-based instructions (2)
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Follow Kotlin official style guide (https://kotlinlang.org/docs/coding-conventions.html)
Use star imports for io.ktor.* packages
Document all public APIs including parameters, return types, and exceptions
Mark internal APIs with @InternalAPI annotation
Run ./gradlew lintKotlin and fix all linting issues before giving control back to the user
Use ./gradlew formatKotlin to automatically fix formatting issues
Run ./gradlew updateLegacyAbi after making ABI changes to update ABI signature files
Binary compatibility is enforced - all public API changes must be tracked in the /api/ directories
Validate ABI with ./gradlew checkLegacyAbi and update with ./gradlew updateLegacyAbi
API changes must be intentional and well-documented
Error handling follows Kotlin conventions with specific Ktor exceptions

Files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
**/test/**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

Follow test naming pattern: DescribeWhatIsBeingTested

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
🧠 Learnings (17)
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : API changes must be intentional and well-documented

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/api/ktor-server-sessions.api
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Document all public APIs including parameters, return types, and exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-06-23T12:49:56.883Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-06-23T12:49:56.883Z
Learning: Error handling should follow Kotlin conventions and use specific Ktor exceptions.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Error handling follows Kotlin conventions with specific Ktor exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
📚 Learning: 2025-06-09T07:09:43.170Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4916
File: ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DeferredDependencyMap.kt:16-24
Timestamp: 2025-06-09T07:09:43.170Z
Learning: In the `tryGetCompleted` extension function on `Deferred<T>` in ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DeferredDependencyMap.kt, exceptions should be thrown if the Deferred completed with an error. The "try" in the function name refers to trying to get a completed value non-blockingly, not to exception handling. The function should return null if not completed, the value if completed successfully, or throw the exception if completed with an error.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
📚 Learning: 2025-05-14T18:05:02.321Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.klib.api:334-336
Timestamp: 2025-05-14T18:05:02.321Z
Learning: Breaking changes in constructor parameter order are acceptable for the ktor-server-di module when the code hasn't been released yet, as confirmed by the development team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-10-15T16:47:28.272Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:442-444
Timestamp: 2025-10-15T16:47:28.272Z
Learning: In the ktor-openapi-schema module, the maintainer prefers to keep certain properties mutable (using `var` instead of `val`) in data classes like Response, even when they are part of the public API, to allow flexibility during construction and modification.

Applied to files:

  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-06-16T17:03:45.729Z
Learnt from: tre3p
Repo: ktorio/ktor PR: 4936
File: ktor-utils/jvm/src/io/ktor/util/ZstdEncoding.kt:28-35
Timestamp: 2025-06-16T17:03:45.729Z
Learning: In the Ktor codebase, encoder implementations consistently use GlobalScope.writer and GlobalScope.reader patterns for compression/decompression operations. This is the established architectural pattern used throughout the codebase for byte channel transformations.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Use star imports for `io.ktor.*` packages

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: The headersOf() function from io.ktor.http package is available through wildcard imports like `import io.ktor.http.*`, so no explicit import statement is needed when using wildcard imports from that package.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Binary compatibility is enforced - all public API changes must be tracked in the `/api/` directories

Applied to files:

  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-05-16T13:11:28.416Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4860
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.api:24-26
Timestamp: 2025-05-16T13:11:28.416Z
Learning: Binary incompatible changes (such as constructor signature changes) are acceptable in the ktor-server-di module when the version is not yet released, as confirmed by the development team.

Applied to files:

  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Mark internal APIs with `InternalAPI` annotation

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
  • ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt
📚 Learning: 2025-11-26T11:34:00.471Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5206
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt:150-150
Timestamp: 2025-11-26T11:34:00.471Z
Learning: In OpenAPI 3.1.1 specification, the Components.schemas field is defined as Map[string, Schema Object] and does NOT allow Reference Objects at the top level, unlike other component fields (responses, parameters, examples, requestBodies, headers, links, callbacks) which are defined as Map[string, <Type> | Reference Object].

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
📚 Learning: 2025-10-15T16:46:27.493Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:43-43
Timestamp: 2025-10-15T16:46:27.493Z
Learning: In the ktor-openapi-schema module, Operation objects (and related OpenAPI objects) are designed to be composable and can be combined from multiple sources. Therefore, properties like `responses` should remain nullable to support intermediate states during object composition/merging.

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
📚 Learning: 2025-05-13T10:24:59.359Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4849
File: ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DependencyRegistry.kt:114-115
Timestamp: 2025-05-13T10:24:59.359Z
Learning: The `provide` function in DependencyRegistry intentionally accepts `DependencyResolver.() -> T?` (nullable return) while passing it to `set` which expects `DependencyResolver.() -> T` (non-nullable return). This is a deliberate design choice to support Java interoperability through Kotlin's flexible types system.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/test/**/*.kt : Follow test naming pattern: `DescribeWhatIsBeingTested`

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
🧬 Code graph analysis (1)
ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt (1)
ktor-utils/common/src/io/ktor/util/Attributes.kt (1)
  • AttributeKey (19-21)
🪛 ast-grep (0.40.0)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt

[warning] 20-20: A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive data, can be leaked and used by internal or external malicious actors. It is recommended to rotate the secret and retrieve them from a secure secret vault or Hardware Security Module (HSM), alternatively environment variables can be used if allowed by your company policy.
Context: Algorithm.HMAC256(jwtSecret)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A03:2021]: Identification and Authentication Failures [REFERENCES]
- https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures

(jwt-hardcode-kotlin)

🔇 Additional comments (64)
ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api (11)

37-72: LGTM! API Key security scheme properly defined.

The ApiKeySecurityScheme public API follows Kotlinx.serialization patterns correctly and aligns with the OpenAPI specification for API key authentication. The inclusion of defaultDescription helper in the Companion object is a good practice for generating consistent descriptions.


452-490: LGTM! HTTP security scheme correctly defined with predefined descriptions.

The HttpSecurityScheme provides predefined DEFAULT_* description constants for common HTTP authentication schemes (basic, bearer, digest, JWT), which aligns with OpenAPI best practices for HTTP authentication.


107-108: Verify the binary compatibility impact of Components constructor change.

The Components class constructor signature has been extended from 10 to 11 parameters to add securitySchemes. This is a binary-breaking change that will require existing code to be recompiled.

Ensure that:

  1. This breaking change is documented in release notes
  2. Migration guidance is provided for users
  3. The change is intentional and aligns with the module's versioning strategy

Based on learnings, binary compatibility is enforced and all public API changes must be tracked.

Also applies to: 111-111, 120-121, 133-133


818-851: LGTM! OAuth2 security scheme correctly defined.

The OAuth2SecurityScheme properly implements the OAuth2 authentication pattern with support for multiple flows via the OAuthFlows property, aligning with the OpenAPI specification.


853-889: LGTM! OAuth flow definition is complete.

The OAuthFlow class properly defines all OAuth2 flow parameters (authorization URL, token URL, refresh URL, and scopes), aligning with the OpenAPI specification. The DEFAULT_SCOPE_DESCRIPTION constant is a helpful addition for generating consistent scope documentation.


891-926: LGTM! OAuth flows container properly defined.

The OAuthFlows class correctly supports all four OAuth2 flow types (implicit, password, clientCredentials, authorizationCode) as defined in the OpenAPI specification, with proper nullable typing.


1079-1112: LGTM! OpenID Connect security scheme correctly defined.

The OpenIdConnectSecurityScheme properly implements the OpenID Connect authentication pattern with the discovery URL, aligning with the OpenAPI specification.


1852-1856: LGTM! Security requirement builder properly defined.

The Security$RequirementBuilder provides a clean builder API for constructing security requirements with scheme names and scopes, consistent with the existing builder patterns in the module.


1858-1876: LGTM! SecurityScheme interface correctly defines the contract.

The SecurityScheme interface provides a proper abstraction for all security scheme types with getDescription() and getType() methods. The inclusion of a polymorphic serializer enables correct serialization/deserialization of different security scheme implementations.


1878-1890: LGTM! SecuritySchemeIn enum correctly defined.

The SecuritySchemeIn enum properly defines the three valid locations for API key parameters (COOKIE, HEADER, QUERY), exactly matching the OpenAPI specification requirements.


1892-1905: LGTM! SecuritySchemeType enum correctly defined.

The SecuritySchemeType enum properly defines all four OpenAPI security scheme types (API_KEY, HTTP, OAUTH2, OPEN_ID_CONNECT), with corresponding implementation classes defined in this file.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1)

11-14: LGTM!

The non-JVM actual implementation correctly returns null with a clear comment explaining that no platform-specific metadata is available for authentication providers on non-JVM platforms. This aligns with the expect/actual pattern used elsewhere in the codebase.

ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/JsonSchema.kt (1)

62-64: LGTM!

The change from "\$id" to $$"$id" (and similar) is a stylistic improvement using Kotlin's raw string prefix to avoid backslash escaping. Both produce identical serialization output ($id, $anchor, $recursiveAnchor), so this is a readability enhancement with no functional impact.

ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt (2)

164-164: LGTM!

The new securitySchemes field correctly follows the OpenAPI Components Object specification and matches the established pattern of other fields in the class (nullable Map with ReferenceOr<T> wrapper). This is an intentional public API addition for the security scheme support feature.


180-191: LGTM!

The isEmpty() method is correctly updated to include securitySchemes.isNullOrEmpty() in the check, maintaining consistency with the existing pattern for all other fields.

ktor-server/ktor-server-plugins/ktor-server-sessions/common/src/io/ktor/server/sessions/Sessions.kt (1)

13-14: LGTM!

Exposing SessionProvidersKey as public with @InternalAPI annotation follows the coding guidelines for marking internal APIs. This change enables cross-module access (e.g., for OpenAPI security scheme inference) while clearly signaling that this is not part of the stable public API surface.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthCommon.kt (2)

80-86: LGTM!

The new refreshUrl and defaultScopeDescriptions properties are well-placed additions for OpenAPI documentation support. The TODO comment appropriately defers the merge of defaultScopes and defaultScopeDescriptions to a future major release to avoid breaking changes.


100-135: Deprecated constructor correctly maintains backward compatibility.

The deprecated constructor properly forwards all existing parameters to the primary constructor while providing sensible defaults (null and emptyMap()) for the new refreshUrl and defaultScopeDescriptions parameters. The lambda adaptation at line 129 correctly bridges the old URLBuilder.() -> Unit signature to the new URLBuilder.(ApplicationRequest) -> Unit signature.

ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.klib.api (5)

39-52: API additions for description support look consistent.

The description property added to AuthenticationProvider and AuthenticationProvider.Config follows a clean pattern that's propagated consistently across all provider types. The constructor signature change from (String?) to (String?, String?) is a breaking binary change but is properly tracked in this ABI file.


79-86: New AuthenticateProvidersRegistration class exposes route authentication metadata.

This class provides access to authentication provider names and strategy for OpenAPI inference. The design is clean with immutable properties.


521-557: OAuth2ServerSettings extended with refreshUrl and defaultScopeDescriptions.

The new constructor adds refreshUrl: String? and defaultScopeDescriptions: Map<String, String> for richer OpenAPI documentation. The old constructor is preserved for backward compatibility.


626-636: New internal API extensions for accessing authentication configuration.

configuration() and allProviders() extensions enable OpenAPI inference to access registered providers. staticSettings() provides access to OAuth settings without dynamic lookup.


271-276: providerLookup nullability and new settings property enable flexible OAuth configuration.

The changes properly support both dynamic provider lookup and static configuration, with validation ensuring at least one is specified. Existing OAuth configurations using providerLookup continue to work without modification, and the new settings property provides a convenient path for static configurations needed for documentation generation.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/FormAuth.kt (3)

22-26: Exposing userParamName and passwordParamName as @InternalAPI.

These properties are correctly marked with @InternalAPI to indicate they're exposed for internal framework use (OpenAPI inference) rather than general consumption. This aligns with the coding guidelines.


66-69: Config constructor updated to accept description parameter.

The constructor properly passes both name and description to the parent AuthenticationProvider.Config. This follows the consistent pattern across all authentication providers.


140-161: Form authentication overloads with delegation pattern.

The existing form() function now delegates to the new overload with description = null, maintaining backward compatibility. The new overload is properly documented.

ktor-server/ktor-server-plugins/ktor-server-auth-jwt/api/ktor-server-auth-jwt.api (1)

1-6: JWT authentication provider gains description parameter overload.

The new jwt(AuthenticationConfig, String, String, Function1) overload follows the same pattern as other authentication providers, adding the description parameter for OpenAPI documentation. The existing overload is preserved for backward compatibility.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt (2)

27-47: Provider registration with description support.

The existing provider() function delegates to the new overload with description = null, maintaining backward compatibility. The new overload properly constructs DynamicProviderConfig(name, description) and includes appropriate documentation.


134-135: configuration() extension exposes internal config for OpenAPI inference.

The @InternalAPI annotation correctly marks this as an internal framework API. This enables the OpenAPI module to access registered authentication providers for security scheme inference.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (4)

15-32: Comprehensive test for basic authentication inference.

The test properly validates that basic authentication providers are inferred with correct type, scheme, description, and bearerFormat. Good coverage of the basic case.


109-113: Test data classes for session authentication.

The @Serializable annotation is appropriate for session data classes used with Ktor Sessions.


382-394: Edge case tests for missing/empty authentication plugin.

Good coverage of edge cases where the Authentication plugin is not installed or has no providers. The tests correctly expect null schemes in these scenarios.


412-423: Test validates dynamic providers cannot be inferred.

This test confirms that custom dynamic providers (created via provider {}) cannot be automatically inferred for OpenAPI documentation, which is the expected behavior.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationProvider.kt (2)

36-41: Well-structured addition of the description property.

The new description property is properly initialized from the config and documented for API documentation purposes. This aligns with the PR objective of supporting OpenAPI security scheme inference.


69-72: Config constructor signature is correctly updated with proper subclass compatibility.

All eight Config subclasses (Basic, Bearer, Digest, Form, JWT, OAuth, Session, and Dynamic) have been updated to pass the new description parameter to the parent constructor. The binary API signatures have been properly tracked in the .api files, confirming that this public API change has been intentionally made and documented.

ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (2)

229-232: Config constructor updated correctly for description support.

The internal constructor now accepts both name and description parameters, properly delegating to the base class.


401-423: New JWT overloads follow consistent delegation pattern.

The existing overload delegates to the new description-aware overload, maintaining backward compatibility while enabling the new functionality.

ktor-server/ktor-server-plugins/ktor-server-auth/jvm/src/io/ktor/server/auth/DigestAuth.kt (2)

96-99: Config constructor properly extended with description.

Consistent with the pattern established in the base AuthenticationProvider.Config class.


168-188: Digest authentication overloads follow the established pattern.

The existing overload delegates to the new description-aware overload, maintaining backward compatibility.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/SessionAuth.kt (2)

63-67: Config constructor correctly includes description.

The @PublishedApi internal visibility is preserved, and the description flows through to the base config.


186-210: Session authentication overloads properly extended.

The existing overload delegates to the new description-aware inline function, maintaining backward compatibility while enabling description metadata for session authentication.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt (3)

60-63: Config constructor properly extended with description.

Consistent with the pattern established across all authentication providers.


112-134: Basic authentication overloads follow the delegation pattern.

The existing overload delegates to the new description-aware overload, ensuring backward compatibility.


159-159: Minor improvement using take() instead of substring().

The change from substring(0, colonIndex) to take(colonIndex) is a minor readability improvement and functionally equivalent.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (3)

90-95: Good validation in build() method.

The requirement that either settings or providerLookup must be provided prevents misconfiguration at build time with a clear error message.


99-100: staticSettings() appropriately marked as internal API.

The @InternalAPI annotation correctly indicates this is for internal use (OpenAPI inference), preventing accidental external dependencies. As per coding guidelines, internal APIs should be marked with this annotation.


143-146: Provider resolution correctly implements fallback logic.

The providerLookup?.invoke(call) ?: settings pattern correctly prioritizes dynamic lookup while falling back to static settings, aligning with the documentation that states either can be specified.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/AuthenticationInterceptors.kt (4)

212-215: New allProviders() function exposes provider registry.

This function is needed for OpenAPI security scheme inference. The @OptIn(InternalAPI::class) annotation correctly indicates that it accesses internal APIs.


326-331: RouteAuthenticationConfig made public with appropriate annotations.

The combination of @KtorDsl and @InternalAPI annotations correctly indicates this is a DSL configuration class intended for internal/plugin use. As per coding guidelines, internal APIs are marked with @InternalAPI annotation.


347-351: DEFAULT_NAME constant provides clearer output.

The companion object with DEFAULT_NAME = "default" improves the toString() output readability when the authentication provider name is null.


354-361: Public exposure of AuthenticateProvidersRegistration and AuthenticateProvidersKey correctly tracked in ABI files.

Both declarations are properly marked with @InternalAPI and the ABI files have been updated accordingly. The ktor-server-auth.api file contains entries for AuthenticateProvidersRegistration (line 1) and AuthenticateProvidersKey (line 84), and the .klib.api file includes the full API signatures (lines 79-85 and 616-617). The binary compatibility tracking aligns with Ktor's requirements for intentional public API changes.

ktor-server/ktor-server-plugins/ktor-server-auth/api/ktor-server-auth.api (13)

1-5: New public API class added for provider registration.

This new AuthenticateProvidersRegistration class appropriately encapsulates authentication provider names and strategy for OpenAPI security scheme inference.


29-31: New provider overload with description parameter.

This overload appropriately extends the provider configuration API to accept an optional description parameter, supporting the OpenAPI documentation requirements.


117-126: LGTM - Non-breaking API additions.

The addition of a Companion object and DEFAULT_NAME constant to AuthenticationRouteSelector are non-breaking, additive API changes that appropriately expose default naming conventions.


138-141: Consistent description parameter added across authentication methods.

All authentication provider configuration methods (basic, bearer, digest, form) now accept an optional description parameter. The synthetic $default methods ensure binary compatibility for existing code.

Also applies to: 159-162, 195-198, 269-272


170-171: LGTM - Config constructors updated consistently.

The BearerAuthenticationProvider.Config and DynamicProviderConfig constructors are appropriately updated to match the parent AuthenticationProvider.Config signature changes, with synthetic constructors maintaining compatibility.

Also applies to: 250-251


422-427: OAuth settings property added for static configuration.

The settings property provides a static alternative to providerLookup, enabling OpenAPI documentation generation and potential performance improvements as noted in the PR objectives.


481-485: OAuth overload and static settings accessor added.

The new oauth overload with description parameter and the staticSettings method appropriately support OpenAPI security scheme inference from OAuth providers.


276-278: Form authentication parameter names exposed.

Exposing getUserParamName and getPasswordParamName appropriately enables OpenAPI schema generation to document the expected form parameter names.


545-562: Session authentication description support added.

The session authentication configuration now accepts an optional description parameter, consistent with other authentication providers. The constructor signature update maintains the established pattern.


103-114: Provider description support added with maintained binary compatibility.

The AuthenticationProvider and its Config class now support a description parameter. The constructor signature shows (String, String), and the synthetic constructor with DefaultConstructorMarker on line 111 confirms the description parameter has a default value, preserving binary compatibility for existing callers.


90-90: The configuration() method already has the @InternalAPI annotation (line 134-135), correctly marking it as an internal API.


508-509: No breaking change — constructor parameter additions are backward compatible.

The new refreshUrl and defaultScopeDescriptions parameters are handled by a deprecated hidden secondary constructor that delegates to the primary constructor with default values (refreshUrl = null, defaultScopeDescriptions = emptyMap()). Existing callers using positional arguments or the old signature will continue to work without modification.


79-84: Add @internalapi annotation to allProviders() function.

The allProviders() function (line 213) exposes internal authentication provider details and should be annotated with @InternalAPI to signal that it is not intended for general use. Currently, it uses @OptIn(InternalAPI::class) internally but lacks the annotation on the function itself. The companion AuthenticateProvidersKey property is correctly annotated with @InternalAPI at line 360.

⛔ Skipped due to learnings
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Mark internal APIs with `InternalAPI` annotation
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : API changes must be intentional and well-documented

Copy link
Contributor

@bjhham bjhham left a comment

Choose a reason for hiding this comment

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

Looking good! I'll take another gander in the morning 👀

@bjhham
Copy link
Contributor

bjhham commented Dec 11, 2025

Seems you've got a test failure...

expected: <Http Digest Authentication> but was: <HTTP Digest Authentication>

Very helpful assert message.

@zibet27
Copy link
Collaborator Author

zibet27 commented Dec 11, 2025

Seems you've got a test failure...

expected: but was:

Very helpful assert message.

Yeah, it's a last-minute refactor 😅. Also, some tests from auth were failing.

@bjhham
Copy link
Contributor

bjhham commented Dec 11, 2025

Now that #5243 is merged, could you include the API key support? There seems to be a provision in OpenAPI for it https://swagger.io/docs/specification/v3_0/authentication/api-keys/

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (1)

401-406: Fix invalid Kotlin call: named argument followed by positional argument (won’t compile).
Line 405 uses description = null and then passes configure positionally, which Kotlin forbids.

 public fun AuthenticationConfig.jwt(
     name: String? = null,
     configure: JWTAuthenticationProvider.Config.() -> Unit
 ) {
-    jwt(name, description = null, configure)
+    jwt(name = name, description = null, configure = configure)
 }
♻️ Duplicate comments (3)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (3)

192-200: KDoc for name parameter does not match function signature.

Line 187 states "@param name The name of the security scheme. Defaults to 'default'." but the signature shows name: String? with no Kotlin default value. The defaulting only occurs when null is explicitly passed (inside registerSecurityScheme).

For consistency with registerBasicAuthSecurityScheme and registerBearerAuthSecurityScheme (which have = null defaults), add a Kotlin default:

 public fun Application.registerApiKeySecurityScheme(
-    name: String?,
+    name: String? = null,
     keyName: String,
     location: SecuritySchemeIn,
     description: String = ApiKeySecurityScheme.defaultDescription(keyName, location.name)
 )

209-215: KDoc for name parameter does not match function signature.

Line 205 states "@param name The name of the security scheme. Defaults to 'default'." but the signature shows name: String? with no Kotlin default value.

 public fun Application.registerOAuth2SecurityScheme(
-    name: String?,
+    name: String? = null,
     flows: OAuthFlows,
     description: String? = OAuth2SecurityScheme.DEFAULT_DESCRIPTION
 )

224-230: KDoc for name parameter does not match function signature.

Line 220 states "@param name The name of the security scheme. Defaults to 'default'." but the signature shows name: String? with no Kotlin default value.

 public fun Application.registerOpenIdConnectSecurityScheme(
-    name: String?,
+    name: String? = null,
     openIdConnectUrl: String,
     description: String? = OpenIdConnectSecurityScheme.DEFAULT_DESCRIPTION
 )
🧹 Nitpick comments (6)
ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (1)

408-423: Public API KDoc: add @param docs (and clarify what description is used for).
The new overload is public; per guidelines, please document parameters (at least name, description, configure) and (optionally) mention that description is intended for generated API docs / OpenAPI.

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (1)

99-100: Consider adding KDoc documentation.

While the function is correctly marked with @InternalAPI, adding KDoc documentation would clarify its purpose for OpenAPI security scheme inference and improve maintainability.

Example:

+/**
+ * Returns the static OAuth server settings if configured.
+ * Used for inferring security schemes in OpenAPI documentation generation.
+ *
+ * [Report a problem](https://ktor.io/feedback/?fqname=io.ktor.server.auth.staticSettings)
+ */
 @InternalAPI
 public fun OAuthAuthenticationProvider.staticSettings(): OAuthServerSettings? = settings
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (2)

49-49: Consider using safe casts for clearer test failure messages.

The pattern schemes[...]?.valueOrNull() as HttpSecurityScheme appears consistently throughout the test methods. While this works, using a non-null cast as after nullable operations can produce less informative error messages if the value is null or of the wrong type.

Consider this safer pattern for clearer test failures:

-val scheme1 = schemes["digest-auth"]?.valueOrNull() as HttpSecurityScheme
+val scheme1 = assertNotNull(schemes["digest-auth"]?.valueOrNull() as? HttpSecurityScheme)

This applies to similar casts on lines 49, 55, 82, 104, 120, 126, 141, and 147.

Also applies to: 82-82, 104-104, 120-120, 141-141


16-150: Consider adding test coverage for error conditions.

The tests comprehensively cover happy paths for both inference and explicit registration. According to the PR objectives, "attempting to infer from the auth plugin when it's not installed should produce a runtime error." Consider adding a test case for this scenario to verify the expected error behavior.

Example test case:

@Test
fun testInferWithoutAuthenticationPlugin() = testApplication {
    startApplication()
    // Should throw or return empty/null when Authentication plugin not installed
    assertFailsWith<IllegalStateException> {
        application.findSecuritySchemes(inferFromAuthenticationPlugin = true)
    }
}
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (2)

40-51: Clarify the KDoc for includeJwt parameter.

Line 44 states "Enable only if you have a plugin installed" but doesn't specify which plugin. Consider clarifying that this requires a JWT authentication plugin (e.g., ktor-server-auth-jwt) to be installed for JWT scheme inference to work.

Apply this diff to improve the documentation:

  * @param includeJwt Whether to include JWT security schemes in the result. Enable only if you have a plugin installed.
+ * @param includeJwt Whether to include JWT security schemes in the result. Enable only if you have a JWT authentication plugin (e.g., ktor-server-auth-jwt) installed.

196-196: Consider using lowercase for location name in default description.

Line 196 uses location.name which returns the enum constant name in uppercase (e.g., "HEADER", "COOKIE"). For consistency with line 124 in the session inference logic (which uses keyLocation.name.lowercase()), consider lowercasing the location name in the default description.

-    description: String = ApiKeySecurityScheme.defaultDescription(keyName, location.name)
+    description: String = ApiKeySecurityScheme.defaultDescription(keyName, location.name.lowercase())
 )
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e248449 and bb03d82.

📒 Files selected for processing (9)
  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (6 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (7 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/test/io/ktor/tests/auth/OAuth1aTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
🧰 Additional context used
📓 Path-based instructions (2)
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Follow Kotlin official style guide (https://kotlinlang.org/docs/coding-conventions.html)
Use star imports for io.ktor.* packages
Document all public APIs including parameters, return types, and exceptions
Mark internal APIs with @InternalAPI annotation
Run ./gradlew lintKotlin and fix all linting issues before giving control back to the user
Use ./gradlew formatKotlin to automatically fix formatting issues
Run ./gradlew updateLegacyAbi after making ABI changes to update ABI signature files
Binary compatibility is enforced - all public API changes must be tracked in the /api/ directories
Validate ABI with ./gradlew checkLegacyAbi and update with ./gradlew updateLegacyAbi
API changes must be intentional and well-documented
Error handling follows Kotlin conventions with specific Ktor exceptions

Files:

  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/test/io/ktor/tests/auth/OAuth1aTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
**/test/**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

Follow test naming pattern: DescribeWhatIsBeingTested

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/jvm/test/io/ktor/tests/auth/OAuth1aTest.kt
🧠 Learnings (12)
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : API changes must be intentional and well-documented

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
📚 Learning: 2025-06-09T07:09:43.170Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4916
File: ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DeferredDependencyMap.kt:16-24
Timestamp: 2025-06-09T07:09:43.170Z
Learning: In the `tryGetCompleted` extension function on `Deferred<T>` in ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DeferredDependencyMap.kt, exceptions should be thrown if the Deferred completed with an error. The "try" in the function name refers to trying to get a completed value non-blockingly, not to exception handling. The function should return null if not completed, the value if completed successfully, or throw the exception if completed with an error.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
📚 Learning: 2025-06-23T12:49:56.883Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-06-23T12:49:56.883Z
Learning: Error handling should follow Kotlin conventions and use specific Ktor exceptions.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Error handling follows Kotlin conventions with specific Ktor exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Document all public APIs including parameters, return types, and exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Mark internal APIs with `InternalAPI` annotation

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
📚 Learning: 2025-05-16T13:11:28.416Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4860
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.api:24-26
Timestamp: 2025-05-16T13:11:28.416Z
Learning: Binary incompatible changes (such as constructor signature changes) are acceptable in the ktor-server-di module when the version is not yet released, as confirmed by the development team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
📚 Learning: 2025-05-14T18:05:02.321Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.klib.api:334-336
Timestamp: 2025-05-14T18:05:02.321Z
Learning: Breaking changes in constructor parameter order are acceptable for the ktor-server-di module when the code hasn't been released yet, as confirmed by the development team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Binary compatibility is enforced - all public API changes must be tracked in the `/api/` directories

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: In Ktor test files, particularly in the ktor-client/ktor-client-core/jvm/test/ directory, test files follow the convention of not including explicit package declarations. This is consistent across test files like CachingCacheStorageTest.kt and should be maintained for consistency.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Use star imports for `io.ktor.*` packages

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: The headersOf() function from io.ktor.http package is available through wildcard imports like `import io.ktor.http.*`, so no explicit import statement is needed when using wildcard imports from that package.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt
🧬 Code graph analysis (2)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (4)
ktor-utils/common/src/io/ktor/util/Attributes.kt (1)
  • AttributeKey (19-21)
ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationPlugin.kt (1)
  • pluginOrNull (100-102)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1)
  • inferPlatformSpecificSecurityScheme (14-27)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1)
  • inferPlatformSpecificSecurityScheme (11-18)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (2)
ktor-server/ktor-server-plugins/ktor-server-di/common/src/io/ktor/server/plugins/di/DependencyRegistry.kt (1)
  • require (70-72)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt (1)
  • register (56-59)
🪛 ast-grep (0.40.0)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt

[warning] 20-20: A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive data, can be leaked and used by internal or external malicious actors. It is recommended to rotate the secret and retrieve them from a secure secret vault or Hardware Security Module (HSM), alternatively environment variables can be used if allowed by your company policy.
Context: Algorithm.HMAC256(jwtSecret)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A03:2021]: Identification and Authentication Failures [REFERENCES]
- https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures

(jwt-hardcode-kotlin)

🔇 Additional comments (17)
ktor-server/ktor-server-plugins/ktor-server-auth/jvm/test/io/ktor/tests/auth/OAuth1aTest.kt (1)

310-325: Good fix: explicit outer-receiver qualification prevents DSL/lambda shadowing.
this@OAuth1aFlowTest.settings is clearer and more robust than relying on unqualified settings inside nested DSL scopes.

ktor-server/ktor-server-plugins/ktor-server-auth-jwt/jvm/src/io/ktor/server/auth/jwt/JWTAuth.kt (2)

117-140: Verify exception contract vs Auth0 JWT: JWTDecodeException may not be the only thrown type.
Catching only JWTDecodeException may be fine, but please confirm via tests / current dependency behavior that Claim.asList(...) / Claim.as(...) won’t throw other runtime exceptions you’d rather map to null/emptyList.


229-233: ABI + docs follow-up for widened auth provider config surface.
Since JWTAuthenticationProvider.Config now routes through AuthenticationProvider.Config(name, description), please ensure ABI files under /api/ are updated and ./gradlew checkLegacyAbi passes (and run updateLegacyAbi if expected).

ktor-server/ktor-server-plugins/ktor-server-auth/common/test/io/ktor/tests/auth/AuthBuildersTest.kt (1)

18-18: LGTM! Correct internal API opt-in.

The import and opt-in annotation are properly applied to use AuthenticationInterceptors, which is now marked as internal API per this PR's changes. The opt-in is correctly scoped to the specific usage point.

Also applies to: 614-614

ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/OAuthProcedure.kt (5)

34-35: LGTM! Dual configuration properties added.

The settings and providerLookup properties appropriately expose configuration values for internal framework use, enabling both static and dynamic OAuth server configuration approaches.


49-72: LGTM! Config class properly extended.

The changes correctly implement dual configuration support:

  • Constructor now accepts description parameter for OpenAPI documentation
  • Both providerLookup and settings are nullable, aligning with the either/or validation
  • Documentation is comprehensive and correctly references the new settings property

90-95: LGTM! Appropriate configuration validation.

The build() function correctly validates that at least one configuration method (settings or providerLookup) is specified. Using require() with a clear error message follows Kotlin conventions.


110-132: LGTM! OAuth DSL properly extended.

The overload pattern correctly maintains backward compatibility while adding description support:

  • Original oauth delegates to new overload with description = null
  • New overload properly constructs the provider using the validated build() method
  • Documentation follows Ktor conventions

145-145: LGTM! Resolution logic correctly implements fallback.

The provider resolution providerLookup?.invoke(call) ?: settings correctly:

  • Prefers dynamic lookup when available
  • Falls back to static settings when lookup is null or returns null
  • Aligns with the validation ensuring at least one is configured
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1)

18-21: Static analysis warning is a false positive for test code.

The hardcoded JWT secret and algorithm setup are appropriate for test fixtures. Test code commonly uses hardcoded credentials, and the values clearly indicate test data (e.g., "test-jwt-secret").

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1)

11-18: LGTM! Clean non-JVM fallback implementation.

The implementation correctly enforces that JWT authentication is not supported on non-JVM platforms and provides a safe fallback by returning null for platform-specific security scheme inference.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (6)

17-22: LGTM! Well-documented public API.

The attribute key is clearly documented and follows Ktor conventions for storing plugin-scoped metadata.


24-38: LGTM! Core registration function is sound.

The function correctly accumulates security schemes in application attributes and handles null provider names by defaulting to AuthenticationRouteSelector.DEFAULT_NAME.


67-84: LGTM! Helper functions implement correct inference logic.

The wrap() function properly converts schemes to OpenAPI references, and inferSecuritySchemesFromAuthentication correctly retrieves providers from the Authentication plugin and delegates to per-provider inference.


86-151: LGTM! Comprehensive provider-to-scheme inference logic.

The function correctly infers OpenAPI security schemes from various Ktor authentication providers:

  • HTTP schemes for Basic and Bearer authentication
  • API Key schemes for Session-based authentication (correctly extracting transport details)
  • OAuth2 schemes with proper flow configuration
  • Platform-specific delegation for Digest and JWT

The session handling properly extracts transport information, and the OAuth inference correctly uses the newly added staticSettings() property.


153-164: LGTM! Well-designed helper with proper defaults.

The function signature and documentation are consistent, with appropriate Kotlin defaults for optional parameters.


166-182: LGTM! Consistent helper design with proper optional parameters.

The function correctly provides defaults for all optional parameters and matches its documentation.

@zibet27 zibet27 requested a review from bjhham December 12, 2025 09:46
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (4)
ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api (2)

164-224: ApiKeySecurityScheme.in and .name being nullable risks emitting invalid OpenAPI—ensure validation exists at build/emit time.

OpenAPI requires in and name for type=apiKey. If nullability is kept for composability, ensure there’s a validation step (or “finalize/normalize” pass) that either fills defaults or fails fast before serialization.


226-284: Components data-class slot insertion changes componentN() ordering and destructuring semantics (binary/source behavior break).

securitySchemes is added as the 7th constructor parameter, which shifts component7() from the previous meaning (formerly “links”) to now “securitySchemes”, and shifts subsequent component indices. Any consumer using destructuring declarations or calling componentN() will break or silently misbehave.

Strongly consider appending securitySchemes to the end of the constructor (and thus to the end of componentN order), keeping existing component indices stable. Based on learnings, public API changes must be intentional and well-documented, and ABI is enforced via /api/ dumps. Based on learnings, API changes must be intentional and well-documented.

ktor-server/ktor-server-plugins/ktor-server-auth-api-key/common/src/io/ktor/server/auth/apikey/ApiKeyAuth.kt (2)

14-41: KDoc for the new public overload is incomplete (missing @param description)
AuthenticationConfig.apiKey(name, description, configure) is public, but its KDoc doesn’t document description (and it duplicates the old KDoc without updating params). Based on learnings, public API changes must be intentional and well-documented.

 /**
  * Installs an API Key authentication mechanism.
  *
  * @param name optional name for this authentication provider. If not specified, a default name will be used.
- * @param configure configuration block for setting up the API Key authentication provider.
+ * @param description optional description for this authentication provider (used by API documentation generators).
+ * @param configure configuration block for setting up the API Key authentication provider.
  */
 public fun AuthenticationConfig.apiKey(
     name: String? = null,
     description: String? = null,
     configure: ApiKeyAuthenticationProvider.Configuration.() -> Unit,
 ) {
     val configuration = ApiKeyAuthenticationProvider.Configuration(name, description)
     val provider = ApiKeyAuthenticationProvider(configuration.apply(configure))
     register(provider)
 }

65-80: Public headerName should have KDoc (even if @InternalAPI)
This is now a public API surface; please document what it represents and any stability expectations (and/or explicitly note it’s @InternalAPI).

 public class ApiKeyAuthenticationProvider internal constructor(
     configuration: Configuration,
 ) : AuthenticationProvider(configuration) {

     @InternalAPI
+    /**
+     * Header name used to extract the API key for this provider.
+     *
+     * This is exposed for internal/advanced integrations (e.g., documentation generators) and may change.
+     */
     public val headerName: String = configuration.headerName
♻️ Duplicate comments (1)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1)

192-238: Align function signatures with KDoc for optional name parameter.

The KDoc for registerApiKeySecurityScheme, registerOAuth2SecurityScheme, and registerOpenIdConnectSecurityScheme states that the name parameter "Defaults to 'default'", but the function signatures declare name: String? with no Kotlin default value. Either add = null to match the documented behavior:

 public fun Application.registerApiKeySecurityScheme(
-    name: String?,
+    name: String? = null,
     keyName: String,
     location: SecuritySchemeIn,
     description: String = ApiKeySecurityScheme.DEFAULT_DESCRIPTION
 ) { ... }

 public fun Application.registerOAuth2SecurityScheme(
-    name: String?,
+    name: String? = null,
     flows: OAuthFlows,
     description: String? = OAuth2SecurityScheme.DEFAULT_DESCRIPTION
 ) { ... }

 public fun Application.registerOpenIdConnectSecurityScheme(
-    name: String?,
+    name: String? = null,
     openIdConnectUrl: String,
     description: String? = OpenIdConnectSecurityScheme.DEFAULT_DESCRIPTION
 ) { ... }

or update the KDoc to clarify that null must be explicitly passed to use the default provider name.

Based on learnings and coding guidelines: public API docs must align with signatures.

🧹 Nitpick comments (2)
ktor-server/ktor-server-plugins/ktor-server-auth-api-key/common/src/io/ktor/server/auth/apikey/ApiKeyAuth.kt (2)

12-12: Use star import for io.ktor.* here (per repo guidelines)
Switch import io.ktor.utils.io.InternalAPIimport io.ktor.utils.io.*.

-import io.ktor.utils.io.InternalAPI
+import io.ktor.utils.io.*

20-25: return is unnecessary in a Unit function
Pure readability nit: the delegating overload can just call the other overload.

 public fun AuthenticationConfig.apiKey(
     name: String? = null,
     configure: ApiKeyAuthenticationProvider.Configuration.() -> Unit,
 ) {
-    return apiKey(name, description = null, configure)
+    apiKey(name, description = null, configure)
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb03d82 and 7760536.

📒 Files selected for processing (11)
  • ktor-server/ktor-server-plugins/ktor-server-auth-api-key/api/ktor-server-auth-api-key.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth-api-key/api/ktor-server-auth-api-key.klib.api (2 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-auth-api-key/common/src/io/ktor/server/auth/apikey/ApiKeyAuth.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api (8 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api (7 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api
🧰 Additional context used
📓 Path-based instructions (2)
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Follow Kotlin official style guide (https://kotlinlang.org/docs/coding-conventions.html)
Use star imports for io.ktor.* packages
Document all public APIs including parameters, return types, and exceptions
Mark internal APIs with @InternalAPI annotation
Run ./gradlew lintKotlin and fix all linting issues before giving control back to the user
Use ./gradlew formatKotlin to automatically fix formatting issues
Run ./gradlew updateLegacyAbi after making ABI changes to update ABI signature files
Binary compatibility is enforced - all public API changes must be tracked in the /api/ directories
Validate ABI with ./gradlew checkLegacyAbi and update with ./gradlew updateLegacyAbi
API changes must be intentional and well-documented
Error handling follows Kotlin conventions with specific Ktor exceptions

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-auth-api-key/common/src/io/ktor/server/auth/apikey/ApiKeyAuth.kt
**/test/**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

Follow test naming pattern: DescribeWhatIsBeingTested

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
🧠 Learnings (16)
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : API changes must be intentional and well-documented

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-auth-api-key/api/ktor-server-auth-api-key.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Binary compatibility is enforced - all public API changes must be tracked in the `/api/` directories

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Cargo plugin (dev.gobley.cargo) used in the Ktor WebRTC RS module depends on the kotlin("plugin.atomicfu") plugin, so atomicfu should not be removed even if there are no direct kotlinx.atomicfu imports in the module's source code.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-05-16T13:11:28.416Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4860
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.api:24-26
Timestamp: 2025-05-16T13:11:28.416Z
Learning: Binary incompatible changes (such as constructor signature changes) are acceptable in the ktor-server-di module when the version is not yet released, as confirmed by the development team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Mark internal APIs with `InternalAPI` annotation

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
📚 Learning: 2025-05-14T18:05:02.321Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.klib.api:334-336
Timestamp: 2025-05-14T18:05:02.321Z
Learning: Breaking changes in constructor parameter order are acceptable for the ktor-server-di module when the code hasn't been released yet, as confirmed by the development team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Gobley Cargo plugin (dev.gobley.cargo) used in the Ktor WebRTC RS module requires the kotlin("plugin.atomicfu") plugin as a dependency, so the atomicfu plugin should not be removed even if there are no direct kotlinx.atomicfu imports in the module's source code.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Use star imports for `io.ktor.*` packages

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-05-08T09:52:11.723Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4836
File: build-logic/src/main/kotlin/ktorbuild.project.server-plugin.gradle.kts:12-12
Timestamp: 2025-05-08T09:52:11.723Z
Learning: In the Ktor project's flattened Gradle structure, projects are declared using a custom DSL with the unary plus operator inside specialized blocks. For example, server projects are declared with `+"project-name"` inside a `server {}` block within the main `projects {}` block. When verifying project declarations, search for `+"project-name"` rather than traditional `include(":project-name")` statements.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Document all public APIs including parameters, return types, and exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-05-07T13:42:29.388Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 4822
File: ktor-server/ktor-server-plugins/ktor-server-i18n/build.gradle.kts:13-17
Timestamp: 2025-05-07T13:42:29.388Z
Learning: In Kotlin build scripts (build.gradle.kts), the preferred syntax for declaring dependencies is using the dot notation like `jvmTest.dependencies { ... }` rather than the nested version `jvmTest { dependencies { ... } }` as it reduces the nesting level by one and improves readability.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: In Ktor test files, particularly in the ktor-client/ktor-client-core/jvm/test/ directory, test files follow the convention of not including explicit package declarations. This is consistent across test files like CachingCacheStorageTest.kt and should be maintained for consistency.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
📚 Learning: 2025-11-27T10:07:26.686Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 5205
File: ktor-client/ktor-client-curl/desktop/interop/include/curl/multi.h:410-420
Timestamp: 2025-11-27T10:07:26.686Z
Learning: In the ktorio/ktor repository, do not review files under `ktor-client/ktor-client-curl/desktop/interop/include/curl/*` as these are upstream libcurl header files copied from the curl project and not maintained by the Ktor team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
📚 Learning: 2025-10-15T16:47:28.272Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:442-444
Timestamp: 2025-10-15T16:47:28.272Z
Learning: In the ktor-openapi-schema module, the maintainer prefers to keep certain properties mutable (using `var` instead of `val`) in data classes like Response, even when they are part of the public API, to allow flexibility during construction and modification.

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-11-26T11:34:00.471Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5206
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt:150-150
Timestamp: 2025-11-26T11:34:00.471Z
Learning: In OpenAPI 3.1.1 specification, the Components.schemas field is defined as Map[string, Schema Object] and does NOT allow Reference Objects at the top level, unlike other component fields (responses, parameters, examples, requestBodies, headers, links, callbacks) which are defined as Map[string, <Type> | Reference Object].

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
📚 Learning: 2025-10-15T16:46:27.493Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:43-43
Timestamp: 2025-10-15T16:46:27.493Z
Learning: In the ktor-openapi-schema module, Operation objects (and related OpenAPI objects) are designed to be composable and can be combined from multiple sources. Therefore, properties like `responses` should remain nullable to support intermediate states during object composition/merging.

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
🧬 Code graph analysis (1)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (4)
ktor-utils/common/src/io/ktor/util/Attributes.kt (1)
  • AttributeKey (19-21)
ktor-server/ktor-server-core/common/src/io/ktor/server/application/ApplicationPlugin.kt (1)
  • pluginOrNull (100-102)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1)
  • inferPlatformSpecificSecurityScheme (14-27)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1)
  • inferPlatformSpecificSecurityScheme (11-18)
🔇 Additional comments (10)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/build.gradle.kts (2)

15-16: Dependency strategy aligns well with OpenAPI security scheme inference requirements.

The compileOnly approach for auth modules in commonMain is appropriate—it allows compile-time access for inferring security schemes while avoiding a hard runtime dependency, which matches the stated goal of producing a runtime error when the auth plugin is not installed. Test-time implementation dependencies correctly enable validation of inference logic.

The JVM-specific compileOnly dependency on auth-jwt and test-time dependencies on auth-jwt and sessions properly isolate platform-specific security scheme inference.

Also applies to: 20-21, 25-27, 28-31


15-16: Verify API file updates for public API changes in authentication modules.

All auth modules have API tracking files, and the description field is currently present in the public API signatures. Ensure that any new or modified public APIs in ktor-server-auth, ktor-server-auth-api-key, and ktor-server-auth-jwt are reflected in their corresponding *.api and *.klib.api files per binary compatibility requirements. If no public API changes were made to these modules in this PR, no action is needed.

ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api (3)

27-61: Verify enum serialization matches OpenAPI spec wire values (cookie/header/query, apiKey/http/oauth2/openIdConnect).

ABI introduces SecuritySchemeIn/SecuritySchemeType with uppercase enum entries; that’s fine only if the serializers map to the correct OpenAPI strings (likely via @SerialName). Please double-check the serialized JSON output and round-trip parsing for these enums on all targets.


1833-1844: Security.Builder helpers (apiKey/basic/oauth2/openIdConnect) look good; verify the scheme-name conventions.

These helpers are a nice ergonomics win. Please verify that apiKey(String) (and others) map to the correct security scheme names in components.securitySchemes, and that the generated requirement objects match OpenAPI semantics (including empty scope lists where appropriate).


1265-1302: OpenID Connect URL is nullable—consider enforcing non-null when type=openIdConnect.

openIdConnectUrl is required by spec for OpenID Connect security schemes. If nullability is intentional for composition, ensure there’s a “must be set” validation prior to emitting the final OpenAPI document.

⛔ Skipped due to learnings
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:43-43
Timestamp: 2025-10-15T16:46:27.493Z
Learning: In the ktor-openapi-schema module, Operation objects (and related OpenAPI objects) are designed to be composable and can be combined from multiple sources. Therefore, properties like `responses` should remain nullable to support intermediate states during object composition/merging.
ktor-server/ktor-server-plugins/ktor-server-auth-api-key/api/ktor-server-auth-api-key.api (2)

6-11: New overload + default stub: please sanity-check Kotlin overload resolution at call sites
This adds apiKey(AuthenticationConfig, String, String, Function1) (plus $default). Since the new params are Strings, it’s worth verifying common usages like apiKey { ... } and apiKey("name") { ... } don’t become ambiguous after adding a “more-args-with-defaults” overload.


13-16: Public ABI now exposes ApiKeyAuthenticationProvider.getHeaderName()—confirm this is intentionally supported
Even if the source annotates it with @InternalAPI, it’s now part of the published JVM ABI; please ensure this is intended and documented as such.

ktor-server/ktor-server-plugins/ktor-server-auth-api-key/api/ktor-server-auth-api-key.klib.api (2)

9-12: headerName is now public in MPP ABI—ensure this is the intended cross-platform contract
This will be visible to JS/Native/Wasm consumers too; please confirm that’s acceptable (even if “internal” by opt-in convention).


33-34: New (name, description, configure) overload in MPP ABI—verify no ambiguity with the existing overload
Please double-check Kotlin call-site resolution for apiKey { ... } / apiKey("name") { ... } in multiplatform builds.

ktor-server/ktor-server-plugins/ktor-server-auth-api-key/common/src/io/ktor/server/auth/apikey/ApiKeyAuth.kt (1)

20-41: No action required. The two apiKey overloads do not create ambiguity. Kotlin's overload resolution correctly distinguishes between them based on argument count: calling with one string argument uses the first overload, while calling with two string arguments uses the second. Existing call sites in the test suite confirm both patterns compile cleanly.

Copy link
Contributor

@bjhham bjhham left a comment

Choose a reason for hiding this comment

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

Looks great 👍

Comment on lines +85 to +86
// TODO: merge `defaultScopes` and `defaultScopeDescriptions` in the next major release
public val defaultScopeDescriptions: Map<String, String> = emptyMap(),
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you log a YT ticket for this and target it for 4.0.0 so we don't forget?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Sure! I'll create it after the PR is merged.

Copy link
Member

@e5l e5l left a comment

Choose a reason for hiding this comment

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

lgtm, please consider merging after the release

}

@OptIn(InternalAPI::class)
public fun AuthenticationConfig.allProviders(): Map<String?, AuthenticationProvider> {
Copy link
Member

Choose a reason for hiding this comment

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

Could you tell me why it is possible to have a nullable key?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In ktor-auth, the auth provider name is nullable, null == "default".
In this PR, I just made it publicly available.

@zibet27
Copy link
Collaborator Author

zibet27 commented Dec 15, 2025

lgtm, please consider merging after the release

Sure, some OpenAPI Security features are still missing.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (5)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt (1)

12-14: LGTM on new authentication imports.

The imports correctly bring in the authentication-related types needed for OpenAPI security integration. As per coding guidelines, star imports should be used for io.ktor.* packages.

Consider consolidating to star import:

-import io.ktor.server.auth.AuthenticateProvidersKey
-import io.ktor.server.auth.AuthenticationRouteSelector
-import io.ktor.server.auth.AuthenticationStrategy
+import io.ktor.server.auth.*
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (2)

224-224: Consider closing HttpClient instances in tests.

The HttpClient() instances created at lines 224 and 239 are not explicitly closed. While the test framework likely handles cleanup, explicitly closing or using client.close() is a best practice to prevent resource leaks.


417-431: Test name may be misleading.

The test is named testDisabledCaching but it actually tests that caching works (stale cache returns old result, bypassing cache returns fresh result). Consider renaming to something like testCachingBehavior or testCacheBypass.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt (1)

12-20: Use star imports for io.ktor.* packages.

Per coding guidelines, star imports should be used for io.ktor.* packages.

-import io.ktor.server.auth.Authentication
-import io.ktor.server.auth.AuthenticationStrategy
-import io.ktor.server.auth.OAuthServerSettings
-import io.ktor.server.auth.UserIdPrincipal
-import io.ktor.server.auth.apikey.apiKey
-import io.ktor.server.auth.authenticate
-import io.ktor.server.auth.basic
-import io.ktor.server.auth.bearer
-import io.ktor.server.auth.oauth
+import io.ktor.server.auth.*
+import io.ktor.server.auth.apikey.*
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1)

32-47: Align registerSecurityScheme ergonomics with the other helpers and reset cache on mutation.

To match the documented “Defaults to default” behavior and the other helpers, it would be clearer to make providerName optional and invalidate the cached schemes when mutating:

-public fun Application.registerSecurityScheme(
-    providerName: String?,
-    securityScheme: SecurityScheme
-) {
-    val providerName = providerName ?: AuthenticationRouteSelector.DEFAULT_NAME
-    val existingSchemes = attributes.getOrNull(AuthSecuritySchemesAttributeKey) ?: emptyMap()
-    attributes.put(AuthSecuritySchemesAttributeKey, existingSchemes + (providerName to securityScheme))
-}
+public fun Application.registerSecurityScheme(
+    providerName: String? = null,
+    securityScheme: SecurityScheme
+) {
+    val resolvedName = providerName ?: AuthenticationRouteSelector.DEFAULT_NAME
+    // Ensure subsequent `findSecuritySchemes(useCache = true)` sees the new entry.
+    attributes.remove(AuthSecuritySchemesCacheAttributeKey)
+    val existingSchemes = attributes.getOrNull(AuthSecuritySchemesAttributeKey) ?: emptyMap()
+    attributes.put(AuthSecuritySchemesAttributeKey, existingSchemes + (resolvedName to securityScheme))
+}

This keeps the API symmetric with registerBasicAuthSecurityScheme/friends and avoids stale cache entries if schemes are added after the first lookup.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7760536 and 2a8cecd.

📒 Files selected for processing (14)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt (4 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/RouteAnnotationApiJvmTest.kt (1 hunks)
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api (8 hunks)
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api (8 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt (4 hunks)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/SecurityScheme.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/src/io/ktor/annotate/SecuritySchemeAnnotation.jvm.kt
🧰 Additional context used
📓 Path-based instructions (2)
**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.kt: Follow Kotlin official style guide (https://kotlinlang.org/docs/coding-conventions.html)
Use star imports for io.ktor.* packages
Document all public APIs including parameters, return types, and exceptions
Mark internal APIs with @InternalAPI annotation
Run ./gradlew lintKotlin and fix all linting issues before giving control back to the user
Use ./gradlew formatKotlin to automatically fix formatting issues
Run ./gradlew updateLegacyAbi after making ABI changes to update ABI signature files
Binary compatibility is enforced - all public API changes must be tracked in the /api/ directories
Validate ABI with ./gradlew checkLegacyAbi and update with ./gradlew updateLegacyAbi
API changes must be intentional and well-documented
Error handling follows Kotlin conventions with specific Ktor exceptions

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/RouteAnnotationApiJvmTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt
  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
**/test/**/*.kt

📄 CodeRabbit inference engine (CLAUDE.md)

Follow test naming pattern: DescribeWhatIsBeingTested

Files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/RouteAnnotationApiJvmTest.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
🧠 Learnings (16)
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: In Ktor test files, particularly in the ktor-client/ktor-client-core/jvm/test/ directory, test files follow the convention of not including explicit package declarations. This is consistent across test files like CachingCacheStorageTest.kt and should be maintained for consistency.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : API changes must be intentional and well-documented

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Use star imports for `io.ktor.*` packages

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Error handling follows Kotlin conventions with specific Ktor exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
📚 Learning: 2025-06-23T12:49:56.883Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-06-23T12:49:56.883Z
Learning: Error handling should follow Kotlin conventions and use specific Ktor exceptions.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
📚 Learning: 2025-05-30T06:45:52.309Z
Learnt from: rururux
Repo: ktorio/ktor PR: 4896
File: ktor-client/ktor-client-core/jvm/test/FileStorageTest.kt:1-12
Timestamp: 2025-05-30T06:45:52.309Z
Learning: The headersOf() function from io.ktor.http package is available through wildcard imports like `import io.ktor.http.*`, so no explicit import statement is needed when using wildcard imports from that package.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Document all public APIs including parameters, return types, and exceptions

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Binary compatibility is enforced - all public API changes must be tracked in the `/api/` directories

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-10-15T16:47:28.272Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:442-444
Timestamp: 2025-10-15T16:47:28.272Z
Learning: In the ktor-openapi-schema module, the maintainer prefers to keep certain properties mutable (using `var` instead of `val`) in data classes like Response, even when they are part of the public API, to allow flexibility during construction and modification.

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-10-15T16:46:27.493Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5125
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt:43-43
Timestamp: 2025-10-15T16:46:27.493Z
Learning: In the ktor-openapi-schema module, Operation objects (and related OpenAPI objects) are designed to be composable and can be combined from multiple sources. Therefore, properties like `responses` should remain nullable to support intermediate states during object composition/merging.

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api
📚 Learning: 2025-11-26T11:34:00.471Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 5206
File: ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt:150-150
Timestamp: 2025-11-26T11:34:00.471Z
Learning: In OpenAPI 3.1.1 specification, the Components.schemas field is defined as Map[string, Schema Object] and does NOT allow Reference Objects at the top level, unlike other component fields (responses, parameters, examples, requestBodies, headers, links, callbacks) which are defined as Map[string, <Type> | Reference Object].

Applied to files:

  • ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/*.kt : Mark internal APIs with `InternalAPI` annotation

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
📚 Learning: 2025-11-27T10:07:26.686Z
Learnt from: osipxd
Repo: ktorio/ktor PR: 5205
File: ktor-client/ktor-client-curl/desktop/interop/include/curl/multi.h:410-420
Timestamp: 2025-11-27T10:07:26.686Z
Learning: In the ktorio/ktor repository, do not review files under `ktor-client/ktor-client-curl/desktop/interop/include/curl/*` as these are upstream libcurl header files copied from the curl project and not maintained by the Ktor team.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api
📚 Learning: 2025-05-14T18:05:02.321Z
Learnt from: bjhham
Repo: ktorio/ktor PR: 4855
File: ktor-server/ktor-server-plugins/ktor-server-di/api/ktor-server-di.klib.api:334-336
Timestamp: 2025-05-14T18:05:02.321Z
Learning: Breaking changes in constructor parameter order are acceptable for the ktor-server-di module when the code hasn't been released yet, as confirmed by the development team.

Applied to files:

  • ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt
📚 Learning: 2025-08-14T15:17:11.466Z
Learnt from: zibet27
Repo: ktorio/ktor PR: 5044
File: ktor-client/ktor-client-webrtc/ktor-client-webrtc-rs/build.gradle.kts:12-12
Timestamp: 2025-08-14T15:17:11.466Z
Learning: The Cargo plugin (dev.gobley.cargo) used in the Ktor WebRTC RS module depends on the kotlin("plugin.atomicfu") plugin, so atomicfu should not be removed even if there are no direct kotlinx.atomicfu imports in the module's source code.

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
📚 Learning: 2025-11-25T09:38:19.393Z
Learnt from: CR
Repo: ktorio/ktor PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-25T09:38:19.393Z
Learning: Applies to **/test/**/*.kt : Follow test naming pattern: `DescribeWhatIsBeingTested`

Applied to files:

  • ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt
🧬 Code graph analysis (4)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (5)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/Authentication.kt (3)
  • install (127-130)
  • provider (27-29)
  • provider (38-47)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BasicAuth.kt (3)
  • basic (112-117)
  • basic (126-134)
  • validate (99-101)
ktor-server/ktor-server-plugins/ktor-server-auth-api-key/common/src/io/ktor/server/auth/apikey/ApiKeyAuth.kt (3)
  • apiKey (20-25)
  • apiKey (33-41)
  • validate (131-133)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (2)
  • registerBearerAuthSecurityScheme (195-204)
  • registerBasicAuthSecurityScheme (181-186)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/DynamicProviderConfig.kt (1)
  • authenticate (19-21)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt (2)
ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt (1)
  • Components (154-197)
ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt (4)
  • security (187-189)
  • requirement (945-947)
  • requirement (956-958)
  • optional (964-966)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (2)
ktor-server/ktor-server-test-host/common/src/io/ktor/server/testing/TestApplication.kt (1)
  • startApplication (415-417)
ktor-server/ktor-server-plugins/ktor-server-auth/common/src/io/ktor/server/auth/BearerAuth.kt (1)
  • authSchemes (104-107)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt (3)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt (1)
  • generateOpenApiSpec (56-85)
ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/OpenApiSpecification.kt (1)
  • OpenApiInfo (74-130)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/SecuritySchemeAnnotation.kt (1)
  • registerApiKeySecurityScheme (214-222)
🪛 ast-grep (0.40.0)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt

[warning] 23-23: A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive data, can be leaked and used by internal or external malicious actors. It is recommended to rotate the secret and retrieve them from a secure secret vault or Hardware Security Module (HSM), alternatively environment variables can be used if allowed by your company policy.
Context: Algorithm.HMAC256(jwtSecret)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A03:2021]: Identification and Authentication Failures [REFERENCES]
- https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures

(jwt-hardcode-kotlin)

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/RouteAnnotationApiJvmTest.kt

[warning] 29-29: A secret is hard-coded in the application. Secrets stored in source code, such as credentials, identifiers, and other types of sensitive data, can be leaked and used by internal or external malicious actors. It is recommended to rotate the secret and retrieve them from a secure secret vault or Hardware Security Module (HSM), alternatively environment variables can be used if allowed by your company policy.
Context: Algorithm.HMAC256(jwtSecret)
Note: [CWE-798]: Use of Hard-coded Credentials [OWASP A03:2021]: Identification and Authentication Failures [REFERENCES]
- https://owasp.org/Top10/A07_2021-Identification_and_Authentication_Failures

(jwt-hardcode-kotlin)

🔇 Additional comments (24)
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/nonJvm/src/io/ktor/annotate/SecuritySchemeAnnotation.nonJvm.kt (1)

11-14: LGTM! Non-JVM stub implementation is correct.

The platform-specific stub correctly returns null for non-JVM targets with a clear explanatory comment. This aligns with the cross-platform design where JVM provides concrete inference for Digest and JWT providers, while non-JVM platforms have no platform-specific metadata available.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/src/io/ktor/annotate/RouteAnnotationApi.kt (2)

178-217: Well-structured OpenAPI security generation from authentication routes.

The mapping of Ktor's AuthenticationStrategy to OpenAPI security requirements is correct:

  • FirstSuccessful → separate requirements (OR relationship)
  • Required → combined map (AND relationship)
  • Optional → includes empty requirement for unauthenticated access

220-235: The destructuring order in RouteAnnotationApi.kt line 223 is correct. The OAuthFlows data class defines fields in this exact order: implicit, password, clientCredentials, authorizationCode. The destructuring matches this order, so there is no risk of silently assigning wrong flow types.

Likely an incorrect or invalid review comment.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/SecuritySchemeInferenceTest.kt (2)

7-7: Unused import.

The HttpClient import appears to be used only for creating OAuth provider configurations. Consider if this is intentional or if a mock/test client should be used instead.


16-432: Comprehensive test coverage for security scheme inference.

The test suite thoroughly covers:

  • All supported authentication provider types (basic, bearer, apiKey, session, oauth)
  • Edge cases (empty plugin, no plugin, dynamic providers)
  • Manual registration overrides
  • Caching behavior
  • Default provider naming
ktor-server/ktor-server-plugins/ktor-server-routing-annotate/common/test/io/ktor/annotate/RouteAnnotationApiTest.kt (2)

319-431: Thorough test coverage for automatic security annotations.

This test validates the correct mapping of Ktor authentication strategies to OpenAPI security requirements:

  • Single auth schemes (lines 386-402)
  • FirstSuccessful creating OR relationships (lines 404-413)
  • Required creating AND relationships (lines 415-422)
  • Optional strategy (lines 424-430)

478-531: Good OAuth2 security annotation test.

The test correctly validates OAuth2 security scheme generation including authorization code flow and scope extraction. Using this@testApplication.client for the OAuth provider configuration is an appropriate approach for testing.

ktor-shared/ktor-openapi-schema/common/src/io/ktor/openapi/Operation.kt (2)

456-459: LGTM - simplified example wrapping.

Using Value(example) directly (via the star import) is cleaner than ReferenceOr.Value(example).


949-966: Well-documented security DSL extensions.

The new methods correctly implement OpenAPI security semantics:

  • requirement(schemes: Map) for AND relationships (all schemes must be satisfied)
  • optional() adds an empty requirement per OpenAPI spec to allow unauthenticated access

The documentation clearly explains the OR/AND relationship patterns.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/RouteAnnotationApiJvmTest.kt (3)

27-30: Hardcoded test credentials are acceptable here.

The static analysis warning about hardcoded credentials is a false positive for this test file. These are test-only fixtures used to configure JWT verification in a controlled test environment, not production secrets.


39-55: Clean test helper function.

The openApiTestRoutes helper reduces duplication between tests by parameterizing the authentication provider name. This follows good test organization practices.


90-121: Good JVM-specific JWT security test.

The test correctly validates that JWT authentication providers are inferred as HTTP bearer schemes with bearerFormat: "JWT", which is important for API consumers to understand the expected token format.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.klib.api (1)

20-36: New security-scheme KLIB ABI entries look consistent with common source.

AuthSecuritySchemesAttributeKey and the Application extensions for finding/registering security schemes (including API key/basic/bearer/OAuth2/OpenID Connect) match the intended public API surface and appear ABI‑correct. No changes needed here.

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/jvm/test/io/ktor/annotate/JvmSecuritySchemeInferenceTest.kt (1)

1-147: Good JVM coverage for digest/JWT inference and registration.

The tests exercise both inferred and explicitly registered schemes (including custom descriptions and custom auth schemes) and validate type/scheme/bearerFormat/description as expected. This should give solid confidence in the JVM‐specific inference helpers.

ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.klib.api (1)

27-42: OpenAPI security-scheme ABI surface is coherent and spec-aligned.

The new SecuritySchemeIn/SecuritySchemeType enums, SecurityScheme hierarchy (API key/HTTP/OAuth2/OpenID Connect), Components.securitySchemes, OAuth flow types, and Security.Builder helpers (including optional) form a consistent model and match the OpenAPI 3.x structure. From an ABI perspective this looks well‑shaped; no further adjustments needed here.

Also applies to: 164-175, 189-229, 231-269, 557-603, 983-1103, 1270-1307, 1826-1867

ktor-server/ktor-server-plugins/ktor-server-routing-annotate/api/ktor-server-routing-annotate.api (1)

29-53: JVM ABI for security-scheme helpers matches the Kotlin declarations.

SecuritySchemeAnnotationKt and SecuritySchemeAnnotation_jvmKt expose the expected find* and register*SecurityScheme methods (including synthetic default-argument bridges) and correctly surface AuthSecuritySchemesAttributeKey. The .api looks in sync with the source module and ABI tracking requirements.

ktor-shared/ktor-openapi-schema/api/ktor-openapi-schema.api (8)

37-72: LGTM: ApiKeySecurityScheme follows OpenAPI spec and project patterns.

The structure is complete with proper serialization support, component/copy methods, and interface implementations.


107-111: LGTM: Components expansion maintains binary compatibility.

The addition of securitySchemes follows the existing pattern for component types. The synthetic constructor with DefaultConstructorMarker at line 108 indicates default parameters are used, maintaining backward compatibility for existing callers.

Based on learnings: Binary compatibility is enforced in this codebase.

Also applies to: 120-121, 133-133


819-852: LGTM: OAuth2SecurityScheme properly structured for OpenAPI OAuth2 flows.

The implementation correctly uses OAuthFlows to encapsulate the various OAuth2 flow types, consistent with OpenAPI 3.x specification.


854-927: LGTM: OAuth flow types complete per OpenAPI specification.

Both OAuthFlow and OAuthFlows correctly model the OAuth2 flow structure per OpenAPI 3.x spec. The inclusion of refreshUrl (line 870) aligns with the PR objectives for supporting refresh token flows.


1080-1113: LGTM: OpenIdConnectSecurityScheme properly models OIDC discovery.

The structure correctly uses openIdConnectUrl for the OpenID Connect discovery endpoint, consistent with OpenAPI 3.x specification.


1647-1684: LGTM: SecurityScheme interface and enums align with OpenAPI specification.

The SecurityScheme interface provides a consistent contract for all security scheme implementations. The enums (SecuritySchemeIn and SecuritySchemeType) correctly represent the valid values per OpenAPI 3.x spec.


1637-1637: LGTM: Security$Builder enhancements improve API ergonomics.

The addition of optional() and the requirement(Map<String, List>) overload provide more flexible ways to construct security requirements, complementing the existing string-based API.

Also applies to: 1639-1639


452-490: No verification needed—DEFAULT_DESCRIPTION constants are correct and consistent.

The DEFAULT_*_DESCRIPTION constants in HttpSecurityScheme already use consistent uppercase "HTTP" casing across all schemes (Basic, Bearer, Digest, JWT). Test expectations in SecuritySchemeInferenceTest.kt confirm these values are correct. No changes required.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants