Skip to main content

okta

Authentication and authorization services.

Provider Summary

total services: 55
total resources: 245

See also:
[SHOW] [DESCRIBE] [REGISTRY]


Installation

To pull the latest version of the okta provider, run the following command:

REGISTRY PULL okta;

To view previous provider versions or to pull a specific provider version, see here.

Authentication

The following system environment variables are used for authentication by default:

These variables are sourced at runtime (from the local machine or as CI variables/secrets).

Using different environment variables

To use different environment variables (instead of the defaults), use the --auth flag of the stackql program. For example:


AUTH='{ "okta": { "type": "api_key", "valuePrefix": "SSWS ", "credentialsenvvar": "YOUR_OKTA_API_TOKEN_VAR" }}'
stackql shell --auth="${AUTH}"

or using PowerShell:


$Auth = "{ 'okta': { 'type': 'api_key', 'valuePrefix': 'SSWS ', 'credentialsenvvar': 'YOUR_OKTA_API_TOKEN_VAR' }}"
stackql.exe shell --auth=$Auth

Server Parameters

The following parameter is required for the okta provider:

  • subdomain - The Okta tenant domain, for example my-company would be supplied if your Okta domain is my-company.okta.com

This parameter must be supplied to the WHERE clause of each SELECT statement.

Example Queries

Try the following queries using stackql shell, or run them from a script or CI pipeline with stackql exec.

Users with status and last sign-in

Every user with login, department, lifecycle status, last sign-in and the provider that validates the password:

SELECT id,
json_extract(profile, '$.login') AS login,
json_extract(profile, '$.department') AS department,
status, lastLogin, passwordChanged,
json_extract(credentials, '$.provider.type') AS auth_provider
FROM okta.users.users
WHERE subdomain = '{{ subdomain }}'
ORDER BY lastLogin;

Groups and their members

Groups with member counts (expand = 'stats' populates _embedded.stats.usersCount), then the members of one group:

SELECT id,
json_extract(profile, '$.name') AS name,
type,
json_extract(_embedded, '$.stats.usersCount') AS member_count,
lastMembershipUpdated
FROM okta.groups.groups
WHERE subdomain = '{{ subdomain }}'
AND expand = 'stats'
ORDER BY member_count DESC;

SELECT id,
json_extract(profile, '$.login') AS login,
status, lastLogin
FROM okta.groups.users
WHERE groupId = '{{ groupId }}'
AND subdomain = '{{ subdomain }}';

Applications with status and sign-on mode

Every app instance with its sign-on mode and lifecycle status:

SELECT id, label, signOnMode, status, created, lastUpdated
FROM okta.apps.applications
WHERE subdomain = '{{ subdomain }}'
ORDER BY signOnMode, label;

Groups assigned to an application

The group assignments of one application, with the group name looked up from the groups resource:

SELECT g.id,
json_extract(g.profile, '$.name') AS group_name,
g.type,
ga.priority, ga.lastUpdated
FROM okta.apps.group_assignments ga
JOIN okta.groups.groups g
ON g.id = ga.id
WHERE ga.appId = '{{ appId }}'
AND ga.subdomain = '{{ subdomain }}'
AND g.subdomain = '{{ subdomain }}'
ORDER BY ga.priority;

Sign-on policies and their rules

Sign-on policies in priority order (type is a required parameter of the policies resource), then the rules of one policy:

SELECT id, name, status, priority, system, lastUpdated
FROM okta.policies.policies
WHERE type = 'OKTA_SIGN_ON'
AND subdomain = '{{ subdomain }}'
ORDER BY priority;

SELECT id, name, status, priority, system, type
FROM okta.policies.policy_rules
WHERE policyId = '{{ policyId }}'
AND subdomain = '{{ subdomain }}'
ORDER BY priority;

Failed sign-ins from the system log

Failed sign-in attempts since a given time, with the filter expression evaluated by Okta rather than after the fact:

SELECT published, eventType, displayMessage,
json_extract(actor, '$.alternateId') AS actor_login,
json_extract(client, '$.ipAddress') AS ip_address,
json_extract(client, '$.geographicalContext.country') AS country,
json_extract(outcome, '$.reason') AS reason
FROM okta.logs.system_log_events
WHERE subdomain = '{{ subdomain }}'
AND since = '2026-09-10T00:00:00.000Z'
AND filter = 'eventType eq "user.session.start" and outcome.result eq "FAILURE"'
ORDER BY published DESC;

API tokens by expiry

Active API tokens with the owning user, client and expiry:

SELECT id, name, clientName, userId, created, lastUpdated, expiresAt, tokenWindow
FROM okta.api_tokens.api_tokens
WHERE subdomain = '{{ subdomain }}'
ORDER BY expiresAt;

Users by status

Number of users in each lifecycle status (the default listing omits users with the DEPROVISIONED status):

SELECT status, COUNT(*) AS user_count
FROM okta.users.users
WHERE subdomain = '{{ subdomain }}'
GROUP BY status
ORDER BY user_count DESC;

Group provisioning

Create a group, replace its profile (the groups resource exposes replace rather than update), then delete it:

INSERT INTO okta.groups.groups (data__profile, subdomain)
SELECT '{"name": "finance-readers", "description": "Read-only access to finance apps"}',
'{{ subdomain }}';

REPLACE okta.groups.groups
SET data__profile = '{"name": "finance-readers", "description": "Read-only access to finance and billing apps"}'
WHERE groupId = '{{ groupId }}'
AND subdomain = '{{ subdomain }}';

DELETE FROM okta.groups.groups
WHERE groupId = '{{ groupId }}'
AND subdomain = '{{ subdomain }}';

Lifecycle operations

Lifecycle methods are EXEC calls, for example suspending a user or deactivating an application:

EXEC okta.users.users.suspend_user
@id = '{{ userId }}',
@subdomain = '{{ subdomain }}';

EXEC okta.apps.applications.deactivate_application
@appId = '{{ appId }}',
@subdomain = '{{ subdomain }}';

Services