Authentication is a crucial aspect of Lumos Integration connectors, ensuring secure and authorized access to third-party APIs. This section outlines the recommended authentication approach used in Lumos connectors.
Recommended Principles
- OAuth2 Preference: OAuth2 is the preferred authentication method for Lumos connectors due to its security and flexibility.
- Credential Readiness: Connectors expect authentication credentials to be ready for use, the connector SDK has a fully fledged OAuth module, which handles specific authorization capabilities.
- Standardized Implementation: Authentication is implemented inside the
client.py
during itβs initialization and the SDK offers pre-defined models for the most common authentication schemes.
OAuth2 Authentication Flow
The general process is as follows:
- The user initiates the OAuth flow with the third-party service, using a
Connect
button in Lumos. - After successful authentication, the service provides an access token.
- This access token, along with any other required credentials, is saved and later on passed to the Lumos connector.
- The connector uses these credentials for all subsequent API requests.
Implementing Authentication
Client class
Each connector typically implements a client class (extending the BaseIntegrationClient
SDK class) in a dedicated client.py
file:
# Example: abc/client.py
import httpx
from connector.oai.base_clients import BaseIntegrationClient
from connector.oai.capability import Request, get_oauth
from connector.utils.httpx_auth import BearerAuth
BASE_URL = 'https://api.abc.com'
class AbcClient(BaseIntegrationClient):
requires_response_body = True
@classmethod
def prepare_client_args(cls, args: Request) -> dict[str, t.Any]:
return {
"auth": BearerAuth(token=get_oauth(args).access_token),
"base_url": BASE_URL,
}
# Implement your API calls / client methods below
The BaseIntegrationClient class serves as the minimal abstraction layer for writing a httpx AsyncClient
implementation. The prepare_client_args class method then provides arguments for httpx
to initialize.
Integration Configuration
In the integration.py file, the authentication type and other connector-specific settings are specified in the Integration object. This configuration can be more complex than when just using a standard OAuth credential. The following is an example when using OAuth2 Authorziation Code Flow:
# Example: abc/Integration.py
from abc.settings import AbcSettings
from connector.generated import OauthCredential
from connector.oai.modules.oauth_module_types import OAuthSettings
integration = Integration(
app_id="abc",
settings_model=AbcSettings,
auth=OAuthCredential,
oauth_settings=OAuthSettings(
authorization_url="https://abc/oauth/authorize",
token_url="https://abc/oauth/token",
),
)
This example assumes that Lumos can and will acquire a public OAuth application that users can authorize with and provide consent to impersonate the logged in user.
Custom Authentication Models
Connectors often require custom authentication models that extend the basic credential types provided by Lumos. These are typically defined in <connector>/settings.py.
Token Based Authentication
# Example: abc/settings.py
import pydantic
from connector.generated import TokenCredential
from connector.serializers.request import AnnotatedField
class abcTokenAuth(TokenCredential):
token: str = AnnotatedField(
title="API Token",
description=(
"To create an API Token, navigate to abc dashboard"
),
secret=True,
)
This custom model:
- ExtendsΒ
TokenCredential
Β for token-based authentication. - UsesΒ
AnnotatedField
Β to ensure secure handling of the token, using thesecret
argument.
Basic Authentication
# Example: abc/settings.py
import pydantic
from connector.generated import BasicCredential
from connector.serializers.request import AnnotatedField
class abcBasicAuth(BasicCredential):
username: str = AnnotatedField(
title="Username",
description=(
"Your username"
),
)
password: str = AnnotatedField(
title="Password",
description=(
"Your password"
),
secret=True,
)
This custom model:
- ExtendsΒ
BasicCredential
Β for basic authentication. - UsesΒ
AnnotatedField
Β to ensure secure handling of the password, using thesecret
argument.
OAuth Client Credentials Flow
Sometimes called machine to machine flow, this OAuth flow is widely used for server-side communication. It requires the caller to authorize and obtain an access_token in a single request-response flow.
For the Client Credentials Flow authentication, you might extend the OAuthClientCredential model. Here's an example:
# Example: abc/settings.py
from connector.generated import OAuthClientCredential
from connector.serializers.request import AnnotatedField
from pydantic import Field
class AbcOAuthClientCredentials(OAuthClientCredential):
scopes: list[str] = AnnotatedField(title="Scopes", hidden=True)
access_token: str = AnnotatedField(title="Access Token", hidden=True)
client_id: str = Field(
title="Client ID",
description="Specific instructions to obtain a Client ID.",
)
client_secret: str = SecretField(
title="Client Secret",
description="Specific instructions to obtain a Client Secret",
)
# Example: abc/integration.py
from abc.settings import AbcAuth, AbcSettings
from connector.oai.modules.oauth_module_types import OAuthCapabilities, OAuthFlowType, OAuthSettings
integration = Integration(
app_id="abc",
settings_model=AbcSettings,
auth=AbcAuth,
oauth_settings=OAuthSettings(
capabilities=OAuthCapabilities(
# Client Credentials Flow often does not support refreshing
# You should disable the capability of this module if that is the case
refresh_access_token=False,
),
token_url="https://abc.com/oauth/token",
flow_type=OAuthFlowType.CLIENT_CREDENTIALS,
scopes={
StandardCapabilityName.LIST_ACCOUNTS: "some required scopes separated with space",
# ...
},
),
)
This example shows how you can extend the standard OAuthClientCredential
model and use the SDK provided OAuth module.
Best Practices
- Security: Use appropriate field types (e.g.,Β
AnnotatedField
with respective arguments likehidden
(from end user, for example when not needed), andsecret
(sensitive secret)) for sensitive information. - Extensibility: Design your authentication and settings models to be easily extensible as API requirements change.
- Validation: Leverage Pydantic's validation capabilities to ensure that provided credentials and settings meet the required format and constraints. The SDK has many different utilities that assist with this, like
get_oauth
,get_token
, etc.
Connector Specific Considerations
While the general structure remains consistent, each connector may have unique authentication requirements.
Always refer to the specific API documentation of the service you're integrating with for the most accurate authentication requirements.
If you require multiple authentication credentials, it is recommended to append the extra credentials to the Settings object using appropriate secret arguments.