Hello everyone,
SATOSA at its current state offers an attribute mapping configuration.
Internally, the attribute mapping mechanism does exactly what it
states: it maps attribute values from one attribute name to another.
The current format is as follows (can also be seen here[0]):
attributes:
identifier:
saml: [eduPersonPrincipalName]
openid: [sub]
While this declarative configuration is very useful and is what makes
SATOSA stand out as a proxy, there are cases where for the mapping to
be valid we would need to process the attribute value. Semantically,
that means that rather than mapping what is needed is conversion.
An example use case would be the mapping of the openid 'sub'
identifier to the saml 'eduPersonPrincipalName' attribute. From the
respective specifications[1][2] we can see that the two attributes
have different structure and requirements. The 'sub' identifier is
part of a JSON Web Token and thus inherits all the rules for forming a
valid JWT, plus the requirement of
[...] It MUST NOT exceed 255 ASCII characters in
length. [...]
while, for the eduPersonPrincipalName attribute we read
[...] It should be represented in the form "user
at scope" [...]
In order to map the sub identifier to eduPersonPrincipalName and
conform to the specification, processing of the attribute value should
take place, transforming the sub identifier format to the "user at scope"
format.
We propose a simple, non-intrusive change to the current attribute
mapping configuration format that would allow us to hook into the
mapping mechanism and process the attribute value before mapping it.
Here is the proposed format for the attribute mapping configuration:
attributes:
identifier:
saml: [eduPersonPrincipalName]
openid: [sub]
processor:
module: python.module.that.inherits.from.AttributeProcessor
key1: value1
key2: value2
The proposed change adds a _special_ sub-dictionary named "processor"
under each internal attribute dictionary, that requires the 'module'
key to be present. The 'module' key is the python module path of our
custom module that is responsible to process the attribute value. The
custom module inherits from the AttributeProcessor module, that
defines the interface of the processing method and its invocation.
Extra keys like 'key1' and 'key2' can be set and are passed as
arguments to our module, acting as module specific configuration
options, allowing further configuration flexibility of the processor.
By default, the AttributeProcessor does nothing more than simply
mapping the attribute value, which is what currently happens and what
should happen if "processor" is not set.
The above described format allows us to stay compatible with the
current configuration format, while giving us the choice and
flexibility to further define the mapping behaviour by allowing us to
hook into the mapping mechanism and process the attribute value.
We are currently working on an implementation and we would appreciate
any feedback on the format, the AttributeProcessor interface, naming
of the newly introduced parts ('processor', 'AttributeProcessor',
etc), and your opinion on whether this could be part of the core of
SATOSA.
[0]:
https://github.com/SUNET/SATOSA/blob/master/example/internal_attributes.yam…
[1]:
https://openid.net/specs/openid-connect-core-1_0.html#SubjectIDTypes
[2]:
http://macedir.org/specs/eduperson/#eduPersonPrincipalName
Thanks,
--
Ivan Kanakarakis