...
So my choice was to investigate what it would take to get the IdP to start with both the private and secret key(s) locked or unconfigured, and change that state at runtime. Somewhat surprisingly, this mostly worked.
Preconditions
This feature is a bit unusual so it's not just a "turn on setting" sort of thing, but something you have to make a few adjustments to the configuration to use. There are two parts to using this:
- Adjust the private and secret key settings to defer availability.
- Enable the unlock-keys webflow to get them installed after startup.
There are two significant risk points, the private key(s) used to sign messages and the secret key(s) used to support client-side session storage. Not every system uses the latter, but client-side storage is the default, so it's typically a factor. There are also private key(s) used to decrypt XML, but the impact of those keys is much less significant, and they don't get much use. Nevertheless, the feature supports unlocking private keys regardless of purpose so if you wanted to leave the decryption keys locked, that's certainly possible.
So how do you do it?
Credential Changes
Normally the configuration of keys and certificates for signing and encryption is found in conf/credentials.xml. To use this feature, it's necessary to move the critical beans defining these credentials out of this file and up into a globally visible place. The recommendation is to use conf/admin/unlock-keys.xml and move the bean(s) you want to "defer" to that file (with a couple of minor adjustments).
The idea is to move the signing and/or encryption beans to this file, and then simply remove the lines referring to the private keys. You simply omit that part, and any such credential will initialize itself with only the certificate "half" in place, but no private key.
Examples are included below.
DataSealer Changes
The secret key component, if it's in use, is normally configured in idp.properties, or in later versions, a separate credentials/secrets.properties file. The change needed here is simply to eliminate the passwords that unlock the keystore and key entry, normally these properties:
Code Block | ||
---|---|---|
| ||
idp.sealer.storePassword = password
idp.sealer.keyPassword = password |
If you remove these lines, or comment them out (prefix with a # character), that automatically kicks the underlying secret key source into a "delayed init" mode that allows it to be unlocked at runtime.
Conditions at Startup
So what happens if you do all this and then start the Java servlet container? By default, it's nothing really noticeable unless you try to login to an SP. The lack of a secret key causes some loud warnings in the log any time the software tries to load or store session data to the client, but it doesn't actually cause a request to fail. The lack of a signing key, however, will cause SAML requests to terminate with an error because of the inability to sign messages. This is not ideal, but it's assumed that if you're using this feature you're aware of what you're doing and you should know that you need to unlock the system before putting it into use.
Unlock Flow
To use this feature, a new administrative flow is provided that has a crude user interface to collect password(s) via a web form and manipulate the system's internals to unlock and install the keys necessary to put the system into a normal state as if the feature hadn't been used. From that point on, the system should behave normally until the next time it restarts.
If the flow believes that it's done this successfully, it records that fact so that if it runs again it simply skips these steps. If it detects a failure, it leaves any remaining work undone and redisplays the form, and the log should usually indicate what didn't work. This is not meant as a fancy GUI for remote use without access to the server and the logs.
...
title | V4.0 |
---|
To get this working, the flow has to be defined and enabled in conf/admin/general-admin.xml, and some Spring beans defined to describe to the flow what it needs to unlock.
Enable the Flow
The following is added to (or uncommented in) the shibboleth.AvailableAdminFlows list bean:
...
language | xml |
---|---|
title | Added to conf/admin/general-admin.xml |
...
Enabling Module (V4.1+)
For V4.1+, configuring and using this feature requires that you first enable the "idp.admin.UnlockKeys" module if it isn't already enabled. Systems upgraded from older releases generally come pre-enabled due to the prior state of the configuration tree.
Code Block |
---|
(Windows)
C:\opt\shibboleth-idp> bin\module.bat -t idp.admin.UnlockKeys || bin\module.bat -e idp.admin.UnlockKeys
(Other)
$ bin/module.sh -t idp.admin.UnlockKeys || bin/module.sh -e idp.admin.UnlockKeys |
Preconditions
This feature is a bit unusual so it's not just a "turn on setting" sort of thing, but something you have to make a few adjustments to the configuration to use. There are two parts to using this:
- Adjust the private and secret key settings to defer availability.
- Enable the unlock-keys webflow to get them installed after startup.
There are two significant risk points, the private key(s) used to sign messages and the secret key(s) used to support client-side session storage. Not every system uses the latter, but client-side storage is the default, so it's typically a factor. There are also private key(s) used to decrypt XML, but the impact of those keys is much less significant, and they don't get much use. Nevertheless, the feature supports unlocking private keys regardless of purpose so if you wanted to leave the decryption keys locked, that's certainly possible.
So how do you do it?
Credential Changes
Normally the configuration of keys and certificates for signing and encryption is found in conf/credentials.xml. To use this feature, it's necessary to move the critical beans defining these credentials out of this file and up into a globally visible place. The recommendation is to use conf/admin/unlock-keys.xml and move the bean(s) you want to "defer" to that file (with a couple of minor adjustments).
The idea is to move the signing and/or encryption beans to this file, and then simply remove the lines referring to the private keys. You simply omit that part, and any such credential will initialize itself with only the certificate "half" in place, but no private key.
Examples are included below.
DataSealer Changes
The secret key component, if it's in use, is normally configured in idp.properties, or in later versions, a separate credentials/secrets.properties file. The change needed here is simply to eliminate the passwords that unlock the keystore and key entry, normally these properties:
Code Block | ||
---|---|---|
| ||
idp.sealer.storePassword = password
idp.sealer.keyPassword = password |
If you remove these lines, or comment them out (prefix with a # character), that automatically kicks the underlying secret key source into a "delayed init" mode that allows it to be unlocked at runtime.
Conditions at Startup
So what happens if you do all this and then start the Java servlet container? By default, it's nothing really noticeable unless you try to login to an SP. The lack of a secret key causes some loud warnings in the log any time the software tries to load or store session data to the client, but it doesn't actually cause a request to fail. The lack of a signing key, however, will cause SAML requests to terminate with an error because of the inability to sign messages. This is not ideal, but it's assumed that if you're using this feature you're aware of what you're doing and you should know that you need to unlock the system before putting it into use.
Unlock Flow
To use this feature, a new administrative flow is provided that has a crude user interface to collect password(s) via a web form and manipulate the system's internals to unlock and install the keys necessary to put the system into a normal state as if the feature hadn't been used. From that point on, the system should behave normally until the next time it restarts.
If the flow believes that it's done this successfully, it records that fact so that if it runs again it simply skips these steps. If it detects a failure, it leaves any remaining work undone and redisplays the form, and the log should usually indicate what didn't work. This is not meant as a fancy GUI for remote use without access to the server and the logs.
Localtabgroup | |||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
...
Reference
Localtabgroup | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Example
In a typical example, the following assumes you want to unlock both the system-supplied secret keystore and the default signing key:
...