Authorisation (authz) under the InternetWide Identity Framework is performed through Diameter, possibly falling back to RADIUS. Very interesting about this choice is that all future developments in our work will concentrate at these servers.

The InternetWide Identity Framework supports of quite a plethora of identities with various clever uses and that may seem confusing to the implementer of a service. Interestingly, it is not difficult at all.

Authentication not via Diameter or RADIUS

Very often, RADIUS or Diameter are used for authentication, as well as authorisation. In general however, this is a choice that applications can make based on their specific requirements. For the InternetWide Identity Framework, Diameter is only used for authorisation, but not authentication. RADIUS may be supported in a backward compatible manner, but it lacks semantics such as secure connections and is far less suitable to securely connect realms.

It is an explicit InternetWide Goal to welcome remote users when they want to access services. This means that these users must be authenticated, and that is not easily done with a locally oriented protocol; instead, the secure transport connecting locations is highly suitable for this purpose.

What remains to be done with Diameter is authorisation -- especially if we are capable of authenticating remote users there is a need to regulate which parties may be granted access.

Authorisation Questions

The two major questions that should concern us are simple:

  • Can authenticated user_A act as though he is authenticated user_B?
  • Can authenticated user_B access resource_R (and possibly its instance_I) in mode_M?
  • Can authenticated user_B communicate with targeted local user_C? (optional)

In the first question, we see user_A change its identity to user_B, which might be a group, role, psuedonym or alias in which the user takes part. If this is done, we will continue to treat user_B as the authenticated user instead of user_A, because apparently the client or his application decided that this is desirable for the resource being used, maybe for reasons of privacy.

The second question makes a decision on the use of a resource, which may be anything; for instance, a Git stashing server. As a general form, we describe resources as a class (which is a UUID, generated per application and possibly registered for ARPA2) and an optional UTF-8 key that instantiates the class. Classes represent conceptual resources, not so much a protocol implementation; so a Git stash may be made available over HTTP, SSH and Git, always with the resource class. The instance exists to further localise a resource; in case of a Git service it can add a unique code for one Git repository on a stash. It might also use a URI format. The resourceClassUUID is explicitly allocated for an application class and defines the format to be used for the resourceInstanceKey applic The second question also mentions a mode of use, for which we identify the CRUD rights and more; for example, Create and Delete may be the privileges of an administrator group member, whereas Read is public and Update limited to a webmaster or an author of a resource.

The third question is for another kind of authorisation. Instead of talking to a resource, it asks to communicate with a user. This question is independent of protocol; so the same answer would apply to email, telephony and chat.

An authorisation inquiry always involves the first form, though it may be trivial because user_A and user_B can be set to the same value. This is valid as a method of testing that this user exists. On top of this inquiry, it is possible to add either the second form, the third form or neither.

Abstract Resources to Serve all Protocols

Thinking in terms of resources is not new at all; it underpins the HTTP model, and RESTful APIs celebrate this idea too. What we do here is abstracting it so that it can be applied to many other protocols as well. This is why there are not HTTP paths but UUIDs in this reasoning. It is up to a service if each protocol (HTTP and XMPP, for example) uses its own set of UUIDs, or whether they overlap, but when they are alternate representation forms of the same data it is advised to share the UUID, even if one protocol can only show a partial view. The need to set a fixed UUID for each conceptual application means that a quick, local scan can be made to decide if a question about authorisation is useful at all; without a resource, no authorisation questions can be asked.

Note that frameworks like OAuth conduct authorisation through HTTP redirection. There is indeed no problem setting up a separate authorisation server and publishing the interactions between that and a resource service; but it is not clear at this point what value that will add, since usually the authorisation service will be controlled by the resource whose access is being granted. For that reason, we consider an internal Diameter service to work fine.

What we do see happening in future ARPA2 phases is that the authorisation handlers near services will interact with a remote identity provider, this is a split of responsibilities that seems to make good architectural sense when the goal is to allow end users more control over their online presence. For these cases, we intend to unleash a standard communication mechanism as part of our 3rd phase, ServiceHub. This mechanism will be based on Diameter, probably with GSS-API protection and run over an SCTP/IPv6 channel. All can then be encapsulated inside the authorisation interface described here, so services should not have to change when we add this extra level.

Formulating the Authorisation Question in Diameter (or RADIUS)

Services can pose authorisation inquiries over either Diameter. We discourage reliance of RADIUS because it is seriously hampered for realm-crossing uses, especially in terms of security which is mostly done with a separate TLS session for each query; that scales really badly.

It is advised to already keep in mind that the uplink to a remote identity provider will standardise on Diameter, though. This hint may help to design the most useful networking components. We currently feel inclined to advise the use of OpenDiameter because it can service both Diameter.

Now, let's see how to ask authorisation questions detailing them:

  • Can authenticated user_A act as though he is authenticated user_B?
  • Can authenticated user_B access resource_R (and possibly its instance_I) in mode_M?
  • Can authenticated user_B communicate with targeted local user_C? (optional)

The combined forms that can make sense are:

  • Only the first question, with user_A equal to user_B to test if a user exists
  • Only the first question, with user_A different from user_B
  • Both the first question and the second question without instance key
  • Both the first question and the second question with instance key
  • Both the first question and the third question

Only the second form uses the AVP NAS-Identifier. Only the third form uses the AVP NAS-Port-Id.

An Access Request packet for these two questions contains the following AVPs:

  • Destination-Realm holds the domain being targeted.
  • User-Name holds the user_B name that should be used; not just the local part, but also the domain, even if it matches the Destination-Realm.
  • User-Password holds the user_A name as it has been authenticated before, including the domain name even if it matches Destination-Realm. In RADIUS, this field is subjected to feel-good "encryption", but Diameter drops this habit. Advise is given to employ end-to-end encryption, but no specification has been approved for this use. This is not a problem; the data that we intend to store in it is not sensitive.
  • NAS-Identifier is used in the second form, where it holds the Resource Class UUID so resource_R, in lowercase text form; if a resource instance is added, the Resource Class UUID is followed by a space and the instance key instance_I in its textual form. Note that this entire field is considered case sensitive.
  • NAS-Port-Id is only used in the third form, where it is set to a targeted local user_C.
  • We never send both a NAS-Identifier and NAS-Port-Id AVP; both may be absent.
  • Other fields may be added to facilitate local distinctions or RFC 7155.
  • Note that the mode_M does not occur in the Access-Request; it is instead returned as a string of flags and can then be tested.

Normally, there is no challenge/response interaction; successful authorisation directly returns an Access Accept packet with the following AVPs:

  • User-Name is the actual user name that should be used; authorisation may have reasons to not set it to user_B but to yet another form; it may even set other values derived from its own internal configuration; the application should process this outcome and forget about its originally requested user names, or it may treat an unexpected user name as a rejection of the desired authorisation. The field contains the user name with its domain.
  • Filter-Id holds a series of letters, each serving as a flag to indicate some permission; we standardise letters and precede it with a % sign. Access Requests with NAS-Identifier ask for a resource (instance) and get

    • a for administration
    • s for services
    • d for resource deleters
    • c for resource creators (who may fill it with content)
    • w for writing to an existing resource
    • r for readers of a resource
    • p for provers who may prive statements without seeing the info used
    • k for knowers who may know that the targeted data exists
    • o for owners of a resource
    • v for visitors, who may only receive limited facilitation

    The permissions usually include the ones listed below them; so the permission r usually comes as rpkov — the Diameter server is responsible for providing them all; the user-facing server (a "NAS" in terms of Diameter) can simply look for the presence of a flag to know what a user may or may not do with a resource.

    On the other hand, when requesting communication with a user through NAS-Port-Id, the flag letters are

    • W for white-listed communication
    • G for gray-listed communication
    • H for honeypot-listed communication
    • B for black-listed communication

    It is sometimes rumoured that H is for "hellbound", but this is not what is defined above. It is generally a mode dedicated to attack handling, and should not be selected lightly; it involves computational overhead on both ends.

    The fallback mode is B for communication and v for visitors. These are regularly returned for entries rejected in the ACL, so do not expect an error for any other reasons than operational concerns. This makes it more difficult to probe for accounts through the NAS.

    If neither NAS-Identifier nor NAS-Port-Id were in the Access Request, then Filter-Id is absent from the Access Accept.

    Note that these rules hold all the potential, and so a response will always succeed; just maybe with very low facilitation levels.

  • Reply-Message may be added; it holds a textual description from the authorisation process that may be shown to the user.

  • Configuration-Token may be added; it holds a sequence of bytes that the NAS can use to unleash the requested resource; this value should not be shown to the client application, but remain within the resource server.
  • Local configurations or RFC 7155 may add attributes that may be specific to a requesting application.

An example of changes to the User-Name by the authorisation server occurs when a member attempts to authorise to a group; in that case, authorisation may conclude that access is accepted, but as a separately named group member; for instance, authenticated user john@example.net may be authorised as a member of support@example.com under member name support+john@example.com. This can be helpful to protect the privacy of John's individual email address; the same mechanism can be used to change from or to external user addresses when domain users hold an alias to such an address.

In situations of operational problems, there may be flat-out rejection, relayed through an Access-Reject message. This is not usually done to reject an attempted access; for that, we return a more subtle result in the Filter-Id that just happens to drop all the way down to guest mode for resource (instance) access, or to black-listed mode for communication. Within the ARPA2 framework, we pride ourselves on always including at least:

  • Reply-Message holds a textual error message about the authorisation process that should be shown to the user

There is a third possible response, and this occurs when access has been gray-listsed. In such situations, the user is asked to somehow prove their identity before they can be added, and to try authorisation again.

The Access Challenge reply contains the following AVPs:

  • Reply-Message holds a textual instruction to the user, indicating how to respond to the challenge (although automated handling is usually preferred)
  • State holds a binary object to be reproduced in the matching response; it holds state for the current challenge/response authorisation attempt; the authorisation server will generally encrypt and/or sign this attribute to avoid tamporing and tapping; the contents of this field may therefore be shown to the user, but the size can easily exceed 100 bytes
  • Idle-Timeout holds the number of seconds that the user may take to respond

In response to this challenge, a somewhat different Access Request should be sent, holding the following AVPs:

  • User-Name holds the same value.
  • User-Password holds the same value.
  • NAS-Identifier holds the same value or is also absent.
  • NAS-Port-Id holds the same value or is also absent.
  • State replicates the same attribute from the Access Challenge.
  • Other fields may be added to facilitate local distinctions.
  • As before, the mode_M is not mentioned in the Access Request.

The difference with the normal Access Request is the addition of the State attribute.

When we add gray-listing facilities to ACLs, presumably as a default policy, we may use the Access Challenge response. Note that services that lack support for gray-listing are supposed to consider this a black-listed response. This method nicely matches the idea of service-specific gray-list handling, and it gives the user a choice.

Consider the Nginx web server. When using its internal TLS support, it sets a variable $ssl_session_id that cannot be falsified by sessions, especially because we trust Nginx to serve our interests. This makes the variable suitable as a key to the current TLS-wrapped connection or session. Within this session, one authorisation effort usually suffices, and it may serve the interests of the client for a prolonged period. The client can be told to "reload" or "reconnect" to refresh their rights to the service. Note that HTTP servers can suggest prolonging connections to a period that matches the caching time for the corresponding information in the authorisation cache that responds locally to access questions that the Nginx proxy forwards, usually through a HTTP Auth Request.

As a transport, the InternetWide Architecture chooses Diameter over RADIUS, because Diameter frames can be carried over SCTP, which saves an application the complexity of resends and uncertainty about the authorisation server being online. It also means that a security layer such as DTLS can be negotiated for a long-lasting connection, causing all future queries to be quickly streamed to the authorisation server, without per-query setup delays. RADIUS has been used in similar setups, but this has rather stretched it beyond its designed-in capacities.