How to update the OpenLDAP schema for Connect2id server 6.x

This is an instruction how to update the LDAP schema from a Connect2id server 4.x or 5.x installation to Connect2id server 6.x if an OpenLDAP directory backend is used.

1. The schema changes

Summary of the schema changes from v4.x and 5.x:

  1. Adds a new oidc-session-schema-openldap.ldif LDAP schema for optional persistence of subject sessions to OpenLDAP.

  2. Updates the oidc-authz-schema-openldap.ldif LDAP schema for optional
    persistence of identifier-based access tokens and token revocation events.

Existing data stored by Connect2id server v4.x or 5.x in OpenLDAP is forward-compatible with Connect2id server v6.x and can continue to be used as it is.

The LDAP schemas for the Connect2id server are made available in a dedicated Git repo. The versions map as follows:

  • Connect2id server 2.x: LDAP schema version 1.0
  • Connect2id server 3.x: LDAP schema version 1.4
  • Connect2id server 4.x: LDAP schema version 1.5
  • Connect2id server 5.x: LDAP schema version 1.5
  • Connect2id server 6.x: LDAP schema version 1.8

2. The on-line configuration in OpenLDAP

OpenLDAP uses on-line configuration (OLC) to enable schema changes with zero downtime. This is facilitated by storing the configuration in a special directory tree at the cn=config root, which may be viewed and modified with a regular LDAP client / browser.

3. Accessing the schema

Access to the cn=config directory tree requires administrator permissions and can be facilitated in two ways:

  • From the command line on the OpenLDAP server host: from a superuser account (e.g. via sudo).

  • Remotely from an LDAP client by making a connection to the OpenLDAP server: with the admin DN and password credentials; these are typically set up by the administrator when the OpenLDAP directory is created.

If you're using a generic LDAP client, such as Apache Directory Studio, the connection must be authenticated with the root DN and password, and the cn=config tree must be specified (otherwise the client will connect to the default data tree).

4. Instructions

Important: We suggest you first try the Try this first on a test or development LDAP directory. Proceed with production when you're sure the upgrade works correctly and there are no issues with your particular OpenLDAP setup.

Step 1: Add new schema for subject sessions

To add the new schema for optional persistence of subject (end-user) sessions make the following command on the OpenLDAP server host:

sudo ldapadd -Y EXTERNAL -H ldapi:/// -f oidc-session-schema-openldap.ldif

Download link: oidc-session-schema-openldap.ldif

Step 2: Locate the authorisations schema

Before we can update the authorisations schema we must find out its DN (location) on the cn=schema, cn=config directory branch. The schema names are prefixed by a number, such as {1}, to set their precedence when the OpenLDAP server loads them (in case they have dependent attributes).

  • From the command line on the OpenLDAP host:

    sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config '(cn=*oidcAuthz)' dn
    
  • If you're using a remote LDAP connection make a search request under the cn=schema,cn=config branch using the (cn=*oidcAuthz) filter.

Write down the search result, that is, the DN of the OpenID Connect authorisation records schema, e.g.

cn={5}oidcAuthz,cn=schema,cn=config

Step 3. Update the authorisation attributes schema

Apply the following LDIF file to update the authorisation attributes schema.

Remember to replace the dn: cn={5}oidcAuthz... with the actual DN of the authorisation schema that you recorded above!

dn: cn={5}oidcAuthz,cn=schema,cn=config
changetype: modify
replace: olcAttributeTypes
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.1 NAME 'authzAccessToken' 
        DESC 'OAuth 2.0 access token' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.28 NAME 'authzAccessTokenIssueDate'
        DESC 'Access token issue date'
        EQUALITY generalizedTimeMatch
        ORDERING generalizedTimeOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.2 NAME 'authzAccessTokenLifetime' 
        DESC 'OAuth 2.0 access token lifetime, in seconds' 
        EQUALITY integerMatch 
        ORDERING integerOrderingMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.3 NAME 'authzAccessTokenEncoding'
        DESC 'OAuth 2.0 access token encoding'
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.23 NAME 'authzAccessTokenEncrypt'
        DESC 'OAuth 2.0 access token encrypt flag'
        EQUALITY booleanMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.4 NAME 'authzRefreshToken'
        DESC 'OAuth 2.0 refresh token'
        EQUALITY caseExactMatch
        ORDERING caseExactOrderingMatch
        SUBSTR caseExactSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.5 NAME ('authzRefreshTokenSecret' 'authzRefreshTokenSalt')
        DESC 'OAuth 2.0 refresh token salt'
        EQUALITY caseExactMatch
        ORDERING caseExactOrderingMatch
        SUBSTR caseExactSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.6 NAME 'authzIssueRefreshToken'
        DESC 'OAuth 2.0 issue refresh token switch' 
        EQUALITY booleanMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.7
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.24 NAME 'authzRefreshTokenLifetime'
        DESC 'OAuth 2.0 refresh token lifetime, in seconds'
        EQUALITY integerMatch
        ORDERING integerOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.25 NAME 'authzRefreshTokenIssueDate'
        DESC 'Refresh token issue date'
        EQUALITY generalizedTimeMatch
        ORDERING generalizedTimeOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.7 NAME 'authzIssuer'
        DESC 'Authorization issuer' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.8 NAME 'authzIssueDate'
        DESC 'Authorization issue date' 
        EQUALITY generalizedTimeMatch 
        ORDERING generalizedTimeOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 
        SINGLE-VALUE
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.9 NAME 'authzUpdateDate'
        DESC 'Authorization issue date'
        EQUALITY generalizedTimeMatch
        ORDERING generalizedTimeOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.10 NAME 'authzSubject'
        DESC 'Authorization subject' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.11 NAME 'authzClientID'
        DESC 'Authorized client' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.12 NAME 'authzAudience'
        DESC 'Authorized audience' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.13 NAME 'authzScopeValue'
        DESC 'Authorized scope value' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.14 NAME 'authzSavedScopeValue'
        DESC 'Saved scope value from a previous authorisation'
        EQUALITY caseExactMatch
        ORDERING caseExactOrderingMatch
        SUBSTR caseExactSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.26 NAME 'authzActor'
        DESC 'Authorized actor in impersonation and delegation cases'
        EQUALITY caseExactMatch
        ORDERING caseExactOrderingMatch
        SUBSTR caseExactSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.15 NAME 'authzData'
        DESC 'Auxiliary authorization data, as JSON object' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.16 NAME 'authzLastAccessDate'
        DESC 'Authorization last access date' 
        EQUALITY generalizedTimeMatch 
        ORDERING generalizedTimeOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 
        SINGLE-VALUE
        USAGE userApplications 
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.27 NAME 'authzRevocationDate'
        DESC 'Authorization revocation date'
        EQUALITY generalizedTimeMatch
        ORDERING generalizedTimeOrderingMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OAuth 2.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.17 NAME 'oidcIDToken'
        DESC 'OpenID Connect ID token' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OpenID Connect 1.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.18 NAME 'oidcClaimName'
        DESC 'Consented OpenID Connect claim name, with optional language tag'
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        USAGE userApplications 
        X-ORIGIN 'OpenID Connect 1.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.19 NAME 'oidcSavedClaimName'
        DESC 'Saved consented OpenID Connect claim name from a previous authorisation, with optional language tag'
        EQUALITY caseExactMatch
        ORDERING caseExactOrderingMatch
        SUBSTR caseExactSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        USAGE userApplications
        X-ORIGIN 'OpenID Connect 1.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.20 NAME 'oidcClaimsLocales'
        DESC 'OpenID Connect claims locales, space separated, by order of preference'
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OpenID Connect 1.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.21 NAME 'oidcPresetUserInfoClaims'
        DESC 'Preset OpenID Connect UserInfo claims, as JSON object' 
        EQUALITY caseExactMatch 
        ORDERING caseExactOrderingMatch 
        SUBSTR caseExactSubstringsMatch 
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        SINGLE-VALUE 
        USAGE userApplications 
        X-ORIGIN 'OpenID Connect 1.0' )
olcAttributeTypes: (  1.3.6.1.4.1.40805.2.1.22 NAME 'oidcSessionID'
        DESC 'Subject session identifier (SID)'
        EQUALITY caseExactMatch
        ORDERING caseExactOrderingMatch
        SUBSTR caseExactSubstringsMatch
        SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
        SINGLE-VALUE
        USAGE userApplications
        X-ORIGIN 'OpenID Connect 1.0' )

To apply the LDIF file from the command on the OpenLDAP host:

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f authz-schema-attributes-update.ldif

The OpenLDAP directory will automatically assign new {xxxx} prefixes to the attributes.

Step 4. Update the authorisation object classes schema

Apply the following LDIF file to update the authorisation object classes schema.

Remember to replace the dn: cn={5}oidcAuthz... with the actual DN of the authorisation schema that you recorded above!

dn: cn={5}oidcAuthz,cn=schema,cn=config
changetype: modify
replace: olcObjectClasses
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.1 NAME 'oauth2Authz' 
        DESC 'OAuth 2.0 authorization' 
        SUP top 
        STRUCTURAL
        MUST (
              authzSubject $
              authzClientID )
        MAY ( description $ 
              authzAccessToken $
              authzAccessTokenLifetime $
              authzAccessTokenEncoding $
              authzAccessTokenEncrypt $
              authzRefreshToken $
              authzRefreshTokenSecret $
              authzIssueRefreshToken $
              authzRefreshTokenLifetime $
              authzRefreshTokenIssueDate $
              authzIssuer $
              authzIssueDate $
              authzUpdateDate $
              authzAudience $
              authzScopeValue $
              authzSavedScopeValue $
              authzActor $
              authzData $ 
              authzLastAccessDate ) 
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.2 NAME 'oauth2AuthzAux' 
        DESC 'OAuth 2.0 authorization' 
        SUP top 
        AUXILIARY 
        MUST (
              authzSubject $
              authzClientID )
        MAY ( description $
              authzAccessToken $
              authzAccessTokenLifetime $
              authzAccessTokenEncoding $
              authzAccessTokenEncrypt $
              authzRefreshToken $
              authzRefreshTokenSecret $
              authzIssueRefreshToken $
              authzRefreshTokenLifetime $
              authzRefreshTokenIssueDate $
              authzIssuer $
              authzIssueDate $
              authzUpdateDate $
              authzAudience $
              authzScopeValue $
              authzSavedScopeValue $
              authzActor $
              authzData $
              authzLastAccessDate )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.3 NAME 'oidcAuthz' 
        DESC 'OAuth 2.0 / OpenID Connect authorization'
        SUP oauth2Authz 
        STRUCTURAL
        MAY ( oidcIDToken $
              oidcClaimName $
              oidcSavedClaimName $
              oidcClaimsLocales $
              oidcPresetUserInfoClaims $
              oidcSessionID )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.4 NAME 'oidcAuthzAux' 
        DESC 'OAuth 2.0 / OpenID Connect authorization'
        SUP oauth2AuthzAux 
        AUXILIARY 
        MAY ( oidcIDToken $
              oidcClaimName $
              oidcSavedClaimName $
              oidcClaimsLocales $
              oidcPresetUserInfoClaims $
              oidcSessionID )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.5 NAME 'oauth2AuthzRevocation'
        DESC 'OAuth 2.0 authorization revocation'
        SUP top
        STRUCTURAL
        MUST ( authzRevocationDate )
        MAY ( description $
              authzSubject $
              authzActor $
              authzClientID )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.6 NAME 'oauth2AuthzRevocationAux'
        DESC 'OAuth 2.0 authorization revocation'
        SUP top
        AUXILIARY
        MUST ( authzRevocationDate )
        MAY ( description $
              authzSubject $
              authzActor $
              authzClientID )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.7 NAME 'oauth2IdAccessToken'
        DESC 'OAuth 2.0 access token'
        SUP top
        STRUCTURAL
        MUST ( authzAccessToken )
        MAY ( description $
              authzSubject $
              authzClientID $
              authzAccessTokenIssueDate $
              authzAccessTokenLifetime $
              authzIssuer $
              authzAudience $
              authzScopeValue $
              authzActor $
              authzData )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.8 NAME 'oauth2IdAccessTokenAux'
        DESC 'OAuth 2.0 access token'
        SUP top
        AUXILIARY
        MUST ( authzAccessToken )
        MAY ( description $
              authzSubject $
              authzClientID $
              authzAccessTokenIssueDate $
              authzAccessTokenLifetime $
              authzIssuer $
              authzAudience $
              authzScopeValue $
              authzActor $
              authzData )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.9 NAME 'oidcIdAccessToken'
        DESC 'OAuth 2.0 / OpenID Connect access token'
        SUP oauth2IdAccessToken
        STRUCTURAL
        MAY ( oidcClaimName $
              oidcClaimsLocales $
              oidcPresetUserInfoClaims )
        X-ORIGIN 'OAuth 2.0' )
olcObjectClasses: ( 1.3.6.1.4.1.40805.2.2.10 NAME 'oidcIdAccessTokenAux'
        DESC 'OAuth 2.0 / OpenID Connect access token'
        SUP oauth2IdAccessTokenAux
        AUXILIARY
        MAY ( oidcClaimName $
              oidcClaimsLocales $
              oidcPresetUserInfoClaims )
        X-ORIGIN 'OAuth 2.0' )

To apply the LDIF file from the command on the OpenLDAP host:

sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f authz-schema-classes-update.ldif

Step 5. Validate the compliance of the schema after the updates

You can do that with the slapschema utility included with OpenLDAP:

sudo slapschema

Step 6. Create new directory branches

Connect2id server v6.x needs additional directory branches to enable persistence (when required) of identifier-based access tokens, revocation events, subject sessions and subject tracking.

Here is a sample LDIF file to add the needed branches. Replace the o=c2id suffix with the one in your OpenLDAP directory.

dn: ou=idAccessTokens,o=c2id
objectClass: organizationalUnit
objectClass: top
ou: idAccessTokens

dn: ou=revocations,o=c2id
objectClass: organizationalUnit
objectClass: top
ou: revocations

dn: ou=sessions,o=c2id
objectClass: organizationalUnit
objectClass: top
ou: sessions

dn: ou=subjects,o=c2id
objectClass: organizationalUnit
objectClass: top
ou: subjects

Use the ldapadd command line LDAP client (or your favourite LDAP browser) to add the branches specified in the LDIF file:

sudo ldapadd -Q -Y EXTERNAL -H ldapi:/// -f branches.ldif

Step 7. Connect2id server configuration

From Connect2id server v6.x on the LDAP server connection details are set inside the Infinispan configuration:

WEB-INF/infinispan-ldap.xml

The LDAP configuration settings are explained in the general LDAP setup guide.

8. Assistance

If you need assistance with the above, email Connect2id support.

9. Further information

  1. Using on-line configuration with OpenLDAP
  2. Access cn=config with an LDAP browser
  3. Installing OpenLDAP with on-line config
  4. Configuring OpenLDAP