<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>PingIdentity on IAMDevBox</title><link>https://www.iamdevbox.com/tags/pingidentity/</link><description>Recent content in PingIdentity on IAMDevBox</description><image><title>IAMDevBox</title><url>https://www.iamdevbox.com/IAMDevBox.com.jpg</url><link>https://www.iamdevbox.com/IAMDevBox.com.jpg</link></image><generator>Hugo -- 0.146.0</generator><language>en-us</language><lastBuildDate>Mon, 04 May 2026 16:04:04 +0000</lastBuildDate><atom:link href="https://www.iamdevbox.com/tags/pingidentity/index.xml" rel="self" type="application/rss+xml"/><item><title>PingOne Advanced Identity Cloud: Architecture, Features, and Developer Guide</title><link>https://www.iamdevbox.com/posts/pingone-advanced-identity-cloud-complete-guide-architecture-features-and-getting-started/</link><pubDate>Mon, 29 Dec 2025 14:28:27 +0000</pubDate><guid>https://www.iamdevbox.com/posts/pingone-advanced-identity-cloud-complete-guide-architecture-features-and-getting-started/</guid><description>PingOne Advanced Identity Cloud developer guide: OIDC/SAML app setup, DaVinci orchestration, MFA configuration, and migration from PingFederate. Includes tenant endpoints, API examples, and troubleshooting common errors.</description><content:encoded><![CDATA[<p>PingOne Advanced Identity Cloud (AIC) is the platform you land on when Ping Identity positions you for cloud-native IAM. It combines the ForgeRock AM/IDM engines with Ping&rsquo;s DaVinci no-code orchestration, all hosted as managed SaaS. If you&rsquo;ve worked with ForgeRock Identity Cloud or legacy PingFederate, AIC will feel familiar — but the console, APIs, and deployment model are different enough to require a dedicated ramp-up.</p>
<p>This guide covers what AIC actually is, how its architecture works, and how to get your first application integrated.</p>
<h2 id="what-is-pingone-advanced-identity-cloud">What Is PingOne Advanced Identity Cloud?</h2>
<p>AIC is Ping&rsquo;s answer to cloud-native CIAM and workforce IAM. After acquiring ForgeRock in 2023, Ping combined ForgeRock Identity Cloud&rsquo;s capabilities with its own DaVinci orchestration platform into a single SaaS offering.</p>
<p><strong>What AIC includes:</strong></p>
<ul>
<li><strong>Authorization Server (AS)</strong>: OAuth 2.0/OIDC/SAML 2.0/FAPI authorization server based on ForgeRock AM</li>
<li><strong>Identity Store</strong>: Managed user directory with schema extension support</li>
<li><strong>Identity Management (IDM)</strong>: Provisioning, reconciliation, connectors to HR/AD/SCIM sources</li>
<li><strong>DaVinci</strong>: Visual no-code flow builder for authentication journeys, registration, and MFA</li>
<li><strong>Governance (optional add-on)</strong>: Access reviews, entitlement management, IGA</li>
</ul>
<p><strong>What AIC is NOT:</strong></p>
<ul>
<li>Not self-hosted — you don&rsquo;t run it on your infrastructure</li>
<li>Not PingFederate — if you have existing PF config, there&rsquo;s a migration path but no direct export/import</li>
<li>Not just PingOne — the legacy PingOne SSO product is a separate offering</li>
</ul>
<h3 id="tenant-structure">Tenant Structure</h3>
<p>Every AIC tenant has one or more <strong>Environments</strong> (e.g., production, staging, dev). Each environment has its own:</p>
<ul>
<li>Environment ID (a UUID, shown in the admin console)</li>
<li>Authorization server base URL: <code>https://&lt;tenant-domain&gt;/&lt;environment_id&gt;/as</code></li>
<li>OIDC discovery: <code>https://&lt;tenant-domain&gt;/&lt;environment_id&gt;/as/.well-known/openid-configuration</code></li>
<li>Admin API: <code>https://&lt;tenant-domain&gt;/v1/environments/&lt;environment_id&gt;</code></li>
</ul>
<p>The tenant domain format is typically <code>auth.pingone.com</code>, <code>auth.pingone.eu</code>, or a custom domain.</p>
<h2 id="architecture-overview">Architecture Overview</h2>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>┌─────────────────────────────────────────────────────────────┐
</span></span><span style="display:flex;"><span>│                 PingOne Advanced Identity Cloud              │
</span></span><span style="display:flex;"><span>│                                                             │
</span></span><span style="display:flex;"><span>│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────┐  │
</span></span><span style="display:flex;"><span>│  │ Authorization│  │  DaVinci     │  │  Identity Mgmt   │  │
</span></span><span style="display:flex;"><span>│  │ Server (AM)  │  │ Orchestration│  │  (IDM/SCIM)      │  │
</span></span><span style="display:flex;"><span>│  │ OIDC/SAML/   │  │ Flows &amp;      │  │  Provisioning    │  │
</span></span><span style="display:flex;"><span>│  │ FAPI         │  │ Connectors   │  │  Sync            │  │
</span></span><span style="display:flex;"><span>│  └──────────────┘  └──────────────┘  └──────────────────┘  │
</span></span><span style="display:flex;"><span>│         │                 │                  │              │
</span></span><span style="display:flex;"><span>│  ┌──────┴─────────────────┴──────────────────┴──────────┐  │
</span></span><span style="display:flex;"><span>│  │              Identity Store (User Directory)           │  │
</span></span><span style="display:flex;"><span>│  └────────────────────────────────────────────────────────┘  │
</span></span><span style="display:flex;"><span>└─────────────────────────────────────────────────────────────┘
</span></span><span style="display:flex;"><span>         ↕ OIDC/SAML/API          ↕ SCIM/REST
</span></span><span style="display:flex;"><span>   Your Applications          External Systems (AD, HR, LDAP)
</span></span></code></pre></div><p><strong>Authentication flow:</strong></p>
<ol>
<li>User hits your app → redirected to AIC authorization endpoint</li>
<li>AIC runs a DaVinci flow (or default AM tree/journey) for authentication</li>
<li>AM issues tokens → returned to your app via redirect</li>
<li>Your app validates tokens using the JWKS endpoint or token introspection</li>
</ol>
<h2 id="setting-up-an-oidc-application">Setting Up an OIDC Application</h2>
<h3 id="step-1-create-the-application">Step 1: Create the Application</h3>
<p>In the AIC admin console:</p>
<ol>
<li>Navigate to <strong>Applications</strong> → <strong>Applications</strong> → <strong>+</strong> (Add Application)</li>
<li>Select <strong>OIDC Web App</strong> (for server-side apps) or <strong>Single Page App</strong> (for SPAs)</li>
<li>Set a name and click <strong>Save</strong></li>
</ol>
<h3 id="step-2-configure-the-application">Step 2: Configure the Application</h3>
<p>Under the <strong>Configuration</strong> tab:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>Redirect URIs:       https://your-app.example.com/callback
</span></span><span style="display:flex;"><span>                     http://localhost:3000/callback  (dev only)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Sign On URL:         https://your-app.example.com/
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Token Endpoint Auth: CLIENT_SECRET_BASIC  (for web apps)
</span></span><span style="display:flex;"><span>                     NONE (for SPAs using PKCE)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>Grant Types:         ✅ Authorization Code
</span></span><span style="display:flex;"><span>                     ✅ Refresh Token
</span></span><span style="display:flex;"><span>                     ☐ Implicit (avoid — deprecated)
</span></span></code></pre></div><p>Enable <strong>PKCE Enforcement</strong> for public clients (SPAs, mobile apps). This is a security best practice — even for confidential clients, PKCE adds protection against authorization code interception.</p>
<h3 id="step-3-note-your-endpoints">Step 3: Note Your Endpoints</h3>
<p>From the <strong>Overview</strong> tab, copy:</p>
<ul>
<li><strong>Client ID</strong>: <code>&lt;uuid&gt;</code></li>
<li><strong>Client Secret</strong>: Shown once — store in a secrets manager</li>
</ul>
<p>Your token endpoint:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>https://auth.pingone.com/&lt;env_id&gt;/as/token
</span></span></code></pre></div><p>Authorization endpoint:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>https://auth.pingone.com/&lt;env_id&gt;/as/authorize
</span></span></code></pre></div><p>Discover all endpoints programmatically:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>curl https://auth.pingone.com/&lt;env_id&gt;/as/.well-known/openid-configuration | jq .
</span></span></code></pre></div><h3 id="step-4-test-an-authorization-code-flow">Step 4: Test an Authorization Code Flow</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Step 1: Build authorization URL</span>
</span></span><span style="display:flex;"><span>AUTH_URL<span style="color:#f92672">=</span><span style="color:#e6db74">&#34;https://auth.pingone.com/&lt;env_id&gt;/as/authorize?\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">response_type=code\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&amp;client_id=&lt;client_id&gt;\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&amp;redirect_uri=https://your-app.example.com/callback\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&amp;scope=openid+profile+email\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&amp;state=</span><span style="color:#66d9ef">$(</span>openssl rand -hex 16<span style="color:#66d9ef">)</span><span style="color:#e6db74">\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&amp;code_challenge=&lt;pkce_challenge&gt;\
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">&amp;code_challenge_method=S256&#34;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Step 2: Exchange code for tokens</span>
</span></span><span style="display:flex;"><span>curl -X POST https://auth.pingone.com/&lt;env_id&gt;/as/token <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Content-Type: application/x-www-form-urlencoded&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;grant_type=authorization_code&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;code=&lt;auth_code&gt;&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;redirect_uri=https://your-app.example.com/callback&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;client_id=&lt;client_id&gt;&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;client_secret=&lt;client_secret&gt;&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;code_verifier=&lt;pkce_verifier&gt;&#34;</span>
</span></span></code></pre></div><h2 id="configuring-saml-20-sso">Configuring SAML 2.0 SSO</h2>
<p>For legacy enterprise apps using SAML, AIC acts as an IdP.</p>
<h3 id="add-a-saml-application">Add a SAML Application</h3>
<ol>
<li><strong>Applications</strong> → <strong>+</strong> → <strong>SAML Application</strong></li>
<li>Upload SP metadata XML (preferred) <strong>or</strong> enter manually:
<ul>
<li><strong>ACS URL</strong>: <code>https://sp.example.com/sso/acs</code></li>
<li><strong>Entity ID</strong>: <code>https://sp.example.com</code></li>
</ul>
</li>
<li>Configure Name ID format (typically <code>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</code>)</li>
</ol>
<h3 id="download-idp-metadata">Download IdP Metadata</h3>
<p>Give this URL to your SP:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-text" data-lang="text"><span style="display:flex;"><span>https://auth.pingone.com/&lt;env_id&gt;/saml20/idp/metadata
</span></span></code></pre></div><p>Or download XML: <strong>Applications</strong> → your SAML app → <strong>Configuration</strong> → <strong>Download Metadata</strong></p>
<h3 id="attribute-mapping">Attribute Mapping</h3>
<p>AIC sends user attributes in the assertion. Map them in the <strong>Attribute Mappings</strong> tab:</p>
<table>
  <thead>
      <tr>
          <th>SAML Attribute</th>
          <th>AIC User Attribute</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><code>email</code></td>
          <td><code>user.email</code></td>
      </tr>
      <tr>
          <td><code>firstName</code></td>
          <td><code>user.name.given</code></td>
      </tr>
      <tr>
          <td><code>lastName</code></td>
          <td><code>user.name.family</code></td>
      </tr>
      <tr>
          <td><code>groups</code></td>
          <td><code>user.memberOfGroupNames</code></td>
      </tr>
  </tbody>
</table>
<h2 id="davinci-no-code-authentication-flows">DaVinci: No-Code Authentication Flows</h2>
<p>DaVinci is where you customize what happens during login — step-up MFA, fraud checks, custom registration, account linking.</p>
<h3 id="flow-basics">Flow Basics</h3>
<p>A DaVinci flow is a visual graph of <strong>connectors</strong> (nodes). Each connector wraps an API or internal service:</p>
<ul>
<li><strong>PingOne Authentication</strong> — triggers the AIC login session</li>
<li><strong>PingOne MFA</strong> — sends push/OTP to enrolled devices</li>
<li><strong>HTTP</strong> — custom API call to your backend (risk check, account lookup)</li>
<li><strong>Error</strong> — returns a user-facing error message</li>
</ul>
<h3 id="linking-a-flow-to-your-application">Linking a Flow to Your Application</h3>
<ol>
<li>Create and test your flow in <strong>DaVinci</strong> → <strong>Flows</strong></li>
<li>In <strong>DaVinci</strong> → <strong>Applications</strong>, create a policy that references the flow</li>
<li>In your <strong>OIDC Application</strong> → <strong>Experience</strong> tab, set the DaVinci policy</li>
</ol>
<p>Once linked, every authorization request to that client triggers your DaVinci flow instead of the default AM login tree.</p>
<h3 id="example-require-mfa-for-admin-users">Example: Require MFA for Admin Users</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-toml" data-lang="toml"><span style="display:flex;"><span>[<span style="color:#a6e22e">Start</span>] <span style="color:#960050;background-color:#1e0010">→</span> [<span style="color:#a6e22e">Get</span> <span style="color:#a6e22e">User</span>] <span style="color:#960050;background-color:#1e0010">→</span> [<span style="color:#a6e22e">Check</span> <span style="color:#a6e22e">Group</span><span style="color:#960050;background-color:#1e0010">:</span> <span style="color:#a6e22e">is-admin</span><span style="color:#960050;background-color:#1e0010">?</span>]
</span></span><span style="display:flex;"><span>                              <span style="color:#960050;background-color:#1e0010">│</span> <span style="color:#a6e22e">yes</span>
</span></span><span style="display:flex;"><span>                        [<span style="color:#a6e22e">PingOne</span> <span style="color:#a6e22e">MFA</span><span style="color:#960050;background-color:#1e0010">:</span> <span style="color:#a6e22e">Push</span>] <span style="color:#960050;background-color:#1e0010">→</span> [<span style="color:#a6e22e">Success</span>]
</span></span><span style="display:flex;"><span>                              <span style="color:#960050;background-color:#1e0010">│</span> <span style="color:#a6e22e">no</span>
</span></span><span style="display:flex;"><span>                        [<span style="color:#a6e22e">PingOne</span> <span style="color:#a6e22e">Auth</span><span style="color:#960050;background-color:#1e0010">:</span> <span style="color:#a6e22e">Password</span>] <span style="color:#960050;background-color:#1e0010">→</span> [<span style="color:#a6e22e">Success</span>]
</span></span></code></pre></div><p>Build this in the DaVinci visual editor — no code required.</p>
<h2 id="mfa-configuration">MFA Configuration</h2>
<h3 id="enroll-a-device-via-api">Enroll a Device via API</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Get user ID first</span>
</span></span><span style="display:flex;"><span>USER_ID<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>curl -s <span style="color:#e6db74">&#34;https://api.pingone.com/v1/environments/&lt;env_id&gt;/users?filter=email eq \&#34;user@example.com\&#34;&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Authorization: Bearer &lt;mgmt_token&gt;&#34;</span> | jq -r <span style="color:#e6db74">&#39;._embedded.users[0].id&#39;</span><span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Send MFA enrollment email</span>
</span></span><span style="display:flex;"><span>curl -X POST <span style="color:#e6db74">&#34;https://api.pingone.com/v1/environments/&lt;env_id&gt;/users/</span>$USER_ID<span style="color:#e6db74">/mfaEnabled&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Authorization: Bearer &lt;mgmt_token&gt;&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#39;{&#34;mfaEnabled&#34;: true}&#39;</span>
</span></span></code></pre></div><h3 id="supported-mfa-methods">Supported MFA Methods</h3>
<table>
  <thead>
      <tr>
          <th>Method</th>
          <th>Use Case</th>
          <th>Setup</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>TOTP (authenticator app)</td>
          <td>Standard MFA</td>
          <td>User scans QR code</td>
      </tr>
      <tr>
          <td>Push notification (PingID)</td>
          <td>Frictionless MFA</td>
          <td>PingID mobile app</td>
      </tr>
      <tr>
          <td>SMS OTP</td>
          <td>Legacy/fallback</td>
          <td>Requires SMS provider config</td>
      </tr>
      <tr>
          <td>Email OTP</td>
          <td>Low-friction</td>
          <td>Built-in</td>
      </tr>
      <tr>
          <td>FIDO2/Passkeys</td>
          <td>Phishing-resistant</td>
          <td>Requires FIDO2 device</td>
      </tr>
      <tr>
          <td>Voice OTP</td>
          <td>Accessibility</td>
          <td>Requires telephony provider</td>
      </tr>
  </tbody>
</table>
<h2 id="user-management-api">User Management API</h2>
<p>AIC exposes a REST API for SCIM-compatible user management:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span><span style="color:#75715e"># Get management token (client credentials)</span>
</span></span><span style="display:flex;"><span>MGMT_TOKEN<span style="color:#f92672">=</span><span style="color:#66d9ef">$(</span>curl -s -X POST <span style="color:#e6db74">&#34;https://auth.pingone.com/&lt;env_id&gt;/as/token&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#34;grant_type=client_credentials&amp;client_id=&lt;worker_app_id&gt;&amp;client_secret=&lt;secret&gt;&amp;scope=p1:read:user p1:create:user p1:update:user&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  | jq -r <span style="color:#e6db74">&#39;.access_token&#39;</span><span style="color:#66d9ef">)</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Create a user</span>
</span></span><span style="display:flex;"><span>curl -X POST <span style="color:#e6db74">&#34;https://api.pingone.com/v1/environments/&lt;env_id&gt;/users&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Authorization: Bearer </span>$MGMT_TOKEN<span style="color:#e6db74">&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Content-Type: application/json&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -d <span style="color:#e6db74">&#39;{
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;email&#34;: &#34;alice@example.com&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;username&#34;: &#34;alice&#34;,
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;name&#34;: {&#34;given&#34;: &#34;Alice&#34;, &#34;family&#34;: &#34;Smith&#34;},
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">    &#34;population&#34;: {&#34;id&#34;: &#34;&lt;population_id&gt;&#34;}
</span></span></span><span style="display:flex;"><span><span style="color:#e6db74">  }&#39;</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e"># Search users</span>
</span></span><span style="display:flex;"><span>curl <span style="color:#e6db74">&#34;https://api.pingone.com/v1/environments/&lt;env_id&gt;/users?filter=email sw \&#34;alice\&#34;&#34;</span> <span style="color:#ae81ff">\
</span></span></span><span style="display:flex;"><span><span style="color:#ae81ff"></span>  -H <span style="color:#e6db74">&#34;Authorization: Bearer </span>$MGMT_TOKEN<span style="color:#e6db74">&#34;</span>
</span></span></code></pre></div><p>The management API requires a <strong>Worker Application</strong> (client credentials flow) with appropriate scopes. Never use your end-user application&rsquo;s client for management operations.</p>
<h2 id="pingone-vs-pingfederate-vs-pingone-aic">PingOne vs PingFederate vs PingOne AIC</h2>
<table>
  <thead>
      <tr>
          <th></th>
          <th>PingFederate</th>
          <th>PingOne (legacy)</th>
          <th>PingOne AIC</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Deployment</strong></td>
          <td>Self-hosted</td>
          <td>SaaS</td>
          <td>SaaS (managed cloud)</td>
      </tr>
      <tr>
          <td><strong>Based on</strong></td>
          <td>Proprietary</td>
          <td>Proprietary</td>
          <td>ForgeRock AM/IDM</td>
      </tr>
      <tr>
          <td><strong>Primary use</strong></td>
          <td>Federation gateway</td>
          <td>Workforce SSO/MFA</td>
          <td>CIAM + Workforce</td>
      </tr>
      <tr>
          <td><strong>Orchestration</strong></td>
          <td>Groovy scripts</td>
          <td>Basic policies</td>
          <td>DaVinci no-code flows</td>
      </tr>
      <tr>
          <td><strong>B2C support</strong></td>
          <td>Limited</td>
          <td>No</td>
          <td>Yes (progressive profiling, consent)</td>
      </tr>
      <tr>
          <td><strong>FAPI support</strong></td>
          <td>Via extension</td>
          <td>No</td>
          <td>Native</td>
      </tr>
      <tr>
          <td><strong>Migration target</strong></td>
          <td>Yes — move to AIC</td>
          <td>Yes — move to AIC</td>
          <td>Current platform</td>
      </tr>
  </tbody>
</table>
<h2 id="common-errors-and-fixes">Common Errors and Fixes</h2>
<p><strong><code>invalid_client</code> on token endpoint</strong></p>
<ul>
<li>Check that your Client ID and secret are correct</li>
<li>Verify the client has the correct grant type enabled</li>
<li>Confirm the redirect URI matches exactly (trailing slash matters)</li>
</ul>
<p><strong><code>access_denied</code> during authorization</strong></p>
<ul>
<li>User is blocked by a DaVinci flow condition (check flow logs in DaVinci → Flows → Executions)</li>
<li>Population restrictions — user may be in a population not assigned to the application</li>
<li>MFA required but device not enrolled</li>
</ul>
<p><strong><code>SAML Response: InResponseTo attribute not matching any outstanding AuthnRequest</code></strong></p>
<ul>
<li>Session mismatch — typically caused by replay or stale browser cache</li>
<li>Fix: clear cookies and restart the SP-initiated flow</li>
</ul>
<p><strong><code>401 Unauthorized</code> on management API</strong></p>
<ul>
<li>Management token has expired (default 1 hour) — re-request it</li>
<li>Worker application missing required scopes — check the token&rsquo;s <code>scope</code> claim</li>
<li>Using wrong environment ID in the API URL</li>
</ul>
<h2 id="troubleshooting-with-logs">Troubleshooting with Logs</h2>
<p>Enable detailed logs under <strong>Settings</strong> → <strong>Environment</strong> → <strong>Audit Logs</strong>. Filter by:</p>
<ul>
<li>Actor (user or application)</li>
<li>Action (<code>SSO_LOGIN</code>, <code>TOKEN_ISSUED</code>, <code>MFA_FAILED</code>)</li>
<li>IP address</li>
</ul>
<p>For DaVinci flow failures, check <strong>DaVinci</strong> → <strong>Flows</strong> → <strong>[flow name]</strong> → <strong>Executions</strong> — each execution shows the step-by-step result including error details.</p>
<h2 id="related-articles">Related Articles</h2>
<p>For PingOne MFA push notification setup and OTP configuration, see the dedicated guide:</p>
<ul>
<li><a href="/posts/pingid-mfa-integration-push-notifications-and-otp-configuration/">PingID MFA Integration: Push Notifications and OTP Configuration</a></li>
<li><a href="/posts/navigating-ping-identity-a-deep-dive-into-features-use-cases-and-comparisons/">Navigating Ping Identity: Features, Use Cases, and Comparisons</a></li>
<li><a href="/tools/saml-decoder/">SAML Decoder Tool</a> — Debug SAML assertions from AIC inline</li>
</ul>
]]></content:encoded></item></channel></rss>