p1-cli
v0.4.0
Published
A CLI tool for managing PingOne resources
Maintainers
Readme
p1-cli
Command-line tool for managing PingOne resources via the PingOne Management API.
Table of Contents
- Features
- Installation
- Authentication
- Configuration
- Usage
- Known Limitations
- Architecture
- Error Handling
- Development
- License
- Disclaimer
Features
- OAuth 2.0 Authentication: Secure client credentials flow with automatic token management and refresh
- Cross-Platform Credential Storage: System keychain integration (macOS, Windows, Linux) with encrypted file fallback
- User Management: Full CRUD operations for PingOne users with verification and listing support
- User Status Management: Enable, disable, lock, and unlock user accounts
- Password Management: Set, reset, and recover user passwords with admin and self-service flows
- MFA Operations: Enable/disable MFA, list and delete MFA devices for users
- Session Management: List active sessions and revoke specific user sessions
- Bulk Operations: Import, export, and delete users in bulk with CSV/JSON support and parallel processing
- Groups Management: Create, read, update, delete groups with member management
- Populations Management: Complete CRUD operations for managing user populations
- Applications Management: Create and manage OAuth/OIDC applications with full lifecycle support
- Environments Management: List and read PingOne environments to discover environment IDs
- Automatic Retry Logic: Transient error handling with exponential backoff
- Response Caching: Configurable caching for read operations to reduce API calls
- Reusable HTTP Helpers: Centralized request handling with
executeRequest,executeCachedRequest, andexecuteVoidRequest - Type-Safe: Built with Effect library for robust error handling and type safety
- Schema Validation: Request/response validation using Effect Schema
- Multi-Region Support: Configurable API base URL for different PingOne regions
- CI/CD Ready: Environment variable support for automated workflows
Installation
From npm (Recommended)
# Install globally
npm install -g p1-cli
# Or use with npx (no installation required)
npx p1-cli --helpFrom Source
# Clone the repository
git clone https://github.com/ryanbas21/ping-cli
cd ping-cli
# Install dependencies
pnpm install
# Build the CLI
pnpm --filter 'p1-cli' build
# Link for local development
cd packages/ping-cli
npm linkSystem Requirements
Node.js: Version 18.x or higher recommended
Optional: Native Keychain Support (for secure credential storage)
The CLI uses keytar for secure credential storage in system keychains:
- macOS: Keychain Access (built-in)
- Windows: Credential Manager (built-in)
- Linux: Secret Service API (requires
libsecret)
Installing on Linux (for keychain support):
# Debian/Ubuntu
sudo apt-get install libsecret-1-dev
# Red Hat/Fedora
sudo yum install libsecret-devel
# Arch Linux
sudo pacman -S libsecretNote: If keytar is unavailable or keychain access fails, the CLI automatically falls back to:
- Encrypted file storage (
~/.ping-cli/credentials.enc) - Suitable for development/testing - Environment variables - For CI/CD environments
See OAUTH_SETUP.md for detailed credential storage information.
Authentication
The PingOne CLI supports OAuth 2.0 Client Credentials flow for secure, automatic token management.
Quick Start (OAuth)
- Create a Worker Application in PingOne (detailed setup guide)
- Authenticate the CLI:
p1-cli auth login \
--client-id="your-client-id" \
--client-secret="your-client-secret" \
--environment-id="your-environment-id" \
--region="com"Or use interactive mode (CLI will prompt for missing values):
p1-cli auth login- Verify authentication:
p1-cli auth status- Use the CLI (authentication is automatic after login):
# Authentication flags are optional when you've logged in
p1-cli list_users --environment-id="your-env-id"
# Or with stored credentials, environment ID is optional too if set via env var
export PINGONE_ENV_ID="your-env-id"
p1-cli list_usersFor complete setup instructions including PingOne Worker Application configuration, see OAUTH_SETUP.md.
Note: After running auth login, you don't need to provide --pingone-token flags - the CLI automatically manages tokens for you.
Authentication Methods
The CLI supports three authentication methods with automatic fallback priority:
1. OAuth Client Credentials (Recommended)
Store credentials once, tokens are managed automatically:
# Store credentials
p1-cli auth login --client-id="..." --client-secret="..." --environment-id="..." --region="com"
# Use CLI commands (no token needed)
p1-cli users list --environment-id="your-env-id"Benefits:
- Automatic token refresh
- Secure credential storage (system keychain)
- No manual token management
- Best for interactive use
2. Environment Variables
Set credentials via environment variables for CI/CD:
# For OAuth (preferred)
export PINGONE_CLIENT_ID="your-client-id"
export PINGONE_CLIENT_SECRET="your-client-secret"
export PINGONE_ENV_ID="your-environment-id"
# Optional: Configure token expiration buffer (default: 300 seconds / 5 minutes)
export PINGONE_TOKEN_BUFFER_SECONDS="60"
# Legacy: Direct token (still supported)
export PINGONE_TOKEN="your-access-token"
export PINGONE_ENV_ID="your-environment-id"
# Use CLI
p1-cli users listBenefits:
- No interactive login required
- Perfect for CI/CD pipelines
- Environment-specific credentials
3. CLI Flags
Provide authentication per-command:
p1-cli users list \
--environment-id="your-env-id" \
--pingone-token="your-access-token"Benefits:
- No stored credentials
- Useful for one-off commands
- Backward compatible
Authentication Priority
The CLI checks authentication in this order:
--pingone-tokenCLI flag (if provided)PINGONE_TOKENenvironment variable- OAuth service (stored credentials from
auth login)
If none are available, the CLI will prompt you to run p1-cli auth login.
CI/CD Integration
For automated environments (GitHub Actions, GitLab CI, etc.):
# Example: GitHub Actions
env:
PINGONE_CLIENT_ID: ${{ secrets.PINGONE_CLIENT_ID }}
PINGONE_CLIENT_SECRET: ${{ secrets.PINGONE_CLIENT_SECRET }}
PINGONE_ENV_ID: ${{ secrets.PINGONE_ENV_ID }}
steps:
- name: List Users
run: p1-cli users listSecurity Best Practices:
- Store credentials in CI/CD secrets (never in code)
- Use separate Worker Applications per environment
- Rotate credentials regularly
- Grant minimum required permissions
Configuration
Optional configuration via environment variables:
# Optional: PingOne API Base URL (defaults to North America)
PINGONE_API_URL=https://api.pingone.com/v1
# Optional: Default population ID
PINGONE_POPULATION_ID=your-default-population-idRegional API Endpoints
The CLI automatically configures the correct API endpoint based on the region you specify during auth login. The API URL is determined using this priority:
PINGONE_API_URLenvironment variable - Explicitly set URL (highest priority)- Stored credentials region - Automatically derived from your login credentials (automatic)
- Default - North America endpoint (fallback)
When you run auth login with a region:
p1-cli auth login --region="ca"
# Automatically uses: https://api.pingone.ca/v1 for all API callsNo manual configuration needed! The CLI automatically extracts the region from your stored credentials and uses the correct API endpoint.
Available Regions:
- North America (default):
https://api.pingone.com/v1 - Europe:
https://api.pingone.eu/v1 - Asia Pacific:
https://api.pingone.asia/v1 - Canada:
https://api.pingone.ca/v1
Manual Override (Optional):
# Override the API URL for testing or custom deployments
export PINGONE_API_URL="https://api.pingone.eu/v1"Usage
Common Usage Patterns
Once authenticated with p1-cli auth login, most commands can be run with minimal flags:
# Set your environment ID once (optional but convenient)
export PINGONE_ENV_ID="your-environment-id"
# Now commands are simple
p1-cli list_users
p1-cli create_user john.doe [email protected] --population-id="pop-123"
p1-cli groups list_groups
p1-cli populations list_populations
# Authentication flags (--pingone-token) are automatically handled
# Environment ID flag (--environment-id) is optional if PINGONE_ENV_ID is setAll examples below show explicit flags for clarity, but remember:
--pingone-tokenis optional when you've runauth login--environment-idis optional whenPINGONE_ENV_IDenvironment variable is set
Authentication Commands
Manage OAuth authentication and view authentication status:
# Login with OAuth client credentials
p1-cli auth login \
--client-id="your-client-id" \
--client-secret="your-client-secret" \
--environment-id="your-environment-id" \
--region="com"
# Login with interactive prompts
p1-cli auth login
# Check authentication status
p1-cli auth status
# Logout (clear stored credentials)
p1-cli auth logoutAuthentication Status Output:
✓ Authenticated
Client ID: 12345678****abcd
Environment: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
✓ Access token is valid
Expires: 1/10/2025, 3:30:00 PMEnvironment Commands
Discover and manage PingOne environments. These commands help you find your environment ID, which is required for other CLI operations.
# List all environments your token has access to
p1-cli environments list_environments \
--pingone-token <token>
# List environments with pagination
p1-cli environments list_environments \
--pingone-token <token> \
--limit 10
# List environments with filter (production only)
p1-cli environments list_environments \
--pingone-token <token> \
--filter 'type eq "PRODUCTION"'
# List environments with filter (sandbox only)
p1-cli environments list_environments \
--pingone-token <token> \
--filter 'type eq "SANDBOX"'
# List environments by region
p1-cli environments list_environments \
--pingone-token <token> \
--filter 'region eq "NA"'
# List environments by name (contains)
p1-cli environments list_environments \
--pingone-token <token> \
--filter 'name sw "Dev"'
# Read a specific environment by ID
p1-cli environments read_environment <environment-id> \
--pingone-token <token>Filter Operators:
eq- Equals (exact match)ne- Not equalssw- Starts withew- Ends withco- Containsand- Logical ANDor- Logical OR
Pagination Limitations:
- The
--limitparameter controls the maximum number of results returned in a single request - Currently, cursor-based pagination for fetching additional pages is not supported
- If your organization has more environments than the limit specified, only the first N results will be returned
- To retrieve all environments when you have many, you may need to use filtering to narrow results
- Results are cached for 5 minutes to improve performance and reduce API load
Note: Environment commands only require a --pingone-token (not an --environment-id) since they operate at the organization level.
User Commands
# Create a user
p1-cli create_user <username> <email> \
--environment-id <env-id> \
--pingone-token <token> \
--population-id <pop-id> \
--given-name "John" \
--family-name "Doe"
# Read a user
p1-cli read_user <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# Update a user (accepts JSON data)
p1-cli update_user <user-id> <json-data> \
--environment-id <env-id> \
--pingone-token <token>
# Update user example
p1-cli update_user abc123 '{"email":"[email protected]"}' \
--environment-id <env-id> \
--pingone-token <token>
# Delete a user
p1-cli delete_user <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# Verify a user with a verification code
p1-cli verify_user <user-id> <verification-code> \
--environment-id <env-id> \
--pingone-token <token>
# List users with optional filtering
p1-cli list_users \
--environment-id <env-id> \
--pingone-token <token> \
--limit 20 \
--filter 'email eq "[email protected]"'User Status Management
Control user account status and authentication capabilities:
# Enable a user account
p1-cli enable_user <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# Disable a user account
p1-cli disable_user <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# Lock a user account (prevents authentication)
p1-cli lock_user <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# Unlock a user account (allows authentication)
p1-cli unlock_user <user-id> \
--environment-id <env-id> \
--pingone-token <token>Note: Lock/unlock controls the account.canAuthenticate flag, while enable/disable controls the enabled flag.
Password Management
Manage user passwords with set, reset, and recovery operations:
# Set a user's password directly (admin operation)
p1-cli set_password <user-id> <password> \
--environment-id <env-id> \
--pingone-token <token>
# Set password and force change on next login
p1-cli set_password <user-id> <password> \
--environment-id <env-id> \
--pingone-token <token> \
--force-change
# Reset password (admin-initiated, sends reset email)
p1-cli reset_password <email> \
--environment-id <env-id> \
--pingone-token <token>
# Recover password (self-service, sends recovery email)
p1-cli recover_password <email> \
--environment-id <env-id> \
--pingone-token <token>Note:
set_password- Direct password change by administratorreset_password- Admin-initiated password reset flow (sends email)recover_password- Self-service password recovery flow (sends email)
MFA Operations
Manage multi-factor authentication for users:
# Enable MFA for a user
p1-cli enable_mfa <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# Disable MFA for a user
p1-cli disable_mfa <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# List MFA devices for a user
p1-cli list_mfa_devices <user-id> \
--environment-id <env-id> \
--pingone-token <token> \
--limit 10
# Delete a specific MFA device
p1-cli delete_mfa_device <user-id> <device-id> \
--environment-id <env-id> \
--pingone-token <token>Session Management
Manage and monitor user sessions:
# List active sessions for a user
p1-cli list_sessions <user-id> \
--environment-id <env-id> \
--pingone-token <token> \
--limit 10
# Revoke a specific session
p1-cli revoke_session <user-id> <session-id> \
--environment-id <env-id> \
--pingone-token <token>Note: Session management is useful for security operations like force logout or investigating active sessions.
Bulk Operations
Efficiently manage large numbers of users with bulk operations supporting CSV and JSON formats.
Bulk Import Users
Import users from a CSV or JSON file with parallel processing:
# Import from CSV (default format)
p1-cli bulk_import_users users.csv \
--environment-id <env-id> \
--pingone-token <token> \
--format csv
# Import from JSON
p1-cli bulk_import_users users.json \
--environment-id <env-id> \
--pingone-token <token> \
--format json
# Dry-run mode (preview without creating users)
p1-cli bulk_import_users users.csv \
--environment-id <env-id> \
--pingone-token <token> \
--dry-run
# Control concurrency (default: 5 parallel operations)
p1-cli bulk_import_users users.csv \
--environment-id <env-id> \
--pingone-token <token> \
--concurrency 10CSV Format Example:
username,email,populationId,givenName,familyName,department
john.doe,[email protected],pop-123,John,Doe,Engineering
jane.smith,[email protected],pop-123,Jane,Smith,SalesJSON Format Example:
[
{
"username": "john.doe",
"email": "[email protected]",
"populationId": "pop-123",
"givenName": "John",
"familyName": "Doe",
"department": "Engineering"
},
{
"username": "jane.smith",
"email": "[email protected]",
"populationId": "pop-123",
"givenName": "Jane",
"familyName": "Smith",
"department": "Sales"
}
]Bulk Export Users
Export users to CSV or JSON format:
# Export all users to CSV
p1-cli bulk_export_users users.csv \
--environment-id <env-id> \
--pingone-token <token> \
--format csv
# Export to JSON
p1-cli bulk_export_users users.json \
--environment-id <env-id> \
--pingone-token <token> \
--format json
# Export with filter
p1-cli bulk_export_users active-users.csv \
--environment-id <env-id> \
--pingone-token <token> \
--filter 'enabled eq true' \
--limit 1000Bulk Delete Users
Delete multiple users from a file containing user IDs:
# Delete users (requires --confirm flag for safety)
p1-cli bulk_delete_users user-ids.csv \
--environment-id <env-id> \
--pingone-token <token> \
--confirm
# Dry-run mode (preview without deleting)
p1-cli bulk_delete_users user-ids.csv \
--environment-id <env-id> \
--pingone-token <token> \
--dry-run
# Control concurrency for rate limiting
p1-cli bulk_delete_users user-ids.csv \
--environment-id <env-id> \
--pingone-token <token> \
--confirm \
--concurrency 3CSV Format for Deletion:
userId
abc-123-def
xyz-456-ghiBulk Operations Features:
- Parallel Processing: Process multiple operations concurrently (default: 5)
- Progress Tracking: Real-time progress updates every 10 operations
- Error Collection: Automatic collection and reporting of failures
- Dry-Run Mode: Preview operations without making changes
- Flexible Formats: Support for both CSV and JSON
- Rate Limiting: Configurable concurrency to respect API limits
Group Commands
# Create a group
p1-cli groups create_group <name> \
--environment-id <env-id> \
--pingone-token <token> \
--description "Group description"
# Read a group
p1-cli groups read_group <group-id> \
--environment-id <env-id> \
--pingone-token <token>
# List all groups
p1-cli groups list_groups \
--environment-id <env-id> \
--pingone-token <token> \
--limit 10
# Update a group
p1-cli groups update_group <group-id> \
--environment-id <env-id> \
--pingone-token <token> \
--name "New Name"
# Delete a group
p1-cli groups delete_group <group-id> \
--environment-id <env-id> \
--pingone-token <token>
# Add a member to a group
p1-cli groups add_member <group-id> <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# Remove a member from a group
p1-cli groups remove_member <group-id> <user-id> \
--environment-id <env-id> \
--pingone-token <token>
# List group members
p1-cli groups list_members <group-id> \
--environment-id <env-id> \
--pingone-token <token>Population Commands
# Create a population
p1-cli populations create_population <name> \
--environment-id <env-id> \
--pingone-token <token> \
--description "Population description"
# Read a population
p1-cli populations read_population <population-id> \
--environment-id <env-id> \
--pingone-token <token>
# List all populations
p1-cli populations list_populations \
--environment-id <env-id> \
--pingone-token <token>
# Update a population
p1-cli populations update_population <population-id> \
--environment-id <env-id> \
--pingone-token <token> \
--name "New Name"
# Delete a population
p1-cli populations delete_population <population-id> \
--environment-id <env-id> \
--pingone-token <token>Application Commands
# Create an application
p1-cli applications create_application <name> \
--environment-id <env-id> \
--pingone-token <token> \
--description "App description" \
--type "WEB_APP"
# Read an application
p1-cli applications read_application <application-id> \
--environment-id <env-id> \
--pingone-token <token>
# List all applications
p1-cli applications list_applications \
--environment-id <env-id> \
--pingone-token <token>
# Update an application
p1-cli applications update_application <application-id> \
--environment-id <env-id> \
--pingone-token <token> \
--name "New Name"
# Delete an application
p1-cli applications delete_application <application-id> \
--environment-id <env-id> \
--pingone-token <token>Known Limitations
OAuth Permission Scopes
Some CLI commands require additional OAuth scopes that may not be granted by default to Worker Applications in PingOne:
UPDATE Operations - Require update scopes:
update_user- Requiresupdate:usersscopegroups update_group- Requiresupdate:groupsscopepopulations update_population- Requiresupdate:populationsscopeapplications update_application- Requiresupdate:applicationsscope
User State Operations - Require user:updateStatus scope:
enable_user,disable_user- Control user enabled statuslock_user,unlock_user- Control authentication capabilityenable_mfa,disable_mfa- Control MFA settingsset_password,reset_password,recover_password- Password operations
Troubleshooting:
If you receive 403 Forbidden or 400 Bad Request errors for these operations:
- Verify your Worker Application has the required scopes in PingOne Admin Console
- Navigate to: Applications → Your Worker App → Resources
- Add the necessary scopes for the operations you need
- Run
p1-cli auth logoutandp1-cli auth loginto get a fresh token with new scopes
Working Operations (available with default Worker Application permissions):
- ✅ All CREATE operations (users, groups, populations, applications)
- ✅ All READ operations (individual and list)
- ✅ All DELETE operations
- ✅ Session listing and management
- ✅ MFA device listing
- ✅ Environment discovery
Architecture
For detailed information about the internal architecture, service composition, and design patterns, see:
- Architecture Guide - Service composition, layer composition, HTTP client patterns
- API Reference - Detailed API documentation
Error Handling
The CLI provides clear error messages to help troubleshoot issues:
Common Error Types
- Authentication Errors: Occurs when credentials are missing or invalid. Run
p1-cli auth loginto authenticate. - API Errors: Returned by the PingOne API (e.g., resource not found, permission denied). Check the error message for details.
- Validation Errors: Input validation failed (e.g., invalid email format, missing required fields).
- Network Errors: Connection issues or timeouts. The CLI automatically retries transient failures.
- Rate Limit Errors: Too many requests. The CLI automatically respects rate limits and retries after the specified delay.
Troubleshooting
If you encounter errors:
- Check authentication: Run
p1-cli auth statusto verify you're authenticated - Verify permissions: Ensure your Worker Application has the necessary OAuth scopes (see Known Limitations)
- Check environment ID: Verify you're using the correct environment ID
- Review error details: Error messages include context to help identify the issue
For detailed error type information for developers, see CONTRIBUTING.md
Development
Want to contribute? See CONTRIBUTING.md for development setup, testing, and contribution guidelines
License
MIT
Disclaimer
⚠️ IMPORTANT: This is completely unsupported and is NOT an official release of a Ping product. This tool is provided as-is for development and testing purposes only. Use at your own risk.
