π Connector SDK
Sample integration built using Connector SDK
Introduction
This guide demonstrates how to build a simple read-only Okta connector using the Lumos Connector SDK. The connector implements user synchronization functionality, mapping Okta user profiles to Lumos account structures.
Note: This sample Okta connector has been created for demonstration purposes, Lumos provides a full-featured native Okta integration.
Prerequisites
Before starting development, ensure you have:
- Python 3.10 or higher installed
- Access to an Okta developer account
- An Okta API token
- Basic familiarity with Python and async programming
Setting Up the Development Environment
First, create and activate a Python virtual environment:
# Create a new directory for your project
mkdir okta
cd okta
# Create a Python virtual environment
python -m venv .venv
# Activate the virtual environment# On Windows:
.venv\Scripts\activate
# On Unix/MacOS:
source .venv/bin/activate
# Install the Lumos Connector SDK with development dependencies
pip install "connector-py[dev]"
Generating the Facade Connector
Use the Lumos Connector SDK to generate a basic connector structure:
# Generate the connector scaffold
connector scaffold okta okta
# Install the connector's dependencies and the connector module
# It is important to use -e (editable) here so code changes will be reflected when running commands
cd okta
pip install -e ".[all]"
# Verify the installation
mypy .
pytest
Understanding the Generated Connector Structure
The scaffold command creates several key files:
Core Files
__about__.py
: Contains version informationmain.py
: Entry point for the connectorsettings.py
: Defines connector configuration modelintegration.py
: Defines connector capabilities and metadataclient.py
: Implements API client functionalityconstants.py
: Stores shared constantsenums.py
: Defines resource and entitlement types
Capability Implementation Files
capabilities_read.py
: Implements read operationscapabilities_write.py
: Implements write operations (not used in this example)
Testing Files
test_all_capabilities.py
: Main test runner- Various test case files for different capabilities
Implementing the Okta Connector
To transform the facade connector into a functional Okta connector, we modified several files:
1. Settings Model (settings.py
)
settings.py
)from pydantic import BaseModel
class OktaSettings(BaseModel):
domain: str# Okta domain e.g. "company.okta.com"
2. Type Definitions (okta_types.py
)
okta_types.py
)We created this new file to handle Okta-specific types and status mappings:
from enum import Enum
from typing import TypedDict
class OktaUserStatus(str, Enum):
ACTIVE = "ACTIVE"
SUSPENDED = "SUSPENDED"
# ... other status values
def map_okta_to_lumos_status(okta_status: str) -> str:
# ... status mapping implementation
3. Integration Configuration (integration.py
)
integration.py
)Updated to use token authentication and register appropriate capabilities:
integration = Integration(
app_id="okta",
auth=TokenCredential,
settings_model=OktaSettings,
# ... other configuration
)
integration.register_capabilities({
StandardCapabilityName.VALIDATE_CREDENTIALS: capabilities_read.validate_credentials,
StandardCapabilityName.LIST_ACCOUNTS: capabilities_read.list_accounts,
})
4. Client Implementation (client.py
)
client.py
)Implemented the Okta API client with proper authentication and user mapping:
class OktaConnectorClient(BaseIntegrationClient):
async def list_users(self, limit: int | None = None,
offset: int | None = None) -> list[FoundAccountData]:
# ... implementation of user listing and mapping
Implementation Details
User Status Mapping
The connector maps Okta user statuses to Lumos account statuses:
- ACTIVE β ACTIVE
- SUSPENDED β SUSPENDED
- DEPROVISIONED β DEPROVISIONED
- STAGED β PENDING
- Others β INACTIVE
Pagination
The implementation supports pagination using Okta's offset-based pagination mechanism, allowing the connector to handle large user sets efficiently.
Error Handling
The connector implements proper error handling for API failures and includes type validation to ensure data consistency.
Testing the Connector
Execute the test suite to verify the implementation:
# Run type checking
mypy .
# Run unit tests
pytest
# Test specific capabilities
okta validate_credentials --json "{\"request\":{},\"settings\":{\"domain\":\"test-domain.okta.com\"},\"auth\":{\"oauth\":null,\"oauth_client_credentials\":null,\"basic\":null,\"token\":{\"token\":\"test-token\"},\"jwt\":null}}"
Expected output:
INFO HTTP Request: GET https://test-domain.okta.com/api/v1/users?limit=1 "HTTP/1.1 200 OK"
INFO Result printing to console
{"response":{"valid":true,"unique_tenant_id":"okta_test-domain.okta.com"},"raw_data":null,"page":null}
INFO Command completed
Deployment
To deploy the connector:
# Build the on-premise connector
connector compile-on-prem --connector-root-module-dir ./okta/okta --app-id okta
The compiled connector (e.g., okta-0.1.0.tar.gz) can then be deployed to the Lumos on-premise agent environment by copying it to the connectors folder (e.g., /lumos-on-premise-agent/connectors)
After a minute, the connector will be available for configuration in the Lumos administrative user interface under Integrations where it can be configured.
Once connected, it will show confirmation.
A few minutes later, after the import is completed, the users imported via this connector will be shown in the Apps page.
Best Practices and Considerations
When implementing your own connector:
- Maintain proper type hints and documentation
- Implement comprehensive error handling
- Use appropriate status mapping for your system
- Consider implementing rate limiting for production use
- Add logging for better observability
- Include comprehensive test coverage
- Pin your version of the Connector SDK. This means that in the generated
pyproject.toml
, you ensure that references toconnector-py
include a specific version. For example:"connector-py == 4.18.0"
. Check pypi for version history.
The complete implementation is available for reference, demonstrating these best practices while maintaining clean, maintainable code.
Updated 15 days ago