How do I use the Okta API in Perl? Skip to main content
How satisfied are you with the Okta Help Center?
Thank you for your feedback!
How satisfied are you with the Okta Help Center?
Very Dissatisfied
Very satisfied
Enter content less than 200 characters.
Ask Search:
Christopher NiggelChristopher Niggel 

How do I use the Okta API in Perl?

I created this script back during our response to the Heartbleed bug.  (Please note, LinkedIn products were not affected by Heartbleed, but some of our hosted applications that did not store or manipulate member data were)  We determined, as a safety precaution, to reset the Okta passwords of a subset of our employees.  To accomplish this, I loaded those users into an AD group which was sync'd with Okta, and then ran this script to parse that group and send password requests.

I'm posting our work to use as an example to how to use the Okta APIs in a Perl script.  Its functionality is not expressed or implied!
#!/usr/bin/perl -w

#Okta password reset script
#Written in response to the Heartbleed SSL bug
#Set the baseURL and the group ID of your affected users
#Set the Authorization header to contain a valid API key
#Outputs to stdout
#C. Niggel LinkedIn Corporation v.2014.4.15r2

use REST::Client;
use JSON::Parse ':all';
use Time::HiRes qw(usleep);

#define our globals
my $client = REST::Client->new();
#k is a loop counter;
my $k = 1;
#edit these options
my $baseurl = "";
my $groupID = "<group id>";

#don't edit these options
my $apiurl = $baseurl ."api/v1/groups/" .$groupID ."/users?";
my $pagecount = 1000;

#define my helper functions
#http request subroutine
#requires a URL in a string, and works on the global client
sub run_api_call {
 #start with connecting to Okta and getting the group
  $client->addHeader('Authorization','SSWS <token>');
#  print $client->responseContent();

#start main program loop

#start with by setting a target url 
my $urlstring = $apiurl . "limit=" .$pagecount;

while($k != 0) {
  #start the loop, set k to 0 so we fail out
  $k = 0;
  #go get the users
  #print "headers are: " . $client->responseHeaders() ."\n";
  #print "body is: " . $client->responseContent() . "\n";
  #obtain the link header
  my $linkheader =  $client->responseHeader("Link");
  #obtain the result set
  my @responsetext = parse_json($client->responseContent());
  #print "received response: " .$#responsetext ."\n";
  #print ref $responsetext; 
  # the group object is now in responsetext
  #begin the password reset subroutine
  for my $i (0..$#responsetext) {
       for my $j (0..$#{$responsetext[$i]}) {
       print $responsetext[$i][$j]{profile}{login} ."\n";

       $newurl = $baseurl . "api/v1/users/" . $responsetext[$i][$j]{id} . "/lifecycle/reset_password?sendEmail=true";
       #print $newurl ."\n";

       #these two lines are the API call. uncomment them to take action
       #print $client->responseContent() ."\n";

       #this throttles the script to no more than 35 API calls/sec
       #a more advanced script would read the throttling header, but this will do


  #Test the link header for pagination. If exists, get more users
  #first, look for the next link in the link header
  if($linkheader =~ m/,(.*)next/) { 
    #we have a next link. filter out the target
    if($1 =~ m/after\=(.*)&/)
          my $target = $1;
          #print "\ntarget" . $target;
  	  if (index($target, 'self') == -1) {     
             #double-checking that it's not a self link. This is probably not necessary
             #we have identified our target, set URL and k
             $urlstring = $apiurl ."after=" .$target ."&limit=" . $pagecount;
	     $k = 1;
#end of loop

print "\n done. \n"


ThomasThomas (Okta, Inc.) 
Chris, thanks for sharing this script, we have had several requests for how to do this from Community members.  Tom
Christopher NiggelChristopher Niggel
Another note, Okta added a big red "Expire All Passwords" button in response to Heartbleed as well.  If you need to respond to an incident, this may be a good approach.  In our case, we determined the greatest risk was to a subset of about 900 users, and didn't want to force 6000 unnecessary password resets!