Skip to main content

Configure SSO

We offer several options when configuring SSO (Single Sign-On).

Configure LDAP as SSO

View the list of LDAP properties. Here's a sample snippet containing server, users and groups to put in your configuration file.

platform-config.yaml
sso:
ldap:
- name: "LDAP" # Custom name for LDAP connection
server: "ldap://openldap:1389" # LDAP server URI with port
managerDn: "cn=admin,dc=example,dc=org" # Bind DN
managerPassword: "adminpassword" # Bind password
search-subtree: true # Search subtree (default: true)
search-base: "ou=users,dc=example,dc=org" # Base DN to search for users
search-filter: "(uid={0})" # Search filter (default: "(uid={0})")
groups-enabled: true # Enable group membership (default: false)
groups-base: "ou=groups,dc=example,dc=org" # Base DN to search for groups
groups-filter: "(member={0})" # Filter on groups (default: "uniquemember={0}")
groups-attribute: "cn" # Group name entry (default: "cn")
note

If your LDAP server is Active Directory and you get an "invalid user" error when trying to log in, try setting your search-filter to '(sAMAccountName={0})'.

User mapping

Here is the mapping between LDAP user's information and Conduktor Console:

LDAPConduktor Console
uidUser ID, used to log in
mail or emailUser email (The only mandatory field)
cnUser name
snUser family name
givenNameUser first name
displayNameUser display name

Groups

To retrieve the groups each user belongs to, you have to set groups-enabled to true, and populate the attributes groups-base and groups-filter.

Note that depending on your LDAP objectClass, the attribute used to filter groups might be changed. For example:

LDAP objectClassConduktor groups-filter
groupOfNames"member={0}"
groupOfUniqueNames"uniqueMember={0}"
Map to external groups

Now that your configuration is finished, you can set up a mapping between your LDAP groups and your Console groups. That way, when a user logs in, they will be automatically added to the corresponding Console groups, based on their LDAP groups.

To create this mapping, you have to create a group from Console, and mention the ID of the group on your LDAP (you should find it in the attribute you mentioned as groups-base).

After the user logged in, we can see they've been added to the group, without any action:

Configure LDAPS certificate

For LDAPs (LDAP over SSL) connection, you have to provide a trusted certificate using Java JKS TrustStore file. See SSL/TLS configuration for more details.

LDAPS SSL certificate can also be passed as PEM encoded string using the property sso.trustedCertificates.

platform-config.yaml
sso:
ignoreUntrustedCertificate: false
trustedCertificates: |
-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----

Configure Auth0 as SSO

View the list of Auth0 properties.

On Auth0 side, you'll have to create a new application:

  1. Create a regular web application:

    Auth01
  2. Get the client ID, client secret and domain:

    Auth02
  3. Configure the callback URI.nThe redirect URI can be something like: http(s)://<Console host>(:<Console port>)/oauth/callback/<OAuth2 config name>. For example, if you deployed Console locally using the name auth0 in your configuration file, you can use http://localhost:8080/oauth/callback/auth0.

Define connection

Remember to specify how you want to connect using the Connections tab of your Auth0 application.

Configure Console

On the Console side, you can add the snippet below to your configuration file. Replace the client ID, client secret and domain with values from step 2 above.

platform-config.yaml
sso:
oauth2:
- name: "auth0"
client-id: "<client ID>"
client-secret: "<client secret>"
openid:
issuer: "https://<domain>"

Configure Amazon Cognito as SSO

On Amazon Cognito side, you'll have to create a user pool with an application:

  1. Create a new user pool

  2. Configure the application client. You can select the name you want, shown here as Conduktor Console and enter the redirect URI as the following: http(s)://<Console host>(:<Console port>)/oauth/callback/<OAuth2 config name>. For example, if you deployed Console locally using the name cognito in your configuration file, you can use http://localhost:8080/oauth/callback/cognito.

Make sure that a client secret will be generated - select Confidential client.

  1. Set the scopes profile, email and openid in the Advanced app settings:

  1. Get the user pool ID, client ID, and client secret, that you'll use in the configuration file of Console

note

You can find the .well-known at: https://cognito-idp.<region>.amazonaws.com/<user pool ID>/.well-known/openid-configuration.

Configure Console

On Console side, you can add the snippet below to your configuration file. You have to replace the client ID, client secret, region, and pool ID, with what you got during step 4.

platform-config.yaml
sso:
oauth2:
- name: "cognito"
client-id: "<client ID>"
client-secret: "<client secret>"
openid:
issuer: "https://cognito-idp.<region>.amazonaws.com/<user pool ID>"

Configure groups

If you want to use the external groups mapping to map groups between your Conduktor Console instance and Amazon Cognito, you must set the property groups-claim to "cognito:groups" in Console configuration file. Below is the full snippet for your configuration file:

platform-config.yaml
sso:
oauth2:
- name: "cognito"
client-id: "<client ID>"
client-secret: "<client secret>"
groups-claim: "cognito:groups"
openid:
issuer: "https://cognito-idp.<region>.amazonaws.com/<user pool ID>"
Map to external groups

Now that your configuration is finished, you can setup the mapping between Amazon Cognito and Console groups. That way, when a user logs in, they will be automatically added to the corresponding Console groups, based on the groups they belong to in Amazon Cognito.

The value you need to put as an external group is the Object ID of the Amazon Cognito group.

Configure Entra ID as SSO

On the Entra ID (formerly Azure Active Directory) side, you'll have to create a new application:

  • Step 1: Create a new application in App registrations and set the callback URI

You can select the name you want, shown here as Conduktor Console, and enter the redirect URI as the following: http(s)://<Console host>(:<Console port>)/oauth/callback/<OAuth2 config name>.

For example, if you deployed Console locally using the name azure in your configuration file, you can use http://localhost:8080/oauth/callback/azure, like on the screenshot below.

For more details on Console redirect URI for OAuth2, you can check the documentation.

  • Step 2: Create a new client secret from the Certificates and secrets tab

warning

You need to keep the Value somewhere safe, as you will not have access to it again.

  • Step 3: Find the client ID and tenant ID in the Overview tab

note

You can find the .well-known at: https://login.microsoftonline.com/<tenant ID>/v2.0/.well-known/openid-configuration.

Configure Console

On Console side, you can add the snippet below to your configuration file. You have to replace the client ID, client secret, and tenant ID, with what you got during steps 2 and 3.

platform-config.yaml
sso:
oauth2:
- name: "azure"
client-id: "<client ID>"
client-secret: "<client secret>"
openid:
issuer: "https://login.microsoftonline.com/<tenant ID>/v2.0"

Configure groups

If you want to use the external groups mapping to map groups between your Conduktor Console instance and Azure, you must add this claim to your Azure application in the Token configuration tab:

warning

If you have a large number of groups within your enterprise, you might need to assign some groups to the application, and check the Groups assigned to the application box when creating the groups claim on Azure AD. This is to avoid exceeding the limit on the number of groups a token can contain.

Then, you must set the property groups-claim to "groups" in the Console configuration file. Below is the full snippet for your configuration file:

platform-config.yaml
sso:
oauth2:
- name: "azure"
client-id: "<client ID>"
client-secret: "<client secret>"
groups-claim: "groups"
openid:
issuer: "https://login.microsoftonline.com/<tenant ID>/v2.0"
Map to external groups

Now that your configuration is finished, you can set up the mapping between Azure AD and Console groups. That way, when a user will log in, they will be automatically added to the corresponding Console groups, based on the groups they belong to in Azure AD.

The value you need to put as an external group is the Object ID of the Azure AD group.

Configure Google as SSO

On Google side:

  • Step 1: Create an application on the OAuth consent screen tab

The scopes needed are email, profile, and openid. Optionally, you need https://www.googleapis.com/auth/cloud-identity.groups.readonly for External Group Mapping.

Google Scopes
  • Step 2: Restrict access to your internal workspace by checking the Internal user type in the OAuth consent screen.
Google Users type internal
  • Step 3: Create a new OAuth client ID

You can select the name you want, shown here as Conduktor Console, and enter the redirect URI as the following: http(s)://<Console host>(:<Console port>)/oauth/callback/<OAuth2 config name>.

For example, if you deployed Console locally using the name google in your configuration file, you can use http://localhost:8080/oauth/callback/google, like on the screenshot below.

For more details on Console redirect URI for OAuth2, you can check the documentation.

Google Create Client
  • Step 4: Get the client ID and the secret ID

After the creation, the pop-up below appears. You can save the client ID and secret as JSON if you want.

Google Client ID Secret
info

If you need to add an authorized domain to your Google account, you can follow this guide.

Configure Console

On Console side, you can add the snippet below to your configuration file. You have to replace the client ID and secret with what you got during the step 4.

platform-config.yaml
sso:
oauth2:
- name: "google"
client-id: "<client ID>"
client-secret: "<client secret>"
scopes: "openid,email,profile"
openid:
issuer: "https://accounts.google.com"

Configure groups

An additional scope https://www.googleapis.com/auth/cloud-identity.groups.readonly is required if you want to sync Google Group with Conduktor Groups.

platform-config.yaml
sso:
oauth2:
- name: "google"
client-id: "<client ID>"
client-secret: "<client secret>"
scopes: "openid,email,profile,https://www.googleapis.com/auth/cloud-identity.groups.readonly"
openid:
issuer: "https://accounts.google.com"
Map to external groups

Now that your configuration is finished, you can set up the mapping between Google Groups and Console groups. That way, when a user logs in, they will be automatically added to the corresponding Console groups, based on the groups they belong to in Google.

The value you need to put as an external group is the email address of the Google Group.

Configure JumpCloud as SSO

On the JumpCloud side, you'll have to create a new application:

  • Step 1: Create a new application in SSO Applications.

  • Step 2: Select a Custom Application as shown below.

Then ensure to select Manage Single Sign-On (SSO), then Configure SSO with OIDC and Export users to this app (Identity Management) as seen in the screenshot below.

Following this, enter general information for your custom application, including the display label, such as conduktor as seen in the screenshot below and configure this application.

  • Step 3: Add Redirect URI(s) and Login URL.

The Redirect URI is where JumpCloud sends the authentication response and ID token for the user's sign-in request to. The Login URL is the URL users need to log into this application.

Enter the redirect URI in the following way:

http(s)://<Console host>:<Console port>/oauth/callback/<OAuth2 config name>.

For example, if you deployed Console locally using the name jumpcloud in your configuration file, you can use https://localhost:8080/oauth/callback/jumpcloud, as seen in the screenshot below.

Enter the Login URL, which is the URL users need to log into this application. In the example below, this is https://localhost:8080 .

  • Step 4: Find the Client ID and Client Secret.

After clicking activate during Step 3 you will be shown configurations for Client ID and Client Secret, be sure to save these somewhere safe.

JumpCloud client ID secret
warning

You need to keep the Client Secret somewhere safe, as you will not have access to it again.

Configure Console

On the Conduktor Console side, you can add the snippet below to your configuration file. You will have to replace the Client ID and Client Secret, as shown in steps 3 and 4.

note

You can find the opendid issuer at: https://oauth.id.jumpcloud.com/ as shown here

platform-config.yaml
sso:
oauth2:
- name: "jumpcloud"
client-id: "<Client ID>"
client-secret: "<Client Secret>"
groups-claim: "groups" #if wanting to use groups mapping
openid:
issuer: "https://oauth.id.jumpcloud.com/"

Or using environment variables:

CDK_SSO_OAUTH2_0_NAME="jumpcloud"
CDK_SSO_OAUTH2_0_DEFAULT=true
CDK_SSO_OAUTH2_0_CLIENT-ID="<Client ID>"
CDK_SSO_OAUTH2_0_CLIENT-SECRET="<Client Secret>"
CDK_SSO_OAUTH2_0_GROUPS-CLAIM="groups"
CDK_SSO_OAUTH2_0_OPENID_ISSUER="https://oauth.id.jumpcloud.com/"

Configure groups

If you want to use the external groups mapping to map groups between your Conduktor Console instance and JumpCloud:

From the JumpCloud side, ensure you have:

  • Checked Email and Profile under the standard scopes
  • Set the email_verified to true
  • The same value in group attribute as in the groups-claim or CDK_SSO_OAUTH2_0_GROUPS-CLAIM value of your Console's configuration

See the example screenshot shown below.

From the Conduktor Console side, you must set the property groups-claim to "groups" in the Console configuration file. Below is the full snippet for your configuration file:

platform-config.yaml
sso:
oauth2:
- name: "jumpcloud"
client-id: "<Client ID>"
client-secret: "<Client Secret>"
groups-claim: "groups"
openid:
issuer: "https://oauth.id.jumpcloud.com/"

Or using environment variables:

CDK_SSO_OAUTH2_0_NAME="jumpcloud"
CDK_SSO_OAUTH2_0_DEFAULT=true
CDK_SSO_OAUTH2_0_CLIENT-ID="<Client ID>"
CDK_SSO_OAUTH2_0_CLIENT-SECRET="<Client Secret>"
CDK_SSO_OAUTH2_0_GROUPS-CLAIM="groups"
CDK_SSO_OAUTH2_0_OPENID_ISSUER="https://oauth.id.jumpcloud.com/"
Map to external groups

Now that your configuration is finished, you can set up the mapping between JumpCloud and Conduktor Console groups. This way, when a user logs in, they will be automatically added to the corresponding Conduktor Console groups, based on the groups they belong to in JumpCloud.

The value you need to put as an external group is the name of the JumpCloud group.

Configure Keycloak as SSO

On Keycloak side, you'll have to create a new application:

  • Step 1: create a new OpenID Connect client, and set the client ID

  • Step 2: Select the Client authentication

  • Step 3: Configure the redirect URI

You can configure it as the following: http(s)://<Console host>(:<Console port>)/oauth/callback/<OAuth2 config name>

For example, if you deployed Console locally using the name keycloak in your configuration file, you can use http://localhost:8080/oauth/callback/keycloak, like in the screenshot below.

For more details on Console redirect URI for OAuth2, you can check the documentation.

  • Step 4: Get the client secret in the Credentials tab

note

You can find the .well-known at: http://<Keycloak host>:<Keycloak port>/realms/<realm name>/.well-known/openid-configuration.

Configure Console

On Console side, you can add the snippet below to your configuration file. You have to replace the client ID, client secret, and tenant ID, with what you got during the previous steps.

platform-config.yaml
sso:
oauth2:
- name: "keycloak"
client-id: "<client ID>"
client-secret: "<client secret>"
openid:
issuer: "http://<Keycloak host>:<Keycloak port>/realms/<realm name>"

Configure groups

If you want to use the external groups mapping to map groups between your Conduktor Console instance and Keycloak, you must create a scope and add it to your Keycloak application:

  • Step 1: Create the scope and configure the mapper to Group Membership

You can add the claim to the token you want. In this example, the UserInfo.

  • Step 2: Add the scope to the application

Then, you must set the property groups-claim to "groups" in the Console configuration file. Below is the full snippet for your configuration file:

platform-config.yaml
sso:
oauth2:
- name: "keycloak"
client-id: "<client ID>"
client-secret: "<client secret>"
groups-claim: "groups"
openid:
issuer: "http://<Keycloak host>:<Keycloak port>/realms/<realm name>"
Map to external groups

Now that your configuration is finished, you can setup the mapping between Keycloak and Console groups. That way, when a user logs in, they will be automatically added to the corresponding Console groups, based on the groups they belong to in Keycloak.

The value you need to put as an external group is the name of the Keycloak group.

warning

If you've selected Full group path in the mapper details of the scope, you will need to use the full path instead of the name of the group.

Configure Okta as SSO

On Okta side, create a new application:

  • Step 1: Create an OpenID Connect web application
Okta create app
  • Step 2: Configure the callback URI

The redirect URI can be like: http(s)://<Console host>(:<Console port>)/oauth/callback/<OAuth2 config name>.

For example, if you deployed Console locally using the name okta in your configuration file, you can use http://localhost:8080/oauth/callback/okta, like in the screenshot below.

For more details on Console redirect URI for OAuth2, you can check the documentation.

Okta callback URI
  • Step 3: Configure app assignments, and save changes
Okta assignments
  • Step 4: Get client ID and client secret, that you'll use in the configuration file of Console
Okta client ID secret
  • Step 5: Find the issuer URL in the Sign On tab of your application. It's made like https://<domain>.okta.com
Okta issuer
note

You can find the .well-known at: https://<domain>.okta.com/.well-known/openid-configuration.

Configure Console

On the Console side, you can add the snippet below to your configuration file. You have to replace the client ID, client secret and domain, with what you got during steps 4 and 5.

platform-config.yaml
sso:
oauth2:
- name: "okta"
client-id: "<client ID>"
client-secret: "<client secret>"
openid:
issuer: "https://<domain>.okta.com"
note

Please note that if you are using a custom auth server in Okta, the OPENID_ISSUER should be in the form https://<yourOktaDomain>/oauth2/<authorizationServerId>/ rather than https://<domain>.okta.com. Find out more about token customization.

Configure an OIDC/OAuth2 provider as SSO

Conduktor supports various OIDC (OpenID Connect) providers, including:

For others, follow these generic steps.

  1. Create an OIDC (OpenID Connect) application in your chosen provider. This application should use standard OAuth2/OIDC authorization code flow with CLIENT_SECRET_BASIC authentication method.

  2. Set OAuth2 authorized redirect URI in your application

For the OAuth2 authorization code flow to work, the OAuth2 provider needs to know; and authorize; where to redirect the user after the authentication process. This is called the redirect URI or callback URI.

The redirect URI will look like this:
http(s)://<Console host>(:<Console port>)/oauth/callback/<OAuth2 config name>

Where <Console host> and <Console port> depend on the Console external URL used and/or configured, and <OAuth2 config name> is the name of the OAuth2 configuration in your Console configuration file see Console configuration step.

More details on Console external URL

When Console initiate the OAuth2 authorization code flow, it tells the OIDC provider where to redirect the user after the authentication process.

But to forge this redirect URI, Console has several choices:

Console external URL is configured

If the Console external URL is configured using environment variable CDK_PLATFORM_EXTERNAL_URL or configuration platform.external.url, it will use it.
But SSO will work ONLY if Console is accessed using this URL. If you try to log in from the second URL you will be redirected to the first URL and then lose browser authentication cookies meaning the SSO will not work.

Console external URL is NOT configured

When no external Console URL is enforced, Console will use requests headers to resolve this external URL. This is recommended if Console is accessed using multiple URLs (internal, external, etc) and have SSO on each of them.

The resolution strategy is the following:

  1. Use the Forwarded header. This is the preferred method if you are using a reverse proxy in front of Console. It uses the host and proto directives (if set) of Forwarded header to determine the external URL.
  2. Use the X-Forwarded-* headers. Support for the non-standard forwarded headers coming from some reverse proxy implementations. It uses the X-Forwarded-Proto, X-Forwarded-Host and X-Forwarded-Port headers to determine the external URL.
  3. Use the Host header. Used if you access to Console directly, without a reverse proxy. In this case, the Host header (generally set by the browser) will be used to determine the external URL.
note

Port will be guessed depending on the content of the Host header and fallback to Console configured port using environment variable CDK_LISTENING_PORT (default to 8080).
Scheme (http/https) will be guessed depending on the current TLS configuration of Console. See TLS configuration for more details. (default to http).

  1. Get the client ID and secret from application settings

Configure Console

On Console side, you need to configure several properties to enable OIDC SSO.

Required properties are:

  • sso.oauth2.name: the name of the OAuth2 configuration. This name will be used in the redirect URI defined on your provider in the steps before. It must be unique.
  • sso.oauth2.client-id: the client ID of your OAuth2 application.
  • sso.oauth2.client-secret: the client secret of your OAuth2 application.
  • sso.oauth2.openid.issuer: the issuer URL of your OpenID Connect provider. This url is used to discover the provider configuration using the .well-known/openid-configuration path.

Optionally, you can configure the following properties:

Example

The provider exposes its configuration using the well-known endpoint: https://<oidc domain>/.well-known/openid-configuration. Here's an example of a configuration file for a generic OIDC provider.

platform-config.yaml
sso:
oauth2:
- name: "oidc-provider"
client-id: "<client ID>"
client-secret: "<client ID>"
openid:
issuer: "https://<oidc domain>/"

SSO config properties

PropertyDescriptionEnvironment variableMandatoryTypeDefault
sso.ignoreUntrustedCertificateDisable SSL checksCDK_SSO_IGNOREUNTRUSTEDCERTIFICATEfalsebooleanfalse
sso.trustedCertificatesSSL public certificates for SSO authentication (LDAPS and OAuth2) as PEMCDK_SSO_TRUSTEDCERTIFICATESfalsestring

OAuth2 config properties

PropertyDescriptionEnvironment variableMandatoryTypeDefault
sso.oauth2[].nameOAuth2 connection nameCDK_SSO_OAUTH2_0_NAMEtruestring
sso.oauth2[].defaultUse as defaultCDK_SSO_OAUTH2_0_DEFAULTtrueboolean
sso.oauth2[].client-idOAuth2 client IDCDK_SSO_OAUTH2_0_CLIENTIDtruestring
sso.oauth2[].client-secretOAuth2 client secretCDK_SSO_OAUTH2_0_CLIENTSECRETtruestring
sso.oauth2[].openid.issuerIssuer to check on tokenCDK_SSO_OAUTH2_0_OPENID_ISSUERtruestring
sso.oauth2[].scopesScopes to be requested in the client credentials requestCDK_SSO_OAUTH2_0_SCOPEStruestring[]
sso.oauth2[].groups-claimGroup attribute from your identity providerCDK_SSO_OAUTH2_0_GROUPSCLAIMfalsestring
sso.oauth2[].username-claimEmail attribute from your identity providerCDK_SSO_OAUTH2_0_USERNAMECLAIMfalsestringemail
sso.oauth2[].allow-unsigned-id-tokensAllow unsigned ID tokensCDK_SSO_OAUTH2_0_ALLOWUNSIGNEDIDTOKENSfalsebooleanfalse
sso.oauth2[].preferred-jws-algorithmConfigure preferred JWS algorithmCDK_SSO_OAUTH2_0_PREFERREDJWSALGORITHMfalsestring one of: "HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "ES256", "ES256K", "ES384", "ES512", "PS256", "PS384", "PS512", "EdDSA"
sso.oauth2-logoutWether the central identity provider logout should be called or notCDK_SSO_OAUTH2LOGOUTfalsebooleantrue

LDAP config properties

PropertyDescriptionEnvironment variableMandatoryTypeDefault
sso.ldap[].nameLdap connection nameCDK_SSO_LDAP_0_NAMEtruestring
sso.ldap[].serverLdap server host and portCDK_SSO_LDAP_0_SERVERtruestring
sso.ldap[].managerDnSets the manager DNCDK_SSO_LDAP_0_MANAGERDNtruestring
sso.ldap[].managerPasswordSets the manager passwordCDK_SSO_LDAP_0_MANAGERPASSWORDtruestring
sso.ldap[].search-subtreeSets if the subtree should be searched.CDK_SSO_LDAP_0_SEARCHSUBTREEfalsebooleantrue
sso.ldap[].search-baseSets the base DN to search.CDK_SSO_LDAP_0_SEARCHBASEtruestring
sso.ldap[].search-filterSets the search filter. By default, the filter is set to (uid={0}) for users using class type InetOrgPerson.CDK_SSO_LDAP_0_SEARCHFILTERfalsestring"(uid={0})"
sso.ldap[].search-attributesSets the attributes list to return. By default, all attributes are returned. Platform search for uid, cn, mail, email, givenName, sn, displayName attributes to map into user token.CDK_SSO_LDAP_0_SEARCHATTRIBUTESfalsestring array[]
sso.ldap[].groups-enabledSets if group search is enabled.CDK_SSO_LDAP_0_GROUPSENABLEDfalsebooleanfalse
sso.ldap[].groups-subtreeSets if the subtree should be searched.CDK_SSO_LDAP_0_GROUPSSUBTREEfalsebooleantrue
sso.ldap[].groups-baseSets the base DN to search from.CDK_SSO_LDAP_0_GROUPSBASEtruestring
sso.ldap[].groups-filterSets the group search filter. If using group class type GroupOfUniqueNames use the filter "uniqueMember={0}". For group class GroupOfNames use "member={0}".CDK_SSO_LDAP_0_GROUPSFILTERfalsestring"uniquemember={0}"
sso.ldap[].groups-filter-attributeSets the name of the user attribute to bind to the group search filter. Defaults to the user’s DN.CDK_SSO_LDAP_0_GROUPSFILTERATTRIBUTEfalsestring
sso.ldap[].groups-attributeSets the group attribute name. Defaults to cn.CDK_SSO_LDAP_0_GROUPSATTRIBUTEfalsestring"cn"
sso.ldap[].propertiesAdditional properties that will be passed to identity provider context.CDK_SSO_LDAP_0_PROPERTIESfalsedictionary