Monday, 10 April 2017

Updating SAML Service Provider keys for Shibboleth IdsP

SAML Service Providers (SPs) maintain one or more key pairs for use when interacting with Identity Providers (IdPs). The public part of these key pairs are distributed to IdP via SAML metadata or otherwise.
SP keys are used for two purposes:
  1. The SP uses them to sign authentication requests
  2. IdP use them to encrypt attribute assertions in responses for decryption by the SP (encryption is optional, but commonly enabled)

Keys need to be replaced occasionally. This can be difficult to achieve without service disruption because the public parts are distributed and it's impractical to update all copies simultaneously. For a Shibboleth IdP, coping with replacement of an SP key used for signing isn't problematic -- a new key can be added to the SP's metadata ahead of deployment and the IdP will be happy with signatures made with either. However once two keys appear in the metadata the IdP may use either to encrypt assertions and this will only work if the SP is happy to perform decryption with either key.
For Shibboleth SPs this isn't a problem, because they can be configured to accept multiple keys for decrypting assertions while using a nominated key for creating signatures. There's a well known procedure for rotating the key on such a SP, see for example documentation on the UK federation site and in the Shiboleth Consortium Wiki. This amounts to:
  • Create new key pair on the SP
  • Configure the SP to accept either key for decryption but not use the new one for signing (by adding the new one with use="encryption")
  • Add the new key to the SPs metadata for both use="signing" and use="encryption" (or just without a 'use' attribute)
  • Wait for the metadata to propagate, or directly update all IdPs
  • Switch the SP to use the new key for signatures (by removing use="encryption" from the new one and adding it to the old one)
  • Completely remove the old key from the SPs metadata
  • Wait for the metadata to propagate, or directly update all IdPs
  • Remove the old key from the SP configuration
Some SPs don't support this. However it is only encryption that causes a problem. The main reason for encrypting assertions is to prevent users seeing what the IdP is saying about them, but in man cases there's nothing in the assertions that the user can't see by other means. So temporarily disabling encryption while rolling a SP key is a possibility. This means that the key can be rolled without downtime with the following revised procedure:
  • Setup custom relying party on the IdP for the SP that suppresses encryption. Something like this:
<rp:RelyingParty id="<SP entityID>"
   provider="<IdP entityID>"
   defaultSigningCredentialRef="IdPCredential" >

   <rp:ProfileConfiguration xsi:type="saml:SAML2SSOProfile" 
       encryptAssertions="never" 
       encryptNameIds="never" />

 </rp:RelyingParty>
  • Add the new key to the SP's metadata
  • Wait for the metadata to propagate, or just update all IdPs.
  • Switch the SP to use the new key
  • Remove old key from metadata
  • Wait for the metadata to propagate, or just update all IdPs.
  • Remove the custom relying party configuration
Note that this requires coordinated work on every IdP with which the SP works so it's not practical on a large scale. It will however work where there's essentially a one-to-one SP -> IdP relationship, as in many SaaS scenarios.

Tools such as the Firefox SAML tracer, the Chrome SAML Dev Tool extension and the SAML Chrome panel are  really helpful for checking that each step of the process has completed before moving in to the next.