DefiningAgents

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.

DefiningAgents

This is an outline of the process and Spring bean(s) involved when adding Agents to a Hub using the Agent Resolver service and some of the basic settings supported.

The primary purpose of the Agent beans are to allow the software Agents to make requests to the Hub so most of the settings on the Agent interface relate to that function. The rest are high-level policy or control settings that would apply to the Agent as a whole such as controls around handling of POST data recovery and character encoding, A detailed reference to the settings supported by the Agent interface is also available.

Concepts

The term “Agent” has a slightly different meaning when thinking about the Hub’s configuration then it does in the larger sense of the SP’s software separation between Agent and Hub software. Specifically, while an Agent can be thought of as a specific piece of software (e.g., an Apache or IIS module) or a specific installation of that software, the Hub can consider an Agent to be “all the installations that collectively act on behalf of a particular web site”, which accounts for the usual scenario of a cluster of cooperating systems behind a load balancer or similar tool.

While it is possible for all the systems in a cluster to act as discrete Agents from the perspective of the Hub’s configuration, that isn’t really the expectation since a cluster of Agents pretty much by definition are intended to have identical behavior with respect to supporting SAML or OpenID Connect or other SSO protocols. So the documentation assumes that the intention is to treat a cluster as a single logical Agent for Hub purposes.

Once the Hub is configured successfully to support a given Agent working with a particular set of IdPs/OPs, adding new Agents with the same requirements for external interoperability can be very simple and streamlined.

Another assumption made here is that we’re talking about “remote” agents. If the Hub is deployed co-located with an Agent installation (as “shibd” was usually deployed in the legacy SP), there is assumed to be a 1:1 relationship between Agent and Hub and the out of the box defaults provide support for a localhost-only deployment of an Agent using a dummy name, so there is no “adding” of the Agent to the Hub’s configuration, merely configuring behavior, often via Java properties.

Basic Agent Definition

The Spring bean you will inherit from to define new Agents is shibboleth.sp.Agent

Beans of this type will automatically define and expose a default Application and RelyingPartyConfiguration automatically, and the bean supports all the settings allowed on the Agent, Application, and RelyingPartyConfiguration interfaces at once. This is designed to facilitate ease of use for simple configurations.

The information needed to define an Agent bean to wire up the most important bean properties is:

  • A Hub-assigned identifier for logging/auditing purposes; this value need not be known by the Agent deployer.

  • A source of credentials for the Agent deployer to use to connect to the Hub.

    • The Agent may be assigned multiple credentials is desired to help with service account rotation, and the username(s) assigned may be, but do not have to be, the same as the Hub-assigned identifier noted above. They will often be different due to the way most organizations name their service accounts.

  • (Optional) An address or address range to limit connections from the Agent if desired.

The bean properties used for the above information are p:id, p:usernames or p:credentials, and p:allowedAddressRanges, respectively. The examples up to this point and in the default files demonstrate most of this, but the credentials deserve a little bit of additional discussion so you understand the options there.

The credentials provided to the bean are internally tracked as a Java Map, with the map keys signifying the username and the values the secret. Either of these may be null. A null key means that the bean ID is the username, while a null value means that the secret is in an external system (LDAP, etc.) rather than wired up internally. The difference between the two properties mentioned relates to this.

When the p:usernames property is used, a simple collection of usernames is fed in with no secrets, as this is used to to tie the bean to the service account names the Agent will be using. The Map values are automatically set to nulls.

<bean p:id="sp.example.org" parent="shibboleth.sp.Agent" p:allowedAddressRanges="0.0.0.0/0" p:usernames="#{{ 'SA1-sp.example.org', 'SA2-sp.example.org' }}" />

When the p:credentials property is used, an actual Map is supplied and you may if desired set keys or values to null if appropriate (or not). The following example is equivalent to the earlier example using the usernames property.

<bean p:id="sp.example.org" parent="shibboleth.sp.Agent" p:allowedAddressRanges="0.0.0.0/0" p:credentials="#{{ 'SA1-sp.example.org': null, 'SA2-sp.example.org': null }}" />

SSO Protocol Usage

SSO support may be automatic in many cases when adding Agents assuming you already have your desired protocol support in place. The up-front steps are covered in SAMLBasics and/or OIDCBasics, and if you’ve done those steps, then in most cases any new Agent beans you add will “inherit” the profile configuration(s) that are automatically enabled (or that are explicitly defined in the lists that are commented out at the end of the file). Either way, they are applied to all Agents, Application overrides, and RelyingParty overrides unless you explicitly set the profileConfigurations property on any of those beans directly.

Issuer

What you typically do have to do to distinguish the new Agent bean is to set its p:issuer property to define the SAML entityID or OIDC client_id the Agent will act under. Usually any new Agent will be for a distinct RP/SP (as perceived by IdPs/OPs), so if nothing else, you have to set that property when multiple Agents are being defined.

In most cases, you need not consult with or coordinate on that value with your Agent deployers. Since you will need to produce some form of Metadata or Client Information for them, you will generally have to know what virtual hosts they’re operating under, and probably have at least a rough idea of what the service is, and you would want to construct a URL identifier to use based on that information. Of course it may be a value that already exists too, from migrating an older deployment, in which case you would get it from the deployer in some sense. But the Agent doesn’t need to know anything about this step beyond that case by design.

It also does not need to directly relate to the Agent bean’s p:id property, although it may certainly be sensible if it does. In fact, you could even build a script or Java code to dynamically generate the values, as discussed in AutomatedIssuerGeneration.

As a real world example, this is what the Agent bean for the SP running on our project server would look like. Since it would be operating with a dedicated Hub on the same host, all that’s really needed are the various identifiers. (In practice, we would likely use the sp.issuer property in fact to supply the entityID in a single Agent case.)

<bean p:id="shibboleth.net" parent="shibboleth.sp.Agent" p:issuer="https://shibboleth.net/sp" />

Public/Private Keys and Certificates

It is generally going to make the most sense to reuse the same set of keypairs and certifiates across all Agents. The keys used are not shared with the Agent deployer under any circumstances; they have no need for them.

Because of how OpenID Connect works, it’s unlikely to make much sense to reuse existing keys when moving to this solution because that protocol supports relatively simple keyset migration by design.

In the case of migration from the legacy SP or another SAML implementation, the usual practice is going to be to start fresh with the keys generated by the Hub in most cases, unless only a single such set of keys is involved. While it is certainly possible to effect a migration of an older SP/RP by reusing its existing keypairs, we would say in general that this is probably a bad idea. While it does avoid a change to existing Metadata, it’s usually not a great idea to get a deployer in the mode of thinking it’s ever ok to share a private key, even within their own organization. In addition, it is complex to configure additional keypairs, especially if there are many of them. Reusing existing Metadata also prevents one from making one of the more significant improvements the new version allows for, which is the elimination of separate endpoint paths for different SAML bindings in favor of a new single, unified endpoint.