A long-lived, non re-assignable, omnidirectional identifier suitable for use as a principal identifier by authentication providers or as a unique external key by applications.
http://macedir.org/specs/eduperson/#eduPersonUniqueId

This is a globally unique identifier that looks a bit like an email address but certainly does not have to be one. (Most existing email addresses will not be suitable canditates for this attribute, due to its requirements for non-reassignment as well as opqaueness.)

eduPersonUniqueID Alternatives

For application integrators the potential alternatives to relying on eduPersonUniqueID in the Higher Education and Research sector basically are:

So eduPersonUniqueID is clearly the preferred choice if:

But eduPersonUniqueID is also an acceptable alternative in basically all other cases where you already accept any of the following as primary identifier for a subject:

So following Postel's law it's recommended for SAML Service Providers to (also) accept eduPersonUniqueID, whenever a stable, unique identifier is needed.

Creating the attribute with Shibboleth IDP v3

If you are already supporting persistent NameIDs you could re-use parts of that configuration to easily create eduPersonUniqueID attributes. The example below works by taking the attribute configured in /opt/shibboleth-idp/conf/saml-nameid.properties (idp.persistentId.sourceAttribute) as source data, applying the same salt as configured in /opt/shibboleth-idp/conf/saml-nameid.properties (idp.persistentId.salt), and generating an MD5 hash from the combined string:

<AttributeDefinition id="eduPersonUniqueId" xsi:type="ScriptedAttribute">
    <Dependency ref="myLDAP" />
    <Script><![CDATA[
        var scopedValue = Java.type("net.shibboleth.idp.attribute.ScopedStringAttributeValue");
        var digestUtils = Java.type("org.apache.commons.codec.digest.DigestUtils");
        var idSaltHash  = digestUtils.md5Hex(
            %{idp.persistentId.sourceAttribute}.getValues().get(0) + "%{idp.persistentId.salt}");
        eduPersonUniqueId.addValue(new scopedValue(idSaltHash,"%{idp.scope}"));
    ]]></Script>
    <AttributeEncoder xsi:type="SAML1ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" encodeType="false" />
    <AttributeEncoder xsi:type="SAML2ScopedString" name="urn:oid:1.3.6.1.4.1.5923.1.1.1.13" friendlyName="eduPersonUniqueId" encodeType="false" />
</AttributeDefinition>