Okta
Port's Okta integration allows you to model Okta identity and access management resources in your software catalog and ingest data into them.
Core support
Prerequisites
Create an Okta API token
- Log in to your Okta admin console.
- Navigate to Security > API > Tokens.
- Click Create Token.
- Provide a name for your token (e.g., "Port Integration").
- Click Create Token.
- Copy the generated token and save it securely.
Store your API token securely and never share it. The token provides access to your Okta data.
Okta Domain
Your Okta domain is the subdomain of your Okta organization URL. For example, if your Okta URL is https://dev-123456.okta.com, your domain would be dev-123456.okta.com.
Setup
Choose one of the following installation methods: Not sure which method is right for your use case? Check the available installation methods.
Configuration
Port integrations use a YAML mapping block to ingest data from the third-party api into Port.
The mapping makes use of the JQ JSON processor to select, modify, concatenate, transform and perform other operations on existing fields and values from the integration API.
Default mapping configuration
This is the default mapping configuration for this integration:
Default mapping configuration (click to expand)
resources:
- kind: okta-user
selector:
query: 'true'
include_groups: true
include_applications: true
fields: "id,status,created,activated,lastLogin,lastUpdated,profile:(login,firstName,lastName,displayName,email,title,department,employeeNumber,mobilePhone,primaryPhone,streetAddress,city,state,zipCode,countryCode)"
port:
entity:
mappings:
identifier: .id
title: .profile.displayName // .profile.firstName + " " + .profile.lastName // .profile.login
blueprint: '"okta-user"'
properties:
login: .profile.login
email: .profile.email
firstName: .profile.firstName
lastName: .profile.lastName
displayName: .profile.displayName
title: .profile.title
department: .profile.department
employeeNumber: .profile.employeeNumber
mobilePhone: .profile.mobilePhone
primaryPhone: .profile.primaryPhone
streetAddress: .profile.streetAddress
city: .profile.city
state: .profile.state
zipCode: .profile.zipCode
countryCode: .profile.countryCode
status: .status
created: .created
activated: .activated
lastLogin: .lastLogin
lastUpdated: .lastUpdated
relations:
groups: .groups[]?.id
- kind: okta-group
selector:
query: 'true'
port:
entity:
mappings:
identifier: .id
title: .profile.name
blueprint: '"okta-group"'
properties:
name: .profile.name
description: .profile.description
type: .type
created: .created
lastUpdated: .lastUpdated
relations:
members: .users[]?.id
Monitoring and sync status
To learn more about how to monitor and check the sync status of your integration, see the relevant documentation.
Mapping & selectors per resource
To view and test the integration's mapping against examples of the third-party API responses, use the jq playground in your data sources page. Find the integration in the list of data sources and click on it to open the playground.
Additional examples of blueprints and the relevant integration configurations:
Set up live events
This integration supports live events, allowing real-time updates to your software catalog without waiting for the next scheduled sync.
Note that different events are supported depending on the resource type.
- Hosted by Port
- Self-hosted
Live events base URL
For integrations installed using the Hosted by Port method, you can obtain the live events base URL from the Get an integration API. The response includes liveEventsUuid and liveEventsIngestHostname in the appSpec section.
Call the endpoint with your integration's identifier:
curl -X GET \
'https://api.port.io/v1/integration/<INTEGRATION_IDENTIFIER>' \
-H 'Authorization: Bearer <PORT_ACCESS_TOKEN>'
The port_region, port.baseUrl, portBaseUrl, port_base_url and OCEAN__PORT__BASE_URL parameters select which Port API instance to use:
- EU (app.port.io) →
https://api.port.io - US (app.us.port.io) →
https://api.us.port.io
In the response, look for the following fields under spec.appSpec:
{
"spec": {
"appSpec": {
"liveEventsUuid": "abcdefghijk",
"liveEventsIngestHostname": "ingest.ocean.getport.io"
}
}
}
Combine them to build the live events base URL:
https://<liveEventsIngestHostname>/live-events/<liveEventsUuid>
For example, with the values above, the live events base URL is:
https://ingest.ocean.getport.io/live-events/abcdefghijk
This is the same URL configured for the integration.
BaseUrl & webhook configuration
To enable real-time updates of the data in your software catalog, you need to define the liveEvents.baseUrl parameter.
This parameter should be set to the URL of your Okta integration instance, which needs to have the option to setup webhooks via HTTP requests/receive HTTP requests, so ensure the network is configured accordingly.
- If Okta and the integration are in the same cluster/network: Use an internal URL (e.g., a Kubernetes service DNS name).
For Kubernetes deployments, create a service to expose the integration pod and use the service URL asliveEvents.baseUrl. If both the source system and integration are in the same cluster, an internal ClusterIP service is sufficient. - If Okta is external to the integration's network: The integration must be exposed via an ingress, load balancer, or public URL that Okta can reach.
If liveEvents.baseUrl is not provided, the integration will continue to function correctly. In such a configuration, to retrieve the latest information from the target system, the scheduledResyncInterval parameter has to be set, or a manual resync will need to be triggered through Port's UI.
To test webhooks or live event delivery to your local environment, expose your local pod or service to the internet using ngrok (e.g. ngrok http http://localhost:8000)
Webhook configuration
The Okta integration supports real-time updates through webhooks. When using the self-hosted installation method, the integration will automatically:
- Create an Event Hook in your Okta organization
- Configure the webhook to send user and group change events
- Process incoming webhook events to update Port entities in real-time
Webhook events
The integration listens for the following Okta events:
user.lifecycle.createuser.lifecycle.activateuser.lifecycle.deactivateuser.lifecycle.suspenduser.lifecycle.unsuspenduser.lifecycle.deleteuser.account.update_profilegroup.user_membership.addgroup.user_membership.removegroup.lifecycle.creategroup.lifecycle.deletegroup.lifecycle.update
Limitations
- The integration currently supports users and groups only
- Custom Okta attributes are not automatically mapped but can be added to the configuration
- Webhook verification is optional but recommended for production environments
Troubleshooting
Common Issues
- Authentication Errors: Verify your Okta API token has the correct permissions and is not expired
- Domain Issues: Ensure your Okta domain is correctly formatted (e.g.,
dev-123456.okta.com) - Webhook Failures: Check that your self-hosted integration is accessible from the internet for webhook delivery
- Rate Limiting: Okta has API rate limits; the integration handles this automatically with retries