Skip to content
API Reference

Connect Ping Identity

Connect PingFederate or PingOne as an identity provider for zone-level user authentication.

This is the Ping Identity walkthrough for Authenticate users with your identity provider. In it, you create an OAuth client in PingFederate, or an application in PingOne, and add it to a custom Zone as a Provider so that Users sign in with their Ping account. Select the tab for the Ping product you run; the Keycard steps are the same for both.

Keycard signs Users in with OpenID Connect, so you set Ping up as an OpenID Connect provider, not a SAML identity provider. Keycard also calls Ping server to server, to read its discovery document and to redeem sign-in codes, so the Ping runtime host must be reachable from the internet, not only from your users’ browsers, and must serve a certificate from a publicly trusted certificate authority.

You need Manager access to the custom Zone; organization Admins aren’t Managers of a custom Zone automatically (see Assign Zone Admin Access). The Zone in this tutorial is named “Example”. Replace <zone-id> with your Zone ID, which appears in the Zone’s domain (<zone-id>.keycard.cloud).

  1. Check the issuer. Open https://<pingfederate-host>/.well-known/openid-configuration and note the issuer, which is PingFederate’s Base URL, port included. If other applications use this instance, don’t change Base URL. On a new instance, you can set it (System > Server > Protocol Settings, Federation Info tab) to a public address without the default :9031 port.

  2. Define the sign-in scopes. In System > OAuth Settings > Scope Management, on the Common Scopes tab, make sure openid, profile, and email exist, adding any that are missing as ordinary scopes rather than dynamic ones. Keycard requests all three on every sign-in, and PingFederate rejects the request before its sign-in page if one is missing. Define any scope you later add under Additional Scopes in Keycard here too.

  3. Map your sign-in to OAuth. In Authentication > OAuth > IdP Adapter Grant Mapping, map the IdP adapter your users already sign in with. On Contract Fulfillment, fulfill USER_KEY and USER_NAME from the adapter’s unique user attribute. USER_KEY feeds sub, which Keycard uses to recognize a returning User, so choose an attribute that never changes. When PingFederate doesn’t use authentication policies for OAuth, mapping more than one adapter shows an adapter-selection page at sign-in.

  4. Set up an access token manager. The OpenID Connect policy needs one. In Applications > OAuth > Access Token Management, reuse an instance or click Create New Instance. Any token type works, because Keycard reads identity from the ID token and doesn’t inspect the access token. Add sub to the instance’s Access Token Attribute Contract. Then in Applications > OAuth > Access Token Mappings, add a mapping for the Default context and this manager, and fulfill sub from USER_KEY with Persistent Grant as the source.

  5. Create the OpenID Connect policy. In Applications > OAuth > OpenID Connect Policy Management, click Add Policy.

    • On Manage Policy, enter a Policy ID and Name, select the access token manager, and select Include User Info in ID Token. Keycard reads claims from the ID token only, so this setting is what gets email and groups to Keycard.
    • On Attribute Contract, keep sub and email, with email left single-valued. To send group membership, add groups under Extend the Contract and select Multi-Valued. Each attribute in the contract needs a source on Contract Fulfillment, so delete the preloaded claims you won’t use, or set them to No Mapping.
    • Leave Attribute Scopes empty. If you do tie attributes to scopes, tie groups to a scope Keycard requests: profile, or a groups scope you also add under Additional Scopes in Keycard.
    • If the email and group attributes live in a directory, add it on Attribute Sources & User Lookup first. On Contract Fulfillment, fulfill sub from USER_KEY with Persistent Grant as the source, email from the attribute holding each user’s email address, and groups from the one holding their group names.

    Save the policy. A new instance has no default policy, so mark this one as the default on the policy list, or select it on the client next.

  6. Create the OAuth client. In Applications > OAuth > Clients, click Add Client.

    • Enter a Client ID, and enter “Example” as the Name.
    • Under Client Authentication, select Client Secret (Internally Managed if asked), click Generate Secret, and save the secret. Keycard sends it as client_secret_post, so the JWT and TLS certificate methods don’t work.
    • Under Redirect URIs, add https://<zone-id>.keycard.cloud/oauth/2/redirect, the only redirect URI sign-in needs.
    • For the grant type, select Authorization Code.
    • In OpenID Connect Policy, select the policy from the previous step, or leave the default if you marked it as the default.
    • Select Bypass Authorization Approval, so PingFederate doesn’t show its own approval page before returning Users to Keycard.
    • If you select Restrict Common Scopes, allow openid, profile, and email, plus any scope under Additional Scopes in Keycard.

    The client works whether or not it requires PKCE, because Keycard always sends an S256 challenge. It needs no sign-out redirect URI, because single logout is off by default and Console doesn’t offer it. If you turn it on through the Keycard API (protocols.openid.single_logout_enabled), also allow https://<zone-id>.keycard.cloud/openid/connect/redirect/logout as a sign-out redirect on the client. Click Save.

Keep the Client ID and secret at hand for the next phase.

  1. In Keycard Console, go to Zones, open the ⋯ menu on your Zone’s card, and select Switch to zone. Keycard creates a Provider in the Zone you’re working in, and a Provider created in another Zone never appears in this Zone’s sign-in settings. If Switch to zone is missing and you aren’t already working in that Zone, you don’t have access to it yet. Creating a Provider takes Manager access; see Assign Zone Admin Access.

  2. Select Providers in the navigation menu, then click Add Provider.

  3. In the Name field, enter “PingFederate” or “PingOne”.

  4. In the Issuer URL field, enter the issuer value from your Ping discovery document, character for character, including any trailing slash. Keycard doesn’t check it when you save, so a mismatch shows up later as a failed sign-in.

    The issuer is your PingFederate Base URL, for example https://<pingfederate-host>, as shown in https://<pingfederate-host>/.well-known/openid-configuration. A port or a virtual issuer changes the value.

  5. In the Client ID and Client Secret fields, enter the values from Ping. Enter both, even though Console doesn’t require a Client ID.

  6. Leave Advanced options closed for a standard setup; Keycard always requests openid, profile, and email. Add a scope under Additional Scopes only if PingFederate releases groups under its own groups scope, which must also exist in PingFederate. Sign-in doesn’t need offline_access.

  7. Click Create Provider. Console opens the new Provider’s Configuration tab.

You can also create this Provider and select it for the Zone with the Keycard Terraform provider, using keycard_provider and keycard_zone_user_identity_config. Register the Zone’s oauth2.redirect_uri, from the keycard_zone resource or data source, as the redirect URI in Ping. Terraform can’t set Additional Scopes, so a Terraform-built Provider relies on Ping releasing groups without a groups scope.

  1. While you’re working in the Zone, select Settings under Zone in the navigation menu. The Zone configuration page opens.

  2. Select the Settings tab.

  3. In the Zone sign in configuration section, open the Identity Provider dropdown and select your Ping Provider.

  4. Click Save Changes.

Keycard now sends every sign-in to this Zone straight to Ping. The first time a User signs in, Keycard creates that User from Ping’s ID token, and the User then appears on the Zone’s People page.

Keycard reads claims from the ID token Ping returns at sign-in and doesn’t call Ping’s userinfo endpoint.

Claim Required How Keycard uses it
sub Yes Together with the issuer, identifies the User on every later sign-in. Keep its source stable.
email Yes, for a User’s first sign-in Sets the User’s email. Policy reads it as context.subject_claims.email. It must be a single string.
groups No Policy reads it as context.subject_claims.groups.

Only email and groups reach policy as claims, so a department attribute or a group claim under another name never does. A claim you set as User Identifier Claim under Advanced options reaches policy only indirectly, as the identifier (principal.identifier) of each User created at sign-in.

Use the Ping groups claim to bring your Ping groups into policy. Keycard Groups are an alternative that policy reads every time it evaluates, so a membership change applies to the next credential request; see Group-based Policies.

The claim must be a top-level claim named exactly groups, in lowercase, holding a list of strings (a single string counts as a list of one). Keycard records it at sign-in, so a membership change in Ping reaches policy only in sessions that start after the User signs in again, and access tokens Keycard issues carry neither groups nor email. An agent that already holds a refresh token keeps the earlier groups; see What Keycard receives from your identity provider. A rule on the claim guards it, then matches the exact string Ping sends:

permit (
principal is Keycard::User,
action,
resource
) when {
context has subject_claims &&
context.subject_claims has groups &&
context.subject_claims.groups.contains("<group-name>")
};

To try a rule against group values before it goes live, see Test an identity provider groups claim. For the full pattern, see Same agent, different user and Groups versus the IdP groups claim.

Sign-in fails with access_denied: no email address

Keycard creates a User only when the ID token carries an email claim that is a single string. Without one, it stops the sign-in with access_denied and the description “Identity provider did not supply an email address.” It returns the error to the Application when it can, so what the User sees depends on the Application.

  • In PingFederate, select Include User Info in ID Token on the OpenID Connect policy, and keep email in the Attribute Contract, fulfilled and not Multi-Valued. If the policy leaves Include User Info in ID Token cleared, select Override Default Delivery on email and groups and choose ID Token.
  • In PingOne, add an email attribute mapping on the application’s Attribute Mappings tab, or set email to ID Token delivery on the OpenID Connect resource’s Attributes tab.
Sign-in fails before the Ping sign-in page appears
  • Check the Issuer URL first. Keycard reads the discovery document at the Issuer URL, minus any trailing slash, plus /.well-known/openid-configuration, and requires its issuer to equal the Issuer URL exactly. A difference in a trailing slash, a port, or a virtual issuer breaks sign-in, sometimes as an invalid URL error. To confirm, copy authorization_endpoint and token_endpoint from the discovery document into Authorization URL and Token URL under the Provider’s Advanced options. If sign-in then reaches Ping, correct the Issuer URL.
  • A scope is missing if PingFederate returns “The requested scope is invalid, unknown, malformed, or exceeds that which the client is permitted to request.” Check that openid, profile, email, and every scope under Additional Scopes exist in Scope Management, and that the client allows them if it uses Restrict Common Scopes.
Sign-in succeeds at Ping, then fails on the way back to Keycard
  • Keycard sends the client secret in the token request body. In PingFederate, the client must use Client Secret. In PingOne, it must use Client Secret Post; with Client Secret Basic, PingOne answers “Unsupported authentication method”.
A policy that matches on groups never matches
  • Confirm Ping sends a claim named exactly groups in the ID token. In PingFederate, check that groups is in the policy’s Attribute Contract with Multi-Valued selected, and that Attribute Scopes doesn’t hide it behind a scope Keycard doesn’t request.
  • Match the exact strings Ping sends, including case. Group attributes from a directory, such as memberOf, often hold full distinguished names.
  • PingOne allows at most 25 values for a multivalued attribute in an ID token. Above that, it sends [SIZE_LIMIT_EXCEEDED] in place of the list, and group-based policies stop matching for that User.
  • Group membership is recorded at sign-in, so have the User sign in again after a change. An agent that connected before the change keeps the earlier groups for up to 90 days, because its refresh token keeps using the groups from sign-in. Disabling the person stops it; revoking a grant doesn’t. Decode Ping’s ID token, not a Keycard access token, to check the claim.
Sign-in fails for returning Users with a federation subject conflict

Keycard links each User to Ping’s issuer and sub, and refuses the sign-in if Ping starts sending a different sub with the same email for someone who has already signed in. It returns access_denied with the description “We could not sign you in. This sign-in conflicts with an existing account. Contact your administrator.” In PingFederate, this happens when you change the attribute that fulfills USER_KEY or sub, or turn on Pairwise Identifier for a client whose Users have already signed in. Keep the sub source stable once Users exist.

PingOne: sign-in stops at the PingOne sign-on page
  • If PingOne shows an error on its own sign-on page and never returns to Keycard, the environment may be disabled or its license expired. Every Zone sign-in fails until the environment is active again, or the Zone uses a different Provider.
  • If a password you’re sure of is rejected, check that you’re signing in to the environment the Zone uses, not the Administrators environment.