A Node.js application for interacting with Okta APIs with automatic configuration management.
- Node.js 18.x or higher
- An Okta account with API access
- Okta API token with appropriate permissions
npm installThe application uses OAuth 2.0 Client Credentials flow for secure, scoped API access.
- Login to Okta Admin Console
- Navigate to Applications → Applications
- Click Create App Integration
- Select API Services (for OAuth 2.0 client credentials)
- Click Next
- Enter application name (e.g., "CSV Agent")
- Click Save
- Note the Client ID and Client Secret (you'll need these)
After creating the OAuth application, grant it the necessary Okta API scopes:
- In the OAuth application settings, go to Okta API Scopes tab
- Click Grant for each of the following scopes:
Application Management:
okta.apps.manage- Create and manage applicationsokta.apps.read- Read application informationokta.schemas.manage- Create custom attributesokta.schemas.read- Read schema information
User & Mapping:
okta.users.read- Read user informationokta.profileMappings.manage- Create profile mappingsokta.profileMappings.read- Read profile mappings
Governance (Optional - for entitlement features):
okta.governance.entitlements.manage- Create entitlementsokta.governance.entitlements.read- Read entitlementsokta.governance.resources.manage- Manage governance resourcesokta.governance.resources.read- Read governance resources
On first run, the application will prompt for:
-
Okta Tenant URL: Your Okta domain
- Examples:
your-tenant.okta.comorhttps://your-tenant.okta.com - The app accepts domains with or without
https://protocol - Must end with
.okta.comor.oktapreview.com - Find this in your Okta admin console URL
- Examples:
-
OAuth Client ID: From the OAuth application you created
-
OAuth Client Secret: From the OAuth application you created
The configuration will be saved to config.json for future runs.
Alternatively, create a config.json file manually:
{
"oktaDomain": "your-tenant.okta.com",
"clientId": "0oaxxxxxxxxxxxxx",
"clientSecret": "your-client-secret",
"selectedCsvFile": "My Application.csv"
}Note: All configuration (Okta credentials and CSV file selection) is stored in the same config.json file.
npm startOn first run, you'll be prompted to enter your Okta credentials:
Configuration file not found. Please provide the following information:
Okta Tenant URL (e.g., your-tenant.okta.com): your-tenant.okta.com
Okta API Token: 00abc...xyz
Configuration saved to ./config.json
For development with auto-reload on file changes:
npm run devThe application automates SAML 2.0 application creation and custom attribute management in Okta:
- CSV File Discovery: Scans the current directory for
.csvfiles - File Selection: If multiple CSV files exist, prompts you to select one (saves selection for future runs)
- App Name Extraction: Uses the CSV filename (without extension) as the app name/label
- Existence Check: Queries Okta to see if an app with that name already exists
- App Creation: If the app doesn't exist, creates a new SAML 2.0 application
- Custom Attributes: Creates custom attributes based on CSV column headers
- Reads column names from the CSV file
- Filters out columns starting with
ent_(enterprise columns) - Creates custom app user attributes for each remaining column
- Checks existing attributes to avoid duplicates
- Profile Mapping: Automatically maps custom attributes to Okta user profile fields
- Matches attribute names to Okta native fields (firstName, lastName, email, etc.)
- Creates bidirectional mappings between app and Okta user profile
- Supports variations (e.g., first_name, fname → firstName)
- Handles unmatched attributes gracefully
- Entitlement Catalog: Generates entitlement catalog from CSV columns with
ent_prefix- Parses all columns starting with
ent_(e.g., ent_UserRole, ent_Permissions, ent_CostCenter) - Extracts unique values from each entitlement column
- Handles comma-separated values within cells (e.g., "Role1,Role2")
- Checks Okta Governance API for existing entitlements
- Provides guidance for importing entitlements into Okta Identity Governance
- Parses all columns starting with
- Confirmation: Displays the app ID, status, custom attributes, mappings, and entitlements created
Place a CSV file in the current directory:
touch "My Application.csv"Run the application:
npm startExample output:
======================================================================
CSV Agent - Okta SAML Application Automation
======================================================================
📋 STEP 1: Loading Configuration
→ Checking for existing configuration file (config.json)...
✓ Configuration loaded successfully
✓ Connected to Okta tenant: your-tenant.okta.com
📂 STEP 2: CSV File Discovery
→ Scanning current directory for .csv files...
✓ Found 1 CSV file: My Application.csv
→ Automatically selected for processing
🔧 STEP 3: Application Processing
→ CSV File: My Application.csv
→ Application Name: "My Application"
→ Querying Okta API to check if application exists...
→ API Call: GET /api/v1/apps?q=My%20Application
ℹ Application does not exist in Okta
→ Preparing SAML 2.0 application definition...
→ API Call: POST /api/v1/apps
✓ Application created successfully!
📊 New Application Details:
• App ID: 0oa1b2c3d4e5f6g7h8i9
• Name: My Application
• Status: ACTIVE
• Sign-On Mode: SAML_2_0
💡 NOTE: SAML settings use placeholder values.
Update SSO URLs and audience in Okta Admin Console.
🏷️ STEP 4: Custom Attribute Management
→ Reading CSV column headers...
→ Filtering out enterprise columns (starting with "ent_")...
✓ CSV parsed successfully
→ Total columns found: 6
→ Excluded columns (ent_*): 1
• ent_InternalID (skipped)
→ Columns to process: 5
• Username
• firstName
• lastName
• email
• department
→ Fetching current app user schema from Okta...
→ API Call: GET /api/v1/meta/schemas/apps/0oa1b2c3d4e5f6g7h8i9/default
✓ Schema retrieved successfully
→ Existing custom attributes: 0
→ Creating 5 new custom attribute(s)...
→ Creating attribute: "Username"
API Call: POST /api/v1/meta/schemas/apps/0oa1b2c3d4e5f6g7h8i9/default
✓ Successfully created
→ Creating attribute: "firstName"
API Call: POST /api/v1/meta/schemas/apps/0oa1b2c3d4e5f6g7h8i9/default
✓ Successfully created
[...]
📊 Custom Attribute Summary:
• Total columns in CSV: 6
• Excluded (ent_*): 1
• Already existed: 0
• Successfully created: 5
======================================================================
✅ Processing Complete!
======================================================================
📍 Next Steps:
1. Login to Okta Admin Console
2. Navigate to Applications → My Application
3. Configure SAML settings (SSO URLs, Audience, etc.)
4. Review custom attributes under Provisioning → To App
If you have multiple CSV files, the app will prompt you to select one:
Connected to Okta successfully!
Looking for CSV files in current directory...
Found 3 CSV file(s):
- App One.csv
- App Two.csv
- App Three.csv
Multiple CSV files found. Please select which one to process:
1. App One.csv
2. App Two.csv
3. App Three.csv
Enter the number (1-3): 2
Selection saved to configuration.
--- Processing: App Two.csv ---
App Name/Label: App Two
Checking if app already exists...
App does not exist. Creating SAML 2.0 application...
✓ App created successfully!
App ID: 0oa1b2c3d4e5f6g7h8i9
Name: App Two
Status: ACTIVE
Sign-On Mode: SAML_2_0
--- Processing Complete ---
On subsequent runs, it will use your saved selection:
Found 3 CSV file(s):
- App One.csv
- App Two.csv
- App Three.csv
Using previously selected file: App Two.csv
(To change selection, delete config.json and run again)
├── index.js # Main application entry point
├── config.js # Configuration management (load/save/prompt)
├── config.json # Credentials storage (gitignored)
├── package.json # Node.js dependencies and scripts
└── README.md # This file
The application looks for .csv files in the current working directory. Make sure:
- You have at least one
.csvfile in the directory where you run the command - The file has the
.csvextension (case-sensitive on some systems)
If you want to process a different CSV file:
- Delete
config.json:rm config.json - Run the app again:
npm start - You'll be prompted to reconfigure (Okta credentials + CSV selection)
If you see this error, ensure your Okta domain:
- Ends with
.okta.comor.oktapreview.com - Examples of valid domains:
- ✓
your-tenant.okta.com - ✓
https://your-tenant.okta.com(will be normalized) - ✓
dev-12345.oktapreview.com - ✗
example.com(invalid - not an Okta domain) - ✗
okta.io(invalid - wrong TLD)
- ✓
The app will keep prompting until you provide a valid Okta domain.
The config.json file may not have write permissions. Check that the application directory is writable.
- Verify your API token is valid and not expired
- Check that the API token has appropriate permissions (needs app management permissions)
- Ensure your Okta domain is correct (without
https://)
- Ensure your API token has permissions to create applications
- Check that the app name doesn't conflict with Okta's naming rules
- Verify your Okta tenant has available app slots (check license limits)
Run npm install to ensure all dependencies are installed.
The application automatically creates custom app user attributes based on CSV column headers:
- Included Columns: All CSV columns become custom attributes by default
- Excluded Columns: Columns starting with
ent_are automatically ignored- Example:
ent_CostCenter,ent_UserRole,ent_Permissionswill be skipped
- Example:
- Duplicate Detection: The app checks existing attributes and only creates new ones
Username,firstName,lastName,email,department,ent_CostCenter,ent_Permissions
john.doe,John,Doe,john@example.com,Engineering,CC100,AdminFrom this CSV:
- ✓ Creates attributes:
Username,firstName,lastName,email,department - ✗ Skips:
ent_CostCenter,ent_Permissions
After the app runs, you can view the created custom attributes in Okta:
- Go to Applications → Select your app
- Navigate to Provisioning → To App
- View the custom attributes in the attribute mappings
The application automatically creates profile mappings between custom app attributes and Okta user profile fields.
- Intelligent Matching: The app analyzes each custom attribute name and attempts to match it to Okta's native user profile attributes
- Case-Insensitive: Matching is case-insensitive and removes special characters
- Variation Support: Recognizes common variations (e.g.,
first_name,fname,givenNameall map tofirstName) - Automatic Mapping: Creates bidirectional mappings in Okta's profile mapping configuration
The app recognizes and maps to these Okta Universal Directory attributes:
Core Attributes:
login,username→user.loginemail→user.email
Name Attributes:
firstName,first_name,fname,givenName→user.firstNamelastName,last_name,lname,surname→user.lastNamemiddleName,middle_name→user.middleNamedisplayName,display_name→user.displayName
Contact Attributes:
phone,primaryPhone,phoneNumber→user.primaryPhonemobile,mobilePhone,cellPhone→user.mobilePhone
Address Attributes:
street,address,streetAddress→user.streetAddresscity→user.citystate,province→user.statezipCode,zip,postalCode→user.zipCodecountry,countryCode→user.countryCode
Organization Attributes:
department,dept→user.departmenttitle,jobTitle→user.titleemployeeNumber,employeeId,employee_number→user.employeeNumberorganization,company→user.organizationdivision→user.divisioncostCenter,cost_center→user.costCentermanager,managerId→user.manager
🔗 STEP 5: Profile Attribute Mapping
→ Analyzing custom attributes for Okta user profile mappings...
→ Matched attributes: 6
• Username → user.login
• firstName → user.firstName
• lastName → user.lastName
• email → user.email
• employeeId → user.employeeNumber
• department → user.department
→ Unmatched attributes (no standard Okta field): 1
• startDate (will remain as custom attribute only)
→ Fetching profile mapping configuration...
→ API Call: GET /api/v1/mappings?sourceId=0oatwx8zgtwuFRc0Y417
✓ Profile mapping found (ID: prmtwx8zh41aQQfJO417)
→ Creating attribute mappings...
[...]
✓ Profile mappings updated successfully
📊 Mapping Summary:
• Total attributes analyzed: 7
• Matched to Okta fields: 6
• Mappings created: 6
• Mappings already existed: 0
• Unmatched attributes: 1
To view the created mappings in Okta:
- Go to Applications → Select your app
- Navigate to Provisioning → To Okta
- View the attribute mappings from app to Okta Universal Directory
The application automatically generates an entitlement catalog from CSV columns prefixed with ent_. This feature is inspired by role mining techniques and helps identify fine-grained authorizations in IAM systems.
Entitlements represent fine-grained user authorizations that determine what actions users can perform and what resources they can access. In this tool, entitlements are represented as CSV columns with the ent_ prefix.
- Column Detection: Identifies all CSV columns starting with
ent_ - Value Extraction: Reads all values from entitlement columns across all records
- Comma-Separated Handling: Splits values like "Role1,Role2" into individual entitlements
- Deduplication: Creates a unique set of values for each entitlement type
- Governance Check: Queries Okta Identity Governance API for existing entitlements
- Status Report: Shows which entitlements exist in Okta vs. new ones from CSV
Username,firstName,lastName,ent_CostCenter,ent_UserRole,ent_Permissions
user1@example.com,John,Doe,CC100,"Manager,Analyst","View,Approve"
user2@example.com,Jane,Smith,CC200,Consultant,"View,Verify,Submit"From this CSV:
- ent_CostCenter: Organizational units (CC100, CC200, CC300, etc.)
- ent_UserRole: Job functions (Manager, Analyst, Consultant, etc.)
- ent_Permissions: Access rights (View, Approve, Submit, Verify, etc.)
📦 STEP 5: Entitlement Catalog Creation
→ Parsing CSV file for entitlement columns (ent_*)...
✓ Found 3 entitlement column(s):
• ent_CostCenter: 7 unique value(s)
• ent_UserRole: 7 unique value(s)
• ent_Permissions: 6 unique value(s)
→ Total unique entitlements to create: 20
→ Checking Okta Governance API availability...
✓ Governance API available (read-only)
→ Current entitlements in system: 1489
📋 Entitlement Catalog from CSV:
→ CostCenter (7 values):
• CC100 (✓ exists in Okta)
• CC200 (new)
• CC300 (✓ exists in Okta)
[...]
📊 Entitlement Catalog Summary:
• Total unique entitlements identified: 20
• Entitlement types: 3
- Read-Only API: Okta Identity Governance entitlements are typically imported/synced from connected applications, not created manually via API
- Licensing Required: This feature requires Okta Identity Governance (OIG) license
- Manual Import: If the governance API is unavailable, the app displays the catalog with instructions for manual import
Important: Before the application can automatically create entitlements, you must first enable the app in Okta Identity Governance:
- Login to Okta Admin Console
- Navigate to Identity Governance → Resources
- Click Add application
- Search for and select your application ("claude disconnected app" in the example)
- Click Add to register the app as a governance resource
- Once added, the app will appear in the Resources list
- Enable Entitlement Management for the application
Once entitlement management is enabled manually, subsequent runs of the CSV Agent will:
- Detect the app is registered in governance
- Automatically create entitlements from the CSV catalog
- Check for duplicates and only create new entitlements
- Display creation status for each entitlement
After enabling entitlement management manually (see above), the CSV Agent will automatically:
- Parse CSV columns with
ent_prefix - Extract unique entitlement values
- Fetch the governance resource ID
- Check existing entitlements to avoid duplicates
- Create new entitlements via the Governance API
- Display success/failure status for each entitlement
Example console output after setup:
📦 STEP 7: Entitlement Catalog & Creation
✓ Governance resource found: res8x9y0zABC123XYZ456
✓ Found 5 existing entitlements
→ Creating entitlements from CSV catalog...
→ Processing CostCenter entitlements:
✓ CC100 (created)
✓ CC200 (created)
• CC300 (already exists)
📊 Entitlement Creation Summary:
• Total unique entitlements: 20
• Successfully created: 15
• Already existed: 5
- IAM Entitlement Analysis: Discover what fine-grained permissions exist in your CSV data
- Role Mining: Use the catalog as input for role mining and RBAC design
- Governance Setup: Understand what entitlements need to be configured in Okta
- Audit & Compliance: Document all entitlement types and values for compliance reviews
The application creates SAML 2.0 apps with default placeholder values:
- SSO ACS URL:
https://example.com/sso/saml - Audience URI:
https://example.com/{appName} - Name ID Format: Email address
- Signature Algorithm: RSA-SHA256
You'll need to update these values in the Okta Admin Console after creation to match your actual SAML service provider requirements.
- The
config.jsonfile is automatically excluded from git via.gitignore - Never commit API tokens to version control
- API tokens should be treated as passwords
- Rotate tokens regularly in production environments
- Consider using environment variables for production deployments
ISC