A Python-based SCIM 1.1 server that enables Okta to import users from SQL Server databases using the On-Premises Provisioning (OPP) Agent.
This connector provides inbound provisioning from SQL Server to Okta. The SCIM server acts as a bridge between your SQL database and Okta's OPP Agent, allowing you to import users with flexible column mapping.
SQL Database → SCIM Server (this app) → Okta OPP Agent → Okta Tenant
This repository includes both SCIM 1.1 and SCIM 2.0 implementations:
| Version | File | Use Case |
|---|---|---|
| SCIM 1.1 | inbound_app.py |
✅ Default - Works with all Okta tenants |
| SCIM 2.0 | scim2_app.py |
Not sure which to use? Start with SCIM 1.1 (inbound_app.py)
SCIM 2.0 Requirements:
- Okta Provisioning Agent 2.1.0 or later
- Early Access feature enabled (self-service, no support ticket needed)
- See Enable Instructions
See SCIM Version Comparison for detailed differences.
- ✅ Two SCIM versions: SCIM 1.1 (default) and SCIM 2.0 (requires OPP Agent 2.1.0+)
- ✅ SCIM 1.1 protocol compliance (compatible with all OPP Agent versions)
- ✅ SCIM 2.0 protocol compliance (requires OPP Agent 2.1.0+ and self-service EA feature)
- ✅ Flexible SQL column mapping via environment variables
- ✅ Support for pagination and filtering
- ✅ Health check endpoint for monitoring
- ✅ Basic authentication for SCIM endpoints
- ✅ Configurable user attributes (name, email, active status, etc.)
- ✅ Supports any SQL Server database schema
- Windows Server (or Linux with Python 3.7+)
- SQL Server database with user data
- Okta tenant with OPP Agent installed
- Python 3.7 or higher
- Administrator access (for running on port 443)
git clone https://github.com/your-org/okta-scim-sql-connector.git
cd okta-scim-sql-connectorpython -m venv venv
venv\Scripts\activate # On Windows
# source venv/bin/activate # On Linux/Mac
pip install -r requirements.txtCopy .env.example to .env and update with your settings:
cp .env.example .envEdit .env with your SQL Server and column mapping details.
# Run SCIM 1.1 server (default - recommended)
python inbound_app.py
# OR run SCIM 2.0 server (requires feature flag from Okta Support)
python scim2_app.py
# Run on port 443 (production) - requires Administrator
# Run PowerShell as Administrator first
python inbound_app.py # or scim2_app.pyWhich version? See SCIM Version Comparison
- Open Okta OPP Agent configuration
- Set SCIM Base URL:
https://your-server:443/scim/v2 - Set Authentication: Basic Auth
- Username: (value from
SCIM_USERNAMEin .env) - Password: (value from
SCIM_PASSWORDin .env)
- Username: (value from
- Test connection
- Import users
Configure your SQL Server connection in .env:
DB_DRIVER=SQL Server
DB_SERVER=your-sql-server.company.com
DB_NAME=YourDatabase
DB_USERNAME=sql_user
DB_PASSWORD=your_passwordMap your SQL columns to SCIM attributes:
# Required Fields
DB_COLUMN_ID=user_id
DB_COLUMN_USERNAME=email
DB_COLUMN_EMAIL=email
# Optional Fields
DB_COLUMN_FIRST_NAME=first_name
DB_COLUMN_LAST_NAME=last_name
DB_COLUMN_DISPLAY_NAME=display_name
DB_COLUMN_ACTIVE=is_active
DB_COLUMN_EXTERNAL_ID=employee_idSet credentials for OPP Agent authentication:
SCIM_USERNAME=okta_import
SCIM_PASSWORD=SecureImportPassword123!SERVER_HOST=0.0.0.0
SERVER_PORT=443| Endpoint | Method | Description |
|---|---|---|
/scim/v2/Users |
GET | List all users |
/scim/v2/Users?startIndex={n}&count={n} |
GET | Paginated user list |
/scim/v2/Users/{id} |
GET | Get specific user |
/scim/v2/ServiceProviderConfig |
GET | SCIM capabilities |
/health |
GET | Health check |
1. Schema Version Mismatch Error
Error: 'urn:scim:schemas:core:1.0' must be declared
Solution: Check what version of SCIM your OPP agent and Okta console support. Consider enabling SCIM 2.0 or using the SCIM 1.1 version
2. Port 443 Requires Administrator
Error: Permission denied
Solution: Run PowerShell as Administrator before starting the server.
3. Database Connection Fails
Error: Connection refused
Solution: Check:
- SQL Server allows remote connections
- Firewall rules allow connection
- SQL Server authentication is enabled
- Credentials are correct
4. No Users Returned
Solution: Check:
- SQL query in code matches your table name
- Column mappings in
.envare correct - Users exist in the database
Edit inbound_app.py and set:
app.run(host=SERVER_HOST, port=SERVER_PORT, debug=True)python test_db_connection.py# PowerShell
$creds = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("okta_import:SecureImportPassword123!"))
$headers = @{ "Authorization" = "Basic $creds" }
Invoke-RestMethod -Uri "http://localhost:443/scim/v2/Users?count=5" -Headers $headers | ConvertTo-Json -Depth 5curl http://localhost:443/healthSee docs/deployment/windows-service-deployment.md for instructions on running as a Windows Service.
- Use HTTPS in production (configure SSL certificate)
- Use strong SCIM credentials
- Restrict network access to OPP Agent only
- Use SQL Server accounts with read-only access
- Enable SQL Server encryption
- Regularly rotate credentials
- Store credentials in a secure vault and access programmatically
- Adjust pagination size in code (default: 100)
- Optimize SQL query with proper indexes
- Consider database connection pooling
- Monitor memory usage for large user sets
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
For issues or questions:
- Open a GitHub issue
- Contact your Okta Solutions Engineering team
- Check Okta documentation: https://help.okta.com
Built for Okta Solutions Engineers to demonstrate SQL database import capabilities.
Version: 1.0.0
Last Updated: October 2025
Maintainer: Joe Van Horn, Okta Office of the Field CTO