Freshservice

This information was last reviewed in January, 2019, by Scott Cantor.

Change Log:

This is not a replacement for the actual documentation and you cannot cut and paste your way to a working system. The examples are not usable without taking into consideration your local needs and requirements.

This is a page for documenting Shibboleth integration with Freshservice.

The official, quite limited, but mostly accurate, documentation is at https://support.freshservice.com/support/solutions/articles/193635-single-sign-on-for-freshservice-using-saml

Identity Provider Metadata

The GUI for Freshservice has a small set of options to manually configure the IdP details, and it does not support metadata in any way. The options are limited to the IdP's SingleSignOnService endpoint (https://hostname/idp/profile/SAML2/Redirect/SSO), a proprietary logout redirect (not SAML), and (oddly) the SHA-256 fingerprint of the IdP's signing certificate.

You can get your signing certificate's fingerpring via:

$ openssl x509 -fingerprint -sha256 -inform pem -in idp/credentials/idp-signing.crt

It's unknown how the service would handle an expired certificate.

Service Provider Metadata

The service doesn't supply metadata, or much documentation on what you need to use, so tracing of messages was required to deduce some of it, but it's pretty limited.

Example metadata created by hand
  <EntityDescriptor entityID="https://yoursite.freshservice.com">
    <SPSSODescriptor
      protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
      <Extensions>
        <mdui:UIInfo>
          <mdui:DisplayName xml:lang="en">Freshservice</mdui:DisplayName>
        </mdui:UIInfo>
      </Extensions>
      <AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
        Location="https://yoursite.freshservice.com/login/saml" index="1"
        isDefault="true"/>
    </SPSSODescriptor>
  </EntityDescriptor>

Profile Requirements

Encryption is not supported. Only a proprietary logout redirect is supported, not SAML's logout profile.

Their requests also unilaterally specify a <NameIDPolicy> element with an email-based Format, so the IdP must be configured to support that or the request will fail (mentioned again below).

Example Shibboleth Configuration

Refer to the RelyingPartyConfiguration topic and be cognizant that creating overrides for every service is generally an inefficient use of the software. Consider identifying common requirements across services and create overrides tied to multiple services that share those requirements, or that reference profile configuration beans containing common settings.

Required Profile Configurations

SAML2.SSO

See SecurityConfiguration for examples of disabling encryption.

Account Provisioning

According to the documentation and my exchanges with their staff, the system does automatic account creation with no limitations, granting basic access to the application as a user, and that can't be prevented or disabled.

NameID Requirements

It assumes email-based identification of users via the standard <NameID> format of urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress, which it requests explicitly at runtime. The IdP must therefore provide that in its response.

Example Shibboleth Configuration

Refer to the NameIDGenerationConfiguration topic for a full treatment of NameID features.

Continuing with the example above, if you have an attribute definition named "mail" produced by your AttributeResolverConfiguration, release it to the app in your AttributeFilterConfiguration (example below).

Finally, to actually produce the necessary <NameID>, modify saml-nameid.xml as shown:

Example saml-nameid.xml changes
	<!-- SAML 2 NameID Generation -->
	<util:list id="shibboleth.SAML2NameIDGenerators">

		<ref bean="shibboleth.SAML2TransientGenerator" />

		<!--
		<ref bean="shibboleth.SAML2PersistentGenerator" />
		-->

		<!--
		Add custom support for mail-based NameID, assumes you've released
		the source attribute (mail) to any SPs expecting to get it.
		-->
		<bean parent="shibboleth.SAML2AttributeSourcedGenerator"
			p:format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
			p:attributeSourceIds="#{ {'mail'} }" />

	</util:list>
Example attribute-filter.xml changes
	<AttributeFilterPolicy id="Datadog">
		<PolicyRequirementRule xsi:type="Requester" value="https://yoursite.freshservice.com" />

		<AttributeRule attributeID="mail" permitAny="true" />
	</AttributeFilterPolicy>

Attribute Requirements

Freshservice supports a number of SAML Attributes, but only with proprietary names. I did not test any of that support.

Other Considerations

It appears to offer back-door access if SSO breaks via /login/normal.