epack install collector okta
Adds to epack.yaml, resolves dependencies, downloads binary.
Run all configured collectors and build a pack:
epack collect
Runs all collectors in epack.yaml and outputs an evidence pack.
Or add manually to epack.yaml:
collectors:
okta:
source: https://github.com/locktivity/epack-collector-okta
Then run epack install to lock and sync.
The Okta collector gathers security posture metrics from your Okta organization. All metrics are percentages (0-100) or policy settings, designed to be actionable and comparable across organizations.
{
"schema_version": "1.0.0",
"collected_at": "2026-02-25T19:46:39Z",
"org_domain": "company.okta.com",
"posture": {
"mfa_coverage": 85,
"mfa_phishing_resistant": 20,
"sso_coverage": 90
},
"users": {
"password_expired": 2,
"locked_out": 0,
"inactive": 15
},
"apps": {
"provisioning_enabled": 40,
"deprovisioning_enabled": 30
},
"policy": {
"policy_count": 2,
"mfa_required_all": false,
"mfa_required_any": true,
"session_lifetime_min_minutes": 15,
"session_lifetime_max_minutes": 1440,
"idle_timeout_min_minutes": 5,
"idle_timeout_max_minutes": 120
}
}
High-level security scores for quick assessment.
| Metric | Why It Matters |
|---|---|
mfa_coverage |
Account takeover protection. MFA significantly reduces credential-based attacks. Low coverage leaves accounts vulnerable to password spraying and phishing. |
mfa_phishing_resistant |
Strong authentication. WebAuthn/FIDO2 factors can't be phished, unlike SMS or TOTP. This is the gold standard for sensitive accounts. |
sso_coverage |
Credential sprawl reduction. Apps not using SSO require separate passwords, increasing password fatigue and reuse risk. |
User account health indicators.
| Metric | Why It Matters |
|---|---|
password_expired |
Compliance and access issues. Users with expired passwords may be locked out or using workarounds that bypass security controls. |
locked_out |
Potential attack indicator. Spikes in lockout rates may indicate brute force or credential stuffing attacks. |
inactive |
Orphan account risk. Inactive accounts (90+ days no login) are prime targets for attackers. They may belong to departed employees or unused service accounts. |
Application lifecycle management health.
| Metric | Why It Matters |
|---|---|
provisioning_enabled |
Onboarding automation. Manual provisioning delays access and increases admin burden. Automated provisioning ensures consistent access based on role. |
deprovisioning_enabled |
Offboarding security. Without automated deprovisioning, departing employees retain app access. This is a major source of data breaches. |
Aggregated security policy settings across all active sign-on policies.
| Metric | Why It Matters |
|---|---|
policy_count |
Policy complexity. Number of active sign-on policies. More policies mean more nuanced access control but also more complexity to audit. |
mfa_required_all |
Universal MFA enforcement. True only if every policy requires MFA. If false, some user groups may bypass MFA. |
mfa_required_any |
Partial MFA enforcement. True if at least one policy requires MFA. Useful to detect if MFA is configured at all. |
session_lifetime_min_minutes |
Strictest session policy. The shortest session lifetime across all policies. Indicates your most restrictive access control. |
session_lifetime_max_minutes |
Most permissive session. The longest session lifetime. Users under this policy have extended access windows. |
idle_timeout_min_minutes |
Strictest idle policy. The shortest idle timeout. Protects high-risk users from unattended sessions. |
idle_timeout_max_minutes |
Most permissive idle timeout. The longest idle timeout. Users under this policy stay logged in longer when inactive. |
OAuth 2.0 with private key JWT is the recommended authentication method. It provides:
- Scoped access (only the permissions you need)
- Short-lived tokens
- Better audit logging
~/.okta/epack-private-key.pem)abc123xyz...). You'll need this for your epack config.okta.users.readokta.apps.readokta.policies.readOAuth scopes alone aren't enough - the service app needs an admin role to access org-wide resources.
collectors:
okta:
source: locktivity/epack-collector-okta@^0.1
config:
org_domain: your-org.okta.com
client_id: 0oa1234567890abcdef # From app settings
key_id: abc123xyz # From public key settings
secrets:
- OKTA_PRIVATE_KEY # PEM-encoded private key
Set the environment variable (use the PEM file you downloaded):
export OKTA_PRIVATE_KEY="$(cat ~/.okta/epack-private-key.pem)"
API tokens are simpler to set up but less secure:
- Tokens don't expire automatically
- Tokens have full permissions of the user who created them
- Harder to audit
collectors:
okta:
source: locktivity/epack-collector-okta@^0.1
config:
org_domain: your-org.okta.com
secrets:
- OKTA_API_TOKEN
Set the environment variable:
export OKTA_API_TOKEN="00abcdef..."
| Option | Required | Description |
|---|---|---|
org_domain |
Yes | Your Okta organization domain (e.g., company.okta.com) |
client_id |
For OAuth | OAuth 2.0 client ID from your service app |
key_id |
For OAuth | Key ID from the public key settings in your Okta app |
| Variable | Description |
|---|---|
OKTA_PRIVATE_KEY |
PEM-encoded RSA private key for OAuth 2.0 |
OKTA_API_TOKEN |
SSWS API token (legacy authentication) |
Ensure either:
- client_id, key_id config and OKTA_PRIVATE_KEY env var are all set (for OAuth), OR
- OKTA_API_TOKEN env var is set (for API token auth)
For OAuth 2.0:
- Verify the client_id is correct
- Verify the key_id matches the Key ID shown in Okta (General → Client Credentials → Public Keys)
- Ensure the private key matches the public key configured in Okta (they're a matched pair)
- Make sure DPoP is disabled
- Check that all required scopes are granted
The collector handles rate limits automatically with exponential backoff. If you see persistent rate limit errors:
- Reduce collection frequency
- Contact Okta support to increase rate limits
Some metrics require specific permissions:
- Policy details require okta.policies.read scope
- If using API token, ensure the token creator has admin privileges
stream: myorg/okta-posture
collectors:
okta:
source: locktivity/epack-collector-okta@^0.1
config:
org_domain: company.okta.com
client_id: 0oa1234567890abcdef
key_id: abc123xyz
secrets:
- OKTA_PRIVATE_KEY
Then run:
export OKTA_PRIVATE_KEY="$(cat /path/to/private-key.pem)"
epack collect
See Configuration for OAuth 2.0 setup instructions.
stream: myorg/okta-posture
collectors:
okta:
source: locktivity/epack-collector-okta@^0.1
config:
org_domain: company.okta.com
secrets:
- OKTA_API_TOKEN
Then run:
export OKTA_API_TOKEN=00abcdef...
epack collect
{
"protocol_version": 1,
"data": {
"schema_version": "1.0.0",
"collected_at": "2026-02-25T14:00:00Z",
"org_domain": "company.okta.com",
"posture": {
"mfa_coverage": 85,
"mfa_phishing_resistant": 20,
"sso_coverage": 90
},
"users": {
"password_expired": 2,
"locked_out": 0,
"inactive": 15
},
"apps": {
"provisioning_enabled": 40,
"deprovisioning_enabled": 30
},
"policy": {
"policy_count": 2,
"mfa_required_all": false,
"mfa_required_any": true,
"session_lifetime_min_minutes": 15,
"session_lifetime_max_minutes": 1440,
"idle_timeout_min_minutes": 5,
"idle_timeout_max_minutes": 120
}
}
}
All coverage values are percentages (0-100). See Overview for detailed metric descriptions.
name: Collect Evidence
on:
schedule:
- cron: "0 0 * * 1" # Weekly on Monday
workflow_dispatch:
jobs:
collect:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install epack
run: |
curl -sSL https://github.com/locktivity/epack/releases/latest/download/epack-linux-amd64 -o epack
chmod +x epack
sudo mv epack /usr/local/bin/
- name: Collect evidence
run: epack collect --frozen
env:
OKTA_PRIVATE_KEY: ${{ secrets.OKTA_PRIVATE_KEY }}
- name: Upload pack
uses: actions/upload-artifact@v4
with:
name: evidence-pack
path: "*.pack"
Store the Okta private key as a repository secret named OKTA_PRIVATE_KEY.
To collect from multiple Okta orgs, define separate collectors:
stream: mycompany/identity-posture
collectors:
okta-prod:
source: locktivity/epack-collector-okta@^0.1
config:
org_domain: company.okta.com
client_id: 0oa1234567890abcdef
key_id: prodkey123
secrets:
- OKTA_PROD_PRIVATE_KEY
okta-preview:
source: locktivity/epack-collector-okta@^0.1
config:
org_domain: company.oktapreview.com
client_id: 0oa0987654321fedcba
key_id: previewkey456
secrets:
- OKTA_PREVIEW_PRIVATE_KEY
Then set both environment variables:
export OKTA_PROD_PRIVATE_KEY="$(cat prod-key.pem)"
export OKTA_PREVIEW_PRIVATE_KEY="$(cat preview-key.pem)"
epack collect
**Full Changelog**: https://github.com/locktivity/epack-collector-okta/compare/v0.1.5...v0.1.6
**Full Changelog**: https://github.com/locktivity/epack-collector-okta/compare/v0.1.4...v0.1.5
**Full Changelog**: https://github.com/locktivity/epack-collector-okta/compare/v0.1.2...v0.1.4
**Full Changelog**: https://github.com/locktivity/epack-collector-okta/compare/v0.1.0...v0.1.3
**Full Changelog**: https://github.com/locktivity/epack-collector-okta/compare/v0.1.0...v0.1.2
**Full Changelog**: https://github.com/locktivity/epack-collector-okta/commits/v0.1.1
**Full Changelog**: https://github.com/locktivity/epack-collector-okta/commits/v0.1.0