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:
- 
Adds a new
oidc-session-schema-openldap.ldifLDAP schema for optional persistence of subject sessions to OpenLDAP. - 
Updates the
oidc-authz-schema-openldap.ldifLDAP 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=configbranch 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.