Customize Authentication

Authentication Overview

Speakeasy created SDKs have authentication configured automatically based on the securitySchemes defined in your OpenAPI specification.

For APIs that are authenticated by long-lived tokens (API Key), these should work out of the box. For APIs that are authenticated by short-lived tokens (oAuth), extra configuration is required to minimize any effort by your users.

securitySchemes Support

In your OpenAPI specification, define the securitySchemes object in accordance with your APIs authentiation mechanism.

Authentication MechanismLanguage Support
HTTP Basic Authentication✅ All Languages
API Key [header]✅ All Languages
API Key [cookie]✅ All Languages
API Key [query param]✅ All Languages
API Key [Bearer]✅ All Languages
oAuth Implicit Flow✅ All Languages
oAuth Refresh Token Flow🏗️ Partial
oAuth Client Credentials Flow🏗️ Partial
mTLS🏗️ Partial

HTTP Basic Authentication

Supported in all languages, defining basic authentication will prompt users for a username and password when instantiating the SDK.

paths:
  /drinks:
    get:
      operationId: listDrinks
      summary: Get a list of drinks.
      description: Get a list of drinks, if authenticated this will include stock levels and product codes otherwise it will only include public information.
      tags:
        - drinks
components:
  securitySchemes:
    auth:
      type: http
      scheme: basic
security:
  - auth: []
const s = sdk.SDK(
  (security = shared.Security(
    (username = "..MY_USER.."),
    (password = "..MY_PASSWORD..")
  ))
);
await s.list_drinks();

API Key Authentication

Supported in all languages, defining api_key authentication will prompt users for a key when instantiating the SDK. How the key is passed to your API will be abstracted from your users. However, we support the key being passed as a header, cookie, query param, or as a bearer token.

paths:
  /drinks:
    get:
      operationId: listDrinks
      summary: Get a list of drinks.
      description: Get a list of drinks, if authenticated this will include stock levels and product codes otherwise it will only include public information.
      tags:
        - drinks
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: api_key
      in: header
security:
  - api_key: []
const s = new SDK({ security: { apiKey: "..MY_KEY.." } });
await s.drinks.listDrinks();

OAuth

Speakeasy supports OAuth authentication in the most popular languages with support for additional languages coming soon.

TypescriptPythonGoC#JavaPHPSwiftRuby
🏗️🏗️🏗️🏗️🏗️

Enabling OAuth security in your SDK currently requires additional configuration outside of your OpenAPI spec.

Step 1: Define OAuth Security in your OpenAPI Spec

Our current Oauth support does not use the OpenAPI description, but native support is on the way, so don't skip this step!

  /oauth2/token:
    get:
      operationId: auth
      security:
        - []
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token: string
                required:
                  - access_token
  /example:
    get:
      operationId: example
      responses:
        200:
          description: OK
components:
  securitySchemes:
    auth:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://speakeasy.bar/oauth2/token/
          scopes: {}
security:
  - auth: []

Step 2: Add Your Callback Function to your SDKs

To implement OAuth authentication, you will need to write a callback function to handle your Oauth token exchange. To do so, add a file to your SDKs src folder called oauth.ts (or oauth.py for python, oauth.go for go, etc):

function withAuthorization(clientID: string, clientSecret: string): (args: CallbackArgs) => Promise<[string, Error]> {
  return async (args: CallbackArgs): Promise<[string, Error]> => {
    const tokenEndpoint = 'https://speakeasy.bar/oauth2/token/';
    const data = {
      grant_type: 'client_credentials',
      client_id: clientID,
      client_secret: clientSecret,
    };
    try {
      const response = await axios.post(tokenEndpoint, data);
      return response.data.access_token;
    } catch (error) {
      throw new Error('Failed to obtain OAuth token');
    }
  };
}
 

Step 3: Pass Callback Function In SDK Instantiation

You'll need to edit your Readme to instruct users to pass in the callback function when instantiating the SDK. Our recommendation is to add a custom Oauth section which shows users how to instantiate their SDK via the callback function:

  const s = new SDK({ securitySource: { callback: withAuthorization("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET") } });
  await s.listDrinks();
 

Scoping Authentication

Global

Global security allows your users to configure the SDK once, and re-use the security configuration for all subsequent aclls

To use Global security, define your security configuration in the security block at the root of the SDK.

paths:
  /drinks:
    get:
      operationId: listDrinks
      summary: Get a list of drinks.
      description: Get a list of drinks, if authenticated this will include stock levels and product codes otherwise it will only include public information.
      tags:
        - drinks
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: api_key
      in: header
security: # Here
  - api_key: []

In the resulting SDK, the user will be able to define the security configuration in the SDK's instantiation. It will then be automatically applied to all subsequent method calls without needing to be passed in as an argument:

const s = new SDK({ security: { apiKey: "..MY_KEY.." } });
await s.drinks.listDrinks();

Per-Operation

Info Icon

NOTE

Security Hoisting: In the case where global security is not defined, we will automatically hoist the most commonly occurring operation level security to be considered global. This will simplify usage of your SDK.

Operation-specific security configuration allows for overriding one endpoint's authentication configuration.

This is most often used for operations that do not require authentication, or for when the operation is used as part of an authentication flow (e.g. invoked to retrieve an shorter-lived access token).

To use Operation-specific security, define security within an operation's scope.

paths:
  /drinks:
    get:
      operationId: listDrinks
      summary: Get a list of drinks.
      description: Get a list of drinks, if authenticated this will include stock levels and product codes otherwise it will only include public information.
      security:
        - apiKey: []
      tags:
        - drinks
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: api_key
      in: header

In the SDK the user will be able to pass in a specific security configuration as an argument to the method call:

const sdk = new SDK();
const operationSecurity: ListDrinksSecurity = {
  apiKey: "",
};
 
sdk.drinks.listDrinks(operationSecurity).then((res: ListDrinksResponse) => {
  if (res.statusCode == 200) {
    // handle response
  }
});