From 0e8332e2e9f2fbe852bfda73a584bcc6a5a53420 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 9 Dec 2025 12:31:43 +0000 Subject: [PATCH 1/2] docs: fix security callbacks documentation for single vs multiple schemes Co-Authored-By: ash@speakeasyapi.dev --- .../authentication/security-callbacks.mdx | 284 ++++++++++++------ 1 file changed, 199 insertions(+), 85 deletions(-) diff --git a/docs/sdks/customize/authentication/security-callbacks.mdx b/docs/sdks/customize/authentication/security-callbacks.mdx index 370df553..ad1b3b1a 100644 --- a/docs/sdks/customize/authentication/security-callbacks.mdx +++ b/docs/sdks/customize/authentication/security-callbacks.mdx @@ -28,9 +28,9 @@ Instead of providing credentials once during SDK instantiation, pass a custom au ]} /> -## Example: Bearer authentication +## Single security scheme -In this example, bearer authentication is used as the only security scheme: +When your OpenAPI spec defines a single security scheme, the SDK exposes the scheme name directly as a property that accepts a callback function returning the credential value. ```yaml security: @@ -42,7 +42,7 @@ components: scheme: bearer ``` -The callback function passed when initializing the SDK acts as a _security source_ and is called whenever a request is made, allowing tokens to be refreshed if needed. +The callback function is called whenever a request is made, allowing tokens to be refreshed if needed. "; - import { Security } from "/models"; - const sdk = new SDK({ - security: async (): Promise => { - // refresh token here - const token = ""; - return { bearerAuth: token }; - }, - });`, +const sdk = new SDK({ + bearerAuth: async (): Promise => { + // refresh token here + const token = await getToken(); + return token; + }, +});`, }, { label: "Python", language: "python", - code: `import requests - import sdk - from sdk.components import Security + code: `import sdk - def callback() -> Security: - # refresh token here - token = "" - return Security(bearer_auth=token) +async def get_token() -> str: + # refresh token here + token = "" + return token - s = sdk.SDK(security=with_authorization(callback))`, +s = sdk.SDK(bearer_auth=get_token)`, }, { label: "Go", language: "go", code: `import ( - "context" - sdk "speakeasy" - "speakeasy/components" - ) - - s := sdk.New( - sdk.WithSecuritySource(func(ctx context.Context) (components.Security, error) { - // refresh token here - token := "" - return components.Security{BearerAuth: token}, nil - }), - )`, + "context" + sdk "speakeasy" +) + +s := sdk.New( + sdk.WithBearerAuth(func(ctx context.Context) (string, error) { + // refresh token here + token := "" + return token, nil + }), +)`, }, { label: "Java", language: "java", code: `import dev.speakeasyapi.speakeasy.SDK; - import dev.speakeasyapi.speakeasy.SecuritySource; - import dev.speakeasyapi.speakeasy.models.components.Security; +import java.util.function.Supplier; + +Supplier tokenSupplier = () -> { + // refresh token here + return ""; +}; + +SDK s = SDK.builder() + .bearerAuth(tokenSupplier) + .build();`, + }, + { + label: "C#", + language: "csharp", + code: `using Speakeasy; + +Func tokenSource = () => +{ + // refresh token here + return ""; +}; +var sdk = new SDK(bearerAuth: tokenSource);`, + }, + { + label: "PHP", + language: "php", + code: `use Speakeasy\\Speakeasy; - class BearerSource implements SecuritySource { +$sdk = Speakeasy\\SDK::builder() + ->setBearerAuth( + function (): string { + // refresh token here + return ""; + } + )->build();`, + }, + { + label: "Ruby", + language: "ruby", + code: `require 'speakeasy' - public Security getSecurity() { - // refresh token here - return Security.builder() - .bearerAuth("") - .build(); - } +sdk = Speakeasy::SDK.new( + bearer_auth: -> { + # Refresh token here + '' } +)`, + }, + ]} +/> + +## Multiple security schemes - _____________________________________ +When your OpenAPI spec defines multiple security schemes, the SDK exposes a `security` property that accepts a callback function returning a `Security` object. This allows you to dynamically choose which authentication method to use. +```yaml +security: + - bearerAuth: [] + - apiKeyAuth: [] +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + apiKeyAuth: + type: apiKey + in: header + name: X-API-Key +``` - import dev.speakeasyapi.speakeasy.SDK; - import dev.speakeasyapi.speakeasy.SecuritySource; - import dev.speakeasyapi.speakeasy.models.components.Security; +The callback function is called whenever a request is made, allowing you to return the appropriate credentials. - SDK s = SDK.builder() - .securitySource(new BearerSource()) - .build();`, +"; +import { Security } from "/models"; + +const sdk = new SDK({ + security: async (): Promise => { + // Choose which auth method to use and refresh if needed + const token = await getToken(); + return { bearerAuth: token }; + // OR: return { apiKeyAuth: "your-api-key" }; + }, +});`, + }, + { + label: "Python", + language: "python", + code: `import sdk +from sdk.components import Security + +def callback() -> Security: + # Choose which auth method to use and refresh if needed + token = "" + return Security(bearer_auth=token) + # OR: return Security(api_key_auth="your-api-key") + +s = sdk.SDK(security=callback)`, + }, + { + label: "Go", + language: "go", + code: `import ( + "context" + sdk "speakeasy" + "speakeasy/components" +) + +s := sdk.New( + sdk.WithSecuritySource(func(ctx context.Context) (components.Security, error) { + // Choose which auth method to use and refresh if needed + token := "" + return components.Security{BearerAuth: token}, nil + // OR: return components.Security{APIKeyAuth: "your-api-key"}, nil + }), +)`, + }, + { + label: "Java", + language: "java", + code: `import dev.speakeasyapi.speakeasy.SDK; +import dev.speakeasyapi.speakeasy.SecuritySource; +import dev.speakeasyapi.speakeasy.models.components.Security; + + +class MultiAuthSource implements SecuritySource { + + public Security getSecurity() { + // Choose which auth method to use and refresh if needed + return Security.builder() + .bearerAuth("") + .build(); + // OR: return Security.builder().apiKeyAuth("your-api-key").build(); + } +} + +_____________________________________ + + +import dev.speakeasyapi.speakeasy.SDK; +import dev.speakeasyapi.speakeasy.SecuritySource; +import dev.speakeasyapi.speakeasy.models.components.Security; + +SDK s = SDK.builder() + .securitySource(new MultiAuthSource()) + .build();`, }, { label: "C#", language: "csharp", code: `using Speakeasy; - using Speakeasy.Models.Components; +using Speakeasy.Models.Components; - Func tokenSource = () => - { - // refresh token here - var token = "" +Func securitySource = () => +{ + // Choose which auth method to use and refresh if needed + var token = ""; - return new Security { BearerAuth = token} - } + return new Security { BearerAuth = token }; + // OR: return new Security { ApiKeyAuth = "your-api-key" }; +}; - var sdk = new SDK(securitySource: tokenSource);`, +var sdk = new SDK(securitySource: securitySource);`, }, { label: "PHP", language: "php", code: `use Speakeasy\\Speakeasy; - $sdk = Speakeasy\\SDK::builder() - ->setSecuritySource( - function (): Security { - //refresh token here - var token = ""; - - return new Security(bearerAuth: $token); - } - )->build(); - - try { - $res = $sdk->drinks->listDrinks(); - - if ($res->Drinks != null) { - // handle response - } - } catch (Errors\\ErrorThrowable $e) { - // handle exception - }`, +$sdk = Speakeasy\\SDK::builder() + ->setSecuritySource( + function (): Security { + // Choose which auth method to use and refresh if needed + $token = ""; + + return new Security(bearerAuth: $token); + // OR: return new Security(apiKeyAuth: "your-api-key"); + } + )->build();`, }, { label: "Ruby", language: "ruby", code: `require 'speakeasy' - sdk = Speakeasy::SDK.new( - security_source: -> { - # Refresh token here - token = '' - - Models::Components::Security.new(bearer_auth: token) - } - ) +sdk = Speakeasy::SDK.new( + security_source: -> { + # Choose which auth method to use and refresh if needed + token = '' - res = sdk.drinks.list_drinks`, -} -]} + Models::Components::Security.new(bearer_auth: token) + # OR: Models::Components::Security.new(api_key_auth: 'your-api-key') + } +)`, + }, + ]} /> From e48637f6239ae00a0d8feb6d406231957f16fa81 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 9 Dec 2025 12:42:12 +0000 Subject: [PATCH 2/2] docs: scale back changes to TypeScript only, revert other languages Co-Authored-By: ash@speakeasyapi.dev --- .../authentication/security-callbacks.mdx | 272 ++++++++++-------- 1 file changed, 158 insertions(+), 114 deletions(-) diff --git a/docs/sdks/customize/authentication/security-callbacks.mdx b/docs/sdks/customize/authentication/security-callbacks.mdx index ad1b3b1a..608346b3 100644 --- a/docs/sdks/customize/authentication/security-callbacks.mdx +++ b/docs/sdks/customize/authentication/security-callbacks.mdx @@ -62,85 +62,122 @@ const sdk = new SDK({ { label: "Python", language: "python", - code: `import sdk + code: `import requests + import sdk + from sdk.components import Security -async def get_token() -> str: - # refresh token here - token = "" - return token + def callback() -> Security: + # refresh token here + token = "" + return Security(bearer_auth=token) -s = sdk.SDK(bearer_auth=get_token)`, + s = sdk.SDK(security=with_authorization(callback))`, }, { label: "Go", language: "go", code: `import ( - "context" - sdk "speakeasy" -) - -s := sdk.New( - sdk.WithBearerAuth(func(ctx context.Context) (string, error) { - // refresh token here - token := "" - return token, nil - }), -)`, + "context" + sdk "speakeasy" + "speakeasy/components" + ) + + s := sdk.New( + sdk.WithSecuritySource(func(ctx context.Context) (components.Security, error) { + // refresh token here + token := "" + return components.Security{BearerAuth: token}, nil + }), + )`, }, { label: "Java", language: "java", code: `import dev.speakeasyapi.speakeasy.SDK; -import java.util.function.Supplier; + import dev.speakeasyapi.speakeasy.SecuritySource; + import dev.speakeasyapi.speakeasy.models.components.Security; -Supplier tokenSupplier = () -> { - // refresh token here - return ""; -}; -SDK s = SDK.builder() - .bearerAuth(tokenSupplier) - .build();`, + class BearerSource implements SecuritySource { + + public Security getSecurity() { + // refresh token here + return Security.builder() + .bearerAuth("") + .build(); + } + } + + _____________________________________ + + + import dev.speakeasyapi.speakeasy.SDK; + import dev.speakeasyapi.speakeasy.SecuritySource; + import dev.speakeasyapi.speakeasy.models.components.Security; + + SDK s = SDK.builder() + .securitySource(new BearerSource()) + .build();`, }, { label: "C#", language: "csharp", code: `using Speakeasy; + using Speakeasy.Models.Components; -Func tokenSource = () => -{ - // refresh token here - return ""; -}; -var sdk = new SDK(bearerAuth: tokenSource);`, + Func tokenSource = () => + { + // refresh token here + var token = "" + + return new Security { BearerAuth = token} + } + + var sdk = new SDK(securitySource: tokenSource);`, }, { label: "PHP", language: "php", code: `use Speakeasy\\Speakeasy; -$sdk = Speakeasy\\SDK::builder() - ->setBearerAuth( - function (): string { - // refresh token here - return ""; - } - )->build();`, + $sdk = Speakeasy\\SDK::builder() + ->setSecuritySource( + function (): Security { + //refresh token here + var token = ""; + + return new Security(bearerAuth: $token); + } + )->build(); + + try { + $res = $sdk->drinks->listDrinks(); + + if ($res->Drinks != null) { + // handle response + } + } catch (Errors\\ErrorThrowable $e) { + // handle exception + }`, }, { label: "Ruby", language: "ruby", code: `require 'speakeasy' -sdk = Speakeasy::SDK.new( - bearer_auth: -> { - # Refresh token here - '' - } -)`, - }, - ]} + sdk = Speakeasy::SDK.new( + security_source: -> { + # Refresh token here + token = '' + + Models::Components::Security.new(bearer_auth: token) + } + ) + + res = sdk.drinks.list_drinks`, +} +]} /> ## Multiple security schemes @@ -184,113 +221,120 @@ const sdk = new SDK({ { label: "Python", language: "python", - code: `import sdk -from sdk.components import Security + code: `import requests + import sdk + from sdk.components import Security -def callback() -> Security: - # Choose which auth method to use and refresh if needed - token = "" - return Security(bearer_auth=token) - # OR: return Security(api_key_auth="your-api-key") + def callback() -> Security: + # refresh token here + token = "" + return Security(bearer_auth=token) -s = sdk.SDK(security=callback)`, + s = sdk.SDK(security=with_authorization(callback))`, }, { label: "Go", language: "go", code: `import ( - "context" - sdk "speakeasy" - "speakeasy/components" -) - -s := sdk.New( - sdk.WithSecuritySource(func(ctx context.Context) (components.Security, error) { - // Choose which auth method to use and refresh if needed - token := "" - return components.Security{BearerAuth: token}, nil - // OR: return components.Security{APIKeyAuth: "your-api-key"}, nil - }), -)`, + "context" + sdk "speakeasy" + "speakeasy/components" + ) + + s := sdk.New( + sdk.WithSecuritySource(func(ctx context.Context) (components.Security, error) { + // refresh token here + token := "" + return components.Security{BearerAuth: token}, nil + }), + )`, }, { label: "Java", language: "java", code: `import dev.speakeasyapi.speakeasy.SDK; -import dev.speakeasyapi.speakeasy.SecuritySource; -import dev.speakeasyapi.speakeasy.models.components.Security; + import dev.speakeasyapi.speakeasy.SecuritySource; + import dev.speakeasyapi.speakeasy.models.components.Security; -class MultiAuthSource implements SecuritySource { + class BearerSource implements SecuritySource { - public Security getSecurity() { - // Choose which auth method to use and refresh if needed - return Security.builder() - .bearerAuth("") - .build(); - // OR: return Security.builder().apiKeyAuth("your-api-key").build(); - } -} + public Security getSecurity() { + // refresh token here + return Security.builder() + .bearerAuth("") + .build(); + } + } -_____________________________________ + _____________________________________ -import dev.speakeasyapi.speakeasy.SDK; -import dev.speakeasyapi.speakeasy.SecuritySource; -import dev.speakeasyapi.speakeasy.models.components.Security; + import dev.speakeasyapi.speakeasy.SDK; + import dev.speakeasyapi.speakeasy.SecuritySource; + import dev.speakeasyapi.speakeasy.models.components.Security; -SDK s = SDK.builder() - .securitySource(new MultiAuthSource()) - .build();`, + SDK s = SDK.builder() + .securitySource(new BearerSource()) + .build();`, }, { label: "C#", language: "csharp", code: `using Speakeasy; -using Speakeasy.Models.Components; + using Speakeasy.Models.Components; -Func securitySource = () => -{ - // Choose which auth method to use and refresh if needed - var token = ""; + Func tokenSource = () => + { + // refresh token here + var token = "" - return new Security { BearerAuth = token }; - // OR: return new Security { ApiKeyAuth = "your-api-key" }; -}; + return new Security { BearerAuth = token} + } -var sdk = new SDK(securitySource: securitySource);`, + var sdk = new SDK(securitySource: tokenSource);`, }, { label: "PHP", language: "php", code: `use Speakeasy\\Speakeasy; -$sdk = Speakeasy\\SDK::builder() - ->setSecuritySource( - function (): Security { - // Choose which auth method to use and refresh if needed - $token = ""; - - return new Security(bearerAuth: $token); - // OR: return new Security(apiKeyAuth: "your-api-key"); - } - )->build();`, + $sdk = Speakeasy\\SDK::builder() + ->setSecuritySource( + function (): Security { + //refresh token here + var token = ""; + + return new Security(bearerAuth: $token); + } + )->build(); + + try { + $res = $sdk->drinks->listDrinks(); + + if ($res->Drinks != null) { + // handle response + } + } catch (Errors\\ErrorThrowable $e) { + // handle exception + }`, }, { label: "Ruby", language: "ruby", code: `require 'speakeasy' -sdk = Speakeasy::SDK.new( - security_source: -> { - # Choose which auth method to use and refresh if needed - token = '' + sdk = Speakeasy::SDK.new( + security_source: -> { + # Refresh token here + token = '' - Models::Components::Security.new(bearer_auth: token) - # OR: Models::Components::Security.new(api_key_auth: 'your-api-key') - } -)`, - }, - ]} + Models::Components::Security.new(bearer_auth: token) + } + ) + + res = sdk.drinks.list_drinks`, +} +]} />