private void buildAuthenticationHistory(final Set<Authentication> authentications,
                                            final Map<String, List<Object>> authenticationAttributes,
                                            final Map<String, List<Object>> principalAttributes,
                                            final AuthenticationBuilder authenticationBuilder,
                                            final PrincipalElectionStrategy principalElectionStrategy) {

        val merger = principalElectionStrategy.getAttributeMerger();
        LOGGER.trace("Collecting authentication history based on [{}] authentication events", authentications.size());
        authentications.forEach(authn -> {
            mergePrincipalAttributes(principalAttributes, merger, authn);
            mergeAuthenticationAttributes(authenticationAttributes, merger, authn);

            authenticationBuilder
                .addSuccesses(authn.getSuccesses())
                .addFailures(authn.getFailures())
                .addWarnings(authn.getWarnings())
                .addCredentials(authn.getCredentials());
        });
    }
Principal id is and must be enforced to be the same for all authentications.
Based on that restriction, it's safe to grab the first principal id in the chain
when composing the authentication chain for the caller.
core/cas-server-core-authentication-api/src/main/java/org/apereo/cas/authentication/DefaultAuthenticationResultBuilder.java