Overview
This guide provides step-by-step instructions for integrating OneLogin with Netskope Security Posture Management (SSPM) using the Bring Your Own App (BYOA) feature. BYOA allows you to extend SSPM's security monitoring capabilities to custom SaaS applications that are not natively supported by Netskope.
Benefits
- Extended Coverage: Monitor OneLogin's security posture alongside other SaaS applications
- Centralized Monitoring: Single pane of view for all SSPM-supported and custom apps
- Integrated Reporting: Unified reporting and alerting across all monitored applications
- Custom Rules: Create custom security rules using Netskope Governance Language (NGL)
Prerequisites
- Netskope tenant with BYOA feature enabled (contact Netskope support)
- OneLogin administrator account with API access
- Access to Netskope SSPM APIs (see Swagger documentation at https://<your-tenant>.goskope.com/apidocs/)
Table of Contents
- Step 1: Register & Onboard Custom App in Netskope SSPM
- Step 2: Create API Credentials in OneLogin
- Step 3: Generate OneLogin Access Token
- Step 4: Fetch Data from OneLogin APIs
- Step 5: Transform & Push Data to Netskope SSPM
- Step 6: Verify Integration & Next Steps
Step 1: Register & Onboard Custom App in Netskope SSPM
1.1 Prerequisites
Before starting, ensure you have:
- BYOA feature enabled for your Netskope tenant (contact Netskope support)
- API token with appropriate permissions:
- RBACv2: Read + Write access for:
- /api/v2/spm/ingestor/customapps
- /api/v2/spm/contentdef/customapps
- /api/v2/spm/customapps
- RBACv3:
- Go to Settings → Administration → Administrators & Roles
- Under the Roles tab, create a new role
- Navigate to Security Posture → Application
- In CASB, set CONFIG APP ACCESS permission to Manage
- RBACv2: Read + Write access for:
1.2 Netskope SSPM API Documentation
Important: For all Netskope SSPM API calls, refer to the interactive Swagger documentation to understand the exact authentication requirements, request formats, and response schemas.
Swagger Documentation URL:
https://<your-tenant>.goskope.com/apidocs/For example: https://mycompany.goskope.com/apidocs/
Navigate to the SPM section and look for endpoints containing "customapps" to find the BYOA-related APIs.
1.3 Register Your Custom Application
Use the API to register OneLogin as a custom application in SSPM.
API Endpoint (search for this in Swagger):
POST /api/v2/spm/customappsApp Name Requirements:
- Must have "EXT" prefix
- Only alphabets and numbers allowed
- No spaces allowed
- Maximum 25 characters
- Example: EXTOneLogin
Logo Requirements (optional):
- Size: less than 120×120 pixels
- Format: SVG
- If not provided, a default Netskope icon will be used
Request Format: multipart/form-data
Form Fields:
| Parameter | Type | Required | Description |
| name | string | Yes | Custom app name (must start with "EXT") |
| logo | binary | No | App logo file (SVG, max 120x120 pixels) |
| description | string | No | Description of the custom app |
Note: Use the Swagger UI at https://<your-tenant>.goskope.com/apidocs/ to:
- View the exact authentication requirements
- Test the API directly in your browser
- See the complete request/response schemas
1.4 Onboard an Instance (via UI)
After registering the custom app, create an instance through the Netskope UI:
- Log in to your Netskope tenant
- Navigate to Configure App Access → Next Gen → Security Posture → Custom Apps
- Find your registered app (EXTOneLogin) in the list
- Click to set up the instance
- Provide the following details:
- Instance Name: e.g., onelogin-prod
- Administrator Email: e.g., admin@company.com
- Click Save to create the instance
Step 2: Create API Credentials in OneLogin
To fetch data from OneLogin, you need to create API credentials with appropriate permissions.
2.1 Navigate to API Access
- Log in to your OneLogin Admin Portal
- Go to Developers → API Access
2.2 Create New Credential
- Click the "New Credential" button (blue button, top right)
- Configure the credential:
- Name: Enter a descriptive name, e.g., sspm-byoa-api or netskope-integration
- Permissions: Select "Read All" to allow fetching users, roles, groups, and apps
2.3 Save and Copy Credentials
After creation, you will see your credential listed with:
- Name: The name you provided
- Permission scope: Read All
- Creator: Your username
Click on the credential to view and copy:
- Client ID: A unique identifier for your API credential
- Client Secret: A secret key (keep this secure!)
Important: Store these credentials securely. You will need them to generate access tokens for API calls.
Step 3: Generate OneLogin Access Token
Use the Client ID and Client Secret from Step 2 to generate an OAuth 2.0 access token.
3.1 API Endpoint
POST https://<subdomain>.onelogin.com/auth/oauth2/v2/tokenReplace <subdomain> with your OneLogin subdomain (e.g., mycompany).
3.2 Option 1: Using application/json
curl 'https://<subdomain>.onelogin.com/auth/oauth2/v2/token' \
-X POST \
-H "Authorization: client_id:<client_id>, client_secret:<client_secret>" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials"
}'3.3 Option 2: Using application/x-www-form-urlencoded
curl 'https://<subdomain>.onelogin.com/auth/oauth2/v2/token' \
-X POST \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id=<client_id>' \
--data-urlencode 'client_secret=<client_secret>'3.4 Sample Response
{
"access_token": "xx508xx63817x752xx74004x30705xx92x58349x5x78f5xx34xxxxx51",
"created_at": "2025-12-22T03:36:18.714Z",
"expires_in": 36000,
"refresh_token": "628x9x0xx447xx4x421x517x4x474x33x2065x4x1xx523xxxxx6x7x20",
"token_type": "bearer",
"account_id": 555555
}3.5 Response Elements
| Field | Description |
| access_token | The token to use for API calls |
| created_at | Timestamp when the token was generated |
| expires_in | Token validity in seconds (36,000 = 10 hours) |
| refresh_token | Token for refreshing access (deprecated) |
| token_type | Token type (bearer) |
| account_id | OneLogin account ID |
Note: The access token is valid for 10 hours (36,000 seconds). Store the access_token for use in Step 4.
Step 4: Fetch Data from OneLogin APIs
Use the access token from Step 3 to fetch users, roles, groups, and apps from OneLogin.
4.1 List Users
API Endpoint:
GET https://<subdomain>.onelogin.com/api/2/userscURL Request:
curl 'https://<subdomain>.onelogin.com/api/2/users' \
-X GET \
-H "Authorization: bearer <access_token>"Query Parameters (optional):
| Parameter | Description |
| created_since | ISO8601 timestamp - returns users created after this date |
| created_until | ISO8601 timestamp - returns users created before this date |
| updated_since | ISO8601 timestamp - returns users updated after this date |
| updated_until | ISO8601 timestamp - returns users updated before this date |
| last_login_since | ISO8601 timestamp - returns users who logged in after this date |
| last_login_until | ISO8601 timestamp - returns users who logged in before this date |
| firstname | Filter by first name |
| lastname | Filter by last name |
| | Filter by email address |
| username | Filter by username |
Sample Response:
[
{
"activated_at": null,
"distinguished_name": null,
"external_id": null,
"firstname": "Mike",
"last_login": null,
"lastname": "Tester",
"directory_id": null,
"invitation_sent_at": null,
"member_of": null,
"updated_at": "2019-08-22T18:43:55.188Z",
"created_at": "2019-08-22T18:43:55.188Z",
"id": 56781966,
"invalid_login_attempts": 0,
"locked_until": null,
"username": null,
"email": "mike.tester@onelogin.com",
"phone": null,
"state": 1,
"group_id": null,
"password_changed_at": "2019-08-22T18:43:55.172Z",
"status": 1,
"samaccountname": null
}
]User Response Elements:
| Field | Description |
| id | User's unique ID in OneLogin |
| | User's email address |
| firstname | User's first name |
| lastname | User's last name |
| username | User's username |
| status | User status (1 = Active, other values = Inactive) |
| state | User state |
| group_id | ID of the group the user belongs to |
| last_login | Timestamp of last login |
| created_at | Timestamp when user was created |
| updated_at | Timestamp when user was last updated |
| invalid_login_attempts | Number of failed login attempts |
| locked_until | Timestamp until which user is locked |
4.2 List Roles
API Endpoint:
GET https://<subdomain>.onelogin.com/api/2/rolescURL Request:
curl 'https://<subdomain>.onelogin.com/api/2/roles' \
-X GET \
-H "Authorization: bearer <access_token>"Query Parameters (optional):
| Parameter | Description |
| name | Filter by role name |
| app_id | Returns roles containing this app ID |
| app_name | Returns roles containing this app name |
| fields | Comma-delimited list of fields to return (apps, users, admins) |
Sample Response:
{
"status": {
"error": false,
"code": 200,
"type": "success",
"message": "Success"
},
"pagination": {
"before_cursor": null,
"after_cursor": null,
"previous_link": null,
"next_link": null
},
"data": [
{
"id": 1111,
"name": "C-Executive"
},
{
"id": 1112,
"name": "Contractor"
},
{
"id": 1113,
"name": "Default"
},
{
"id": 1114,
"name": "Employee"
}
]
}Role Response Elements:
| Field | Description |
| id | Role's unique ID in OneLogin |
| name | Role name |
| apps | Array of app IDs associated with the role (if requested via fields parameter) |
| users | Array of user IDs assigned to the role (if requested via fields parameter) |
| admins | Array of admin user IDs for the role (if requested via fields parameter) |
4.3 List Groups (API v1)
API Endpoint:
GET https://<subdomain>.onelogin.com/api/1/groups
Note: The Groups API uses v1 and has a slightly different authorization header format (uses bearer: instead of bearer ).
cURL Request:
curl 'https://<subdomain>.onelogin.com/api/1/groups' \
-X GET \
-H "Authorization: bearer:<access_token>"Sample Response:
{
"status": {
"error": false,
"code": 200,
"type": "success",
"message": "Success"
},
"pagination": {
"before_cursor": null,
"after_cursor": null,
"previous_link": null,
"next_link": null
},
"data": [
{
"id": 417333,
"name": "employees",
"reference": null
},
{
"id": 419333,
"name": "contractors",
"reference": null
},
{
"id": 419888,
"name": "managers",
"reference": null
},
{
"id": 419999,
"name": "admins",
"reference": null
}
]
}Group Response Elements:
| Field | Description |
| id | Group's unique ID in OneLogin |
| name | Group name |
| reference | Deprecated field (always null) |
4.4 List Apps (Third-Party Applications)
API Endpoint:
GET https://<subdomain>.onelogin.com/api/2/apps
cURL Request:
curl 'https://<subdomain>.onelogin.com/api/2/apps' \
-X GET \
-H "Authorization: bearer <access_token>"Query Parameters (optional):
| Parameter | Description |
| name | App name or partial name (use * wildcard) |
| connector_id | Returns apps based on a specific connector |
| auth_method | Filter by auth method (0=Password, 1=OpenId, 2=SAML, 3=API, 4=Google, 6=Forms, 7=WSFED, 8=OIDC) |
Sample Response:
[
{
"id": 1061937,
"connector_id": 50534,
"auth_method": 2,
"auth_method_description": "SAML2.0",
"name": "Amazon Web Services (AWS) Multi Role",
"description": "",
"updated_at": "2020-01-14T21:21:06Z",
"created_at": "2020-01-14T21:21:06Z",
"visible": true
}
]App Response Elements:
| Field | Description |
| id | App's unique ID in OneLogin |
| connector_id | ID of the app's underlying connector |
| name | App name |
| description | App description |
| auth_method | Authentication method ID |
| auth_method_description | Human-readable auth method description |
| visible | Whether app is visible in OneLogin portal |
| created_at | Timestamp when app was created |
| updated_at | Timestamp when app was last updated |
Step 5: Transform & Push Data to Netskope SSPM
Transform the OneLogin API responses to match the Netskope SSPM schema, then push to the ingestor endpoints.
5.1 Netskope SSPM API Documentation
Important: For all Netskope SSPM API calls in this section, refer to the interactive Swagger documentation to understand the exact authentication requirements and request formats.
Swagger Documentation URL:
https://<your-tenant>.goskope.com/apidocs/
How to find the APIs in Swagger:
- Open the Swagger UI URL above
- Use Ctrl+F (or Cmd+F on Mac) to search for "customapps" or "ingestor"
- Look for the following endpoint paths:
| API Purpose | Endpoint to Search |
| Register Custom App | POST /api/v2/spm/customapps |
| Push Users | POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/users |
| Push Roles | POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/roles |
| Push Groups | POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/groups |
| Push Third-Party Apps | POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/thirdpartyapps |
Use the Swagger UI to:
- View the exact authentication requirements
- Test APIs directly in your browser
- See complete request/response schemas
5.2 Push Users
API Endpoint:
POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/users
SSPM User Schema:
{
"users": [
{
"email_id": "string (required)",
"name": "string",
"user_type": "string (internal/external)",
"user_status": "string (enabled/disabled)",
"administrator": "boolean",
"last_login_time": "integer (unix timestamp)",
"group_ids": ["array of strings"],
"role_ids": ["array of strings"],
"modified_time": "integer (unix timestamp)",
"created_time": "integer (unix timestamp)",
"additional_metadata": "object"
}
]
}Field Mapping (OneLogin → SSPM):
| OneLogin Field | SSPM Field | Transformation |
| | email_id | Direct mapping |
| firstname + lastname | name | Concatenate with space |
| status | user_status | 1 → "enabled", else "disabled" |
| - | user_type | Set to "internal" or "external" based on email domain |
| - | administrator | Default to false |
| last_login | last_login_time | Convert ISO8601 to Unix timestamp |
| group_id | group_ids | Wrap in array if not null |
| - | role_ids | Map from user-role associations |
| updated_at | modified_time | Convert ISO8601 to Unix timestamp |
| created_at | created_time | Convert ISO8601 to Unix timestamp |
Sample Transformed Payload:
{
"users": [
{
"email_id": "mike.tester@onelogin.com",
"name": "Mike Tester",
"user_type": "internal",
"user_status": "enabled",
"administrator": false,
"last_login_time": null,
"group_ids": [],
"role_ids": [],
"modified_time": 1566498235,
"created_time": 1566498235
}
]
}
5.3 Push Roles
API Endpoint:
POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/roles
SSPM Role Schema:
{
"roles": [
{
"id": "string (required)",
"name": "string (required)",
"description": "string",
"permissions": ["array of strings"],
"created_time": "integer (unix timestamp)",
"modified_time": "integer (unix timestamp)"
}
]
}
Field Mapping (OneLogin → SSPM):
| OneLogin Field | SSPM Field | Transformation |
| id | id | Convert to string |
| name | name | Direct mapping |
| - | description | Use role name as description |
| - | permissions | Use [name] as placeholder array |
| - | created_time | Not available in OneLogin response |
| - | modified_time | Not available in OneLogin response |
Sample Transformed Payload:
{
"roles": [
{
"id": "1111",
"name": "C-Executive",
"description": "C-Executive role",
"permissions": ["C-Executive"]
},
{
"id": "1112",
"name": "Contractor",
"description": "Contractor role",
"permissions": ["Contractor"]
},
{
"id": "1113",
"name": "Default",
"description": "Default role",
"permissions": ["Default"]
},
{
"id": "1114",
"name": "Employee",
"description": "Employee role",
"permissions": ["Employee"]
}
]
}5.4 Push Groups
API Endpoint:
POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/groups
SSPM Group Schema:
{
"groups": [
{
"id": "string (required)",
"name": "string (required)",
"description": "string",
"role_ids": ["array of strings"],
"created_time": "integer (unix timestamp)",
"modified_time": "integer (unix timestamp)"
}
]
}Field Mapping (OneLogin → SSPM):
| OneLogin Field | SSPM Field | Transformation |
| id | id | Convert to string |
| name | name | Direct mapping |
| - | description | Use group name as description |
| - | role_ids | Empty array or link to associated roles |
| - | created_time | Not available in OneLogin response |
| - | modified_time | Not available in OneLogin response |
Sample Transformed Payload:
{
"groups": [
{
"id": "417333",
"name": "employees",
"description": "employees group",
"role_ids": []
},
{
"id": "419333",
"name": "contractors",
"description": "contractors group",
"role_ids": []
},
{
"id": "419888",
"name": "managers",
"description": "managers group",
"role_ids": []
},
{
"id": "419999",
"name": "admins",
"description": "admins group",
"role_ids": []
}
]
}
5.5 Push Third-Party Apps
API Endpoint:
POST /api/v2/spm/ingestor/customapps/{appname}/instances/{instancename}/thirdpartyapps
SSPM Third-Party App Schema:
{
"third_party_apps": [
{
"application_id": "string (required)",
"name": "string (required)",
"description": "string",
"risk_score": "integer (0-100)",
"created_time": "integer (unix timestamp)",
"modified_time": "integer (unix timestamp)"
}
]
}Field Mapping (OneLogin → SSPM):
| OneLogin Field | SSPM Field | Transformation |
| id | application_id | Convert to string |
| name | name | Direct mapping |
| description | description | Direct mapping |
| - | risk_score | Default to 0 (Low risk) or calculate based on auth_method |
| updated_at | modified_time | Convert ISO8601 to Unix timestamp |
| created_at | created_time | Convert ISO8601 to Unix timestamp |
Sample Transformed Payload:
{
"third_party_apps": [
{
"application_id": "1061937",
"name": "Amazon Web Services (AWS) Multi Role",
"description": "",
"risk_score": 0,
"modified_time": 1579037466,
"created_time": 1579037466
}
]
}
5.6 Timestamp Conversion
To convert ISO8601 timestamps (from OneLogin) to Unix timestamps (for SSPM):
ISO8601 Format: 2019-08-22T18:43:55.188Z Unix Timestamp: 1566498235
You can use online converters or your programming language's built-in date/time functions to perform this conversion.
Step 6: Verify Integration & Next Steps
6.1 Verify Data in Netskope SSPM
After pushing data, verify the integration in the Netskope UI:
- Log in to your Netskope tenant
- Navigate to Security Posture → Inventory
- Select your custom app (EXTOneLogin) from the application dropdown
- Verify that users, roles, groups, and apps are visible
6.2 Create Custom Rules
Create custom security rules using Netskope Governance Language (NGL) to monitor your OneLogin instance.
Example Rules:
- Check for disabled users:
EXTOneLogin User should-have user_status = "enabled"
- Check for users without recent login:
EXTOneLogin User should-have last_login_time > (now - 90 days)
- Check for high-risk third-party apps:
EXTOneLogin ThirdPartyApp should-have risk_score < 50
6.3 Create Policies
- Navigate to Security Posture → Policies
- Create a new policy
- Add your custom rules to the policy
- Enable the policy for monitoring
6.4 Benefits After Integration
After completing the integration, you can take advantage of all SSPM features:
- Single Pane of View: Monitor OneLogin alongside all other SaaS applications
- Posture Score: Track your OneLogin security posture over time
- Advanced Analytics Reports: Generate detailed reports on user activity, role assignments, and app usage
- Alerting: Set up alerts for security policy violations
- Monitoring: Continuous monitoring of your OneLogin configuration
- Compliance: Map security findings to compliance frameworks
6.5 Scheduling Regular Data Syncs
For continuous monitoring, you should schedule regular data syncs to keep your SSPM data up-to-date. Use your preferred automation tool:
- Cron Jobs (Linux/macOS)
- Task Scheduler (Windows)
- Cloud Functions (AWS Lambda, Azure Functions, Google Cloud Functions)
Rate Limits
OneLogin API Rate Limits
- Check rate limits using: GET /api/2/oauth20-tokens/rate_limit
- Rate limit headers are included in API responses
Troubleshooting
Common Issues
- 401 Unauthorized (OneLogin)
- Verify your Client ID and Client Secret
- Ensure the access token has not expired (valid for 10 hours)
- Check that the API credential has "Read All" permissions
- 401 Unauthorized (Netskope)
- Verify your authentication credentials
- Ensure appropriate SSPM permissions are configured
- Check the Swagger documentation at https://<your-tenant>.goskope.com/apidocs/ for correct authentication method
- 404 Not Found (Netskope)
- Verify the custom app name matches exactly (e.g., EXTOneLogin)
- Verify the instance name is correct
- Ensure the custom app and instance are created
- 422 Unprocessable Entity
- Check the request payload matches the expected schema
- Ensure required fields are present (e.g., email_id for users)
References
- Netskope BYOA Documentation
- OneLogin API Documentation
- OneLogin Generate Tokens API
- OneLogin List Users API
- OneLogin List Roles API
- OneLogin List Groups API
- OneLogin List Apps API
- Create Custom Rules using NGL
- SSPM Policies




