This software is not yet released and this is preliminary documentaton subject to significant change. It should not be used in production or to protect important resources at this stage.
DefiningRelyingPartyConfigurations
RelyingPartyConfigurations are used in the Hub’s Agent Resolver service to control what functional profiles are enabled, their settings, and in unusual cases to adjust security configurations such as keys or algorithms. Normally this is all defaulted via a single “default” RelyingPartyConfguration.
Overrides can be used to customize profile behavior based on the specific authenticating authority or some characteristic of it. Requests to the Hub are mapped to a particular Agent and Application, and from there a determination is made as to which RelyingPartyConfguration should apply. Most of the settings needed to fulfil the request will come from either that interface or the contained ProfileConfigurations within it.
This is essentially the same purpose for which they’re used in the IdP’s RelyingPartyConfigurationservice except that in the IdP the “relying party” is usually the SP/RP the IdP is issuing responses to. This is not always true; the IdP’s proxying features sometimes flip that around and in those cases, the semantics align pretty directly to how the Hub uses the concept.
Overview
Within each Application (or more commonly Agents acting as their default Application), there are always:
An “unverified” RelyingPartyConfguration that applies when a request is not secured by some kind of authentication or verification step, usually brokered with SAML Metadata, OIDC Client Information, or similar mechanism. This is commonly applied to cases where information needs to be served publically, which is more typical with OAuth/OIDC (e.g., self-hosted metadata and keyset information).
A “default” RelyingPartyConfguration that applies when a request is verified somehow, but there is no peer-based override. This is the most common case, and is handled for you because each Application bean implements its own default RelyingPartyConfiguration automatically. That is, defining an Agent gets you “for free” a default Application and default RelyingPartyConfiguration with no additional configuration syntax.
A possibly empty list of RelyingPartyConfguration overrides that are checked in series until one of them applies to a request.
Unlike the IdP, however, because there can be (but don’t have to be) multiple instances of each of these, the beans used to define the defaults are a bit different to minimize the amount of XML needed. Instead of explicitly defining each of these three cases for every Agent or Application, the configuration is optimized to allow a common set of definitions for them that will be automatically applied for you into each Agent and Application unless overridden.
In the majority of cases, you would not be expected to need to do a lot of one-off definitions of RelyingPartyConfguration information that would differ by Agent or Application, for the simple reason that the point of them is generally to customize behavior for a specific IdP/OP, and that custom behavior is likely more about the IdP/OP than about the specific Agent using it.
Metadata-Driven Configuration
Some of the actual need for RelyingParty overrides was obviated later in the IdP’s maturity cycle with the ability to add tags to SAML Metadata to drive behavior and overrides profile settings directly. The history of the RelyingParty mechanism dates back to the earliest IdP versions, but it’s no longer usually the best way to handle things, at least when SAML Metadata is used.
A separate topic will be created about this subject, but for now the IdP MetadataDrivenConfigurationtopic is the best material available about it and it works the same way.
As with the IdP now, when using SAML Metadata, it is strongly encouraged that you explore that option before using overrides, though in some cases a simple override or two are fine. When things start to compound and overrides start multiplying, then that’s a sign that you’re off track.
RelyingPartyConfiguration Usage
Before getting into the weeds of how to configure things, it’s useful to understand in general terms what the settings available on the RelyingPartyConfguration are. The most important setting they carry is the profileConfigurations property, which carries a collection of beans implementing the ProfileConfiguration interface. While it is possible to get more advanced using ActivationConditions (as in the IdP), generally including a particular bean means that that profile is enabled for a request to the Hub that maps to that configuration, so it is a basic toggle controlling what features are active, broadly speaking.
Note that by default, no usable profiles are implemented in the “core” Hub plugin, only provided by the protocol plugins themselves for SAML, OpenID, etc. But those plugins auto-register internal instances of the necessary objects and configures them by default in order to simplify initial deployment.
In the Hub, the issuer property is also used somewhat frequently if the Hub serves multiple Agents, since they likely have to be configured with different protocol identifiers, but because of how the configuration is layered, in most cases that property can be set on an Agent bean itself and applies to all of its activity.
Finally, the interface also exposes a global SecurityConfiguration interface that carries some rarely-modified generic security settings and objects. This isn’t normally something one needs to modify because the more typically relevant information such as keys are controlled in other ways using the ProfileConfiguration beans.
Summing up, there isn’t usually a lot you would set specifically on the RelyingPartyConfguration itself other than the profileConfigurations collection.
Default Beans
To limit the extra configuration required even when many Agents are defined, there are three stand alone beans that may exist in the conf/sp/agents.xml file:
shibboleth.sp.DefaultProfileConfigurations
This bean carries a collection of beans implementing the ProfileConfiguration interface, which as in the IdP enumerate which functional profiles are to be enabled, and allows their behavior to be customized with far too many options and settings for anybody’s health. This is where most of your typical configuration customization is located.
This default collection of profiles is auto-injected for you into every Agent and Application unless you customize those objects with a specific
profileConfigurationsbean property definition.The actual beans available to build on for this come not from the core Hub plugin but from the protocol plugins that extend it, and they may often have the same names as beans used with the IdP, but are in fact different objects, so there is no conflict there.
shibboleth.sp.UnverifiedProfileConfigurations
Similarly, this bean also carries a collection of ProfileConfiguration beans that are enabled for unverified requests and is also auto-injected into every Agent and Application.
It’s a bit more complex to override this on a per-Agent or Application basis. See “Unverified Profile Example - Enabling for a Specific Agent” below.
shibboleth.sp.RelyingPartyOverrides
This is a collection of RelyingPartyConfguration beans (as would be found in the IdP today) that act as the sequence of overrides to test for each request. These are also injected for you into every Agent and Application, unless those objects are customized with a specific
relyingPartyConfigurationsbean property that points to a different collection of overrides.Notably, their
profileConfigurationsproperty is left unset, so if the point of your override is to alter some other setting, you can continue to inherit the use of the objects in the shibboleth.sp.DefaultProfileConfigurations bean in most cases, but it is more typical to need to override that property with a different set of profile beans, as that’s normally the purpose of an override.
For now, the thing to take away is that by altering the contents of these three beans, you can generally map in all the ProfileConfiguration beans and settings you want to use across the Hub’s Agents, and can define a few RelyingPartyConfguration overrides if needed.
There are examples of some of the unusual cases later on, though they should be quite rare.
RelyingParty Override Factories
At the lowest level, it is possible to create an override by defining a bean with a parent of RelyingParty and attaching an activationCondition property with a custom class or ScriptedPredicatethat implements an arbitrary condition to determine if the override applies. This is rare, however.
As in the IdP, there are a set of “factories” provided that assist in producing particular kinds of overrides for different criteria. Using them saves work and automatically constructs the expected activationCondition for you.
The provided factories are:
RelyingPartyByName
Applies an override based on the entityID/client_id/etc. of the authenticating authority. This is the most common one for simple exceptions.
RelyingPartyByEntitiesDescriptor
Applies an override based on a SAML Metadata batch’s
<EntitiesDescriptor>Nameattribute. This is not recommended when consuming external metadata but may be workable when metadata is built locally.
RelyingPartyByGroup
This is the same as the previous case but also adds a check for an entity’s membership in a SAML
<AffiliationDescriptor>in the supplied metadata. Quite rare in practice but again may make sense in some local scenarios.
RelyingPartyByTag
Applies an override based on
<EntityAttributes>metadata extension tags. The tag-based approach is a generally recommended way of doing simple overrides that might apply to a large number of systems. It is a form of MetadataDrivenConfiguration that essentially indirects the settings by storing them inside the Hub configuration while referencing the override with a tag.
RelyingPartyByMappedTag
This is the same as the previous case, but allows you to optimize tag-based overrides by relying on the decoding of tags in SAML Metadata into internal IdPAttribute objects via the AttributeRegistryConfiguration. Even without dedicated rules, the system can auto-decode URI-named SAML Attribute extensions into IdPAttributes with a corresponding name "as is", so generally the mapped variant should work the same way and will be faster.
There are examples of all of these methods in the IdP documentation in the RelyingPartyConfiguration topic so they won’t be repeated here for now.
Examples
Routine Example - Customizing SAML Options for a Secondary IdP
Before demonstrating more unusual cases, we’ll start with a more routine case of a a couple of Agents and defining some profiles plus an override.
In this scenario, the global properties (not shown) are set up to require a Discovery Service to select the IdP, so it becomes possible for a “default” IdP and a “second” IdP to be selected, which would trigger the override. The purpose of the override is to alter the default use of a “strong-auth” SAML AuthnContext class in requests to the enterprise IdP so that requests to the guest IdP would not specify it.
There are other ways to configure such a use case (including reversing the default and exception cases), but this is certainly one way to do it.
If more Agents or Application overrides were to be defined, they would inherit all of the RelyingParty-defined configuration automatically. Not all of the likely settings, particularly on the Agent side, are included to maintain the focus on the new portions.
Unverified Profile Example - Enabling for a Specific Agent
This is not a real world example, but since there are few “unverified” profiles in practice…supposing that OpenID keysets are to be exposed only via one Agent, this illusrates a way to do that. In practice, exposing keysets will require Agent configuration as well, so would already be Agent-limited without the Hub needing to do so, making this example pathological.
In the example, we uncomment and leave empty the shibboleth.sp.UnverifiedProfileConfigurations bean, which prevents the system’s automatic enablement of profiles by default.