Hydra: Token authentication

Hydra is the name for the central IPAM at the University of Oxford. To those of you that did not know this, I will suggest that you may stop reading further as this blog post is not for you.

Right, since you’re still reading, I assume you know about Hydra and are interested enough to know about its changes and developments. This blog post will lay out one new development in particular: a new means of authentication named tokens.

This post goes into a fair bit of detail, but if you want to skip to the Conclusion section at the end, there should be a fairly concise summary.

1. Prerequisite knowledge: authentication vs authorization

Skip this section if you know the difference between these two words within the context of access control.

With a computer interface with any degree of access control, the system needs to verify who you are. This is authentication [authN]. Traditionally this has been done using a shared secret, a password. These days more modern and fancier mechanisms exist such as biometrics and multifactor authentication, but these are just different means to the same end: can you prove who you say you are?

Post authentication the system knows you’re you.  Now, it needs to know what you are authorized to do, or what you’re allowed to read or change. This unsurprisingly is authorization [authZ].

AuthZ and authN are two distinct processes but sometimes they have been merged together, and lines have blurred. Microsoft’s Active Directory springs to mind. In Hydra they are distinct subsystems.

2. History: Hydra, stats and SPNEGO authentication

Ever since Hydra went live, its API has been a very prominent part of the service. There is nothing that you can do in the user interface that is not possible using the API, and for those of you out there who have made use of the API, thank you! We appreciate that it is being used.

To put some numbers out there, there have been 411 “users” (I write “users” in quotes to mean the union of human users and API users) who have updated entries in Hydra. Of those “users”, 5 have been API users. Doesn’t sound like much, but the number of transactions is a bit different: these 5 users account for 39% of all transactions within the system!

Hydra’s authZ database is a join of two data sources, Groupstore and Hydra’s own databases. Groupstore handles the creation of Groups and the assignment of users to them. Hydra then has a mechanism to pull the data into its own database, and augment it with domains and subnet associations to said Groups. Further, ACLs are assigned to DNS zones, but I mention that only for completeness.

On the authN side, currently, the method used depends on what kind of access is being requested. Human users use Shibboleth, and machine API calls use SPNEGO.

Now, the authN system that underpins the API is a tried and tested one shared by other systems, including CUD and SAVANT. This SPNEGO system has some alluring advantages, particularly at the time of Hydra’s introduction:

  1. It made use of the same backend authN (not authZ) database used by users at the time.
  2. The “users” that can authenticate are visible and assignable to Groups in Groupstore. Adding and removing “users” to groups is an identical process for the two types of user.

However, there is this feeling that SPNEGO authentication is rather heavyweight, and it favours Unix-like clients (surprising given that SPNEGO’s first implementation was Microsoft’s!) Whether that feeling is justified or not is not going to be discussed further, but it’s not escaped our notice in the Network Support and Development team that this sentiment exists. Perhaps the 5 Hydra API users is a testament to SPNEGO’s daunting reputation!

As such, we will be hoping to introduce Basic Authentication to Hydra as an additional authN mechanism, called tokens. These tokens’ authZ are totally managed outside of Groupstore and thus do not have the same fine-grained level of control as “users” do.

  1. Each token is only associated with one group. You cannot affiliate one token with multiple groups, not by direct association nor by indirect inheritance.
  2. Tokens can be created, and destroyed. There are no mechanisms by which you can modify an existing token.
  3. Tokens cannot be used for user UI access, or said another way, tokens will only grant the holder API access.

3. Token constraints: masks

If Basic Authentication was all I had to say about tokens, then this blog post could probably have just been a few lines in an email. However, the self imposed limitations above allow us to do something that up until this point has been impossible: further constrain a token by use of masks.

When you create a token, which at creation time is associated to a Group, you will have the opportunity to assign the following masks:

  • Hostname mask
  • IP mask
  • Content mask
  • Target mask

With these masks set wide open, this token will have the same permissions as any “user” in the group. However, the utility comes where these values are set to either blank, in which case the creation of any record of a particular type is impossible, or to some other value, thus constraining the records that can be created.

As an aside, you may be thinking that the word “mask” isn’t accurate here, as these permissions are not based on binary values, and you would be correct. However, I hope some sloppy, but acknowledged, terminology doesn’t get in the way of understanding the core principles of what this system gives you, which is a fairly powerful self-service permissions system. It’s also a word that is close enough to a correct term, and all the other good words were taken!

Some examples may be helpful here:

3.0.1. Example 1: Same permissions as any “user” in the group.

  • hostname: %
  • ip: 0.0.0.0/0,::/0
  • content: %
  • target: %

Note that there are additional checks outside these masks, and so even with these fully permissive values the token will be constrained by the permissions of the zones and of the Group in which it belongs.

3.0.2. Example 2: An A record for any hostname within the group

  • hostname: %
  • ip: 0.0.0.0/0
  • content: [blank]
  • target: [blank]

Note that creation of CNAME, TXT records will not be permitted with these masks. Also no AAAA (IPv6) records are permitted.

3.0.3. Example 3: SPF records for example.org. and example.com.

  • hostname: %.example.(org|com).
  • ip: [blank]
  • content: v=spf1 %
  • target: [blank]

Note that if this token is placed in a group which does not have permissions to edit either example.org or example.com, then this token is incapable of doing anything.

3.0.4. Example 4: SRV records pointing to example.org.

This example is more complicated:

  • hostname: _%.(tls|tcp|udp).%
  • ip: [blank]
  • content: [blank]
  • target: example.org.

Three main points about this example:

This hostname mask is imperfect: the first “%” could include a ’.’ thus breaking the format of an SRV record. To be truly restrictive you would need to use character classes, which I leave as an exercise for the reader, especially since this is an unrealistic example already. For full details on the mask format, please see below.

Secondly, the target can only point to one value. You would not be able to point an SRV record to foo.example.org., for example. If you want that then the target mask needs to be %.example.org. Finally, there is only an implication that this is limited to SRV records. A CNAME record with the same hostname, target values would be just as valid and indeed would be accepted by Hydra. An MX record would be too, except that MX
records cannot begin with ’_’ so would be rejected for that reason.

4. Mask format

Let’s get the easy one out the way: the IP mask is a comma separated list of subnets. It currently only supports IPv4 and IPv6 subnets. Invalid entries (e.g. 0.0.x.0/24, FOOOOO) will be accepted as entries but will be silently ignored by the system at validation time.

For the remaining masks, hostname, content and target, the format uses PostgreSQL’s SIMILAR TO syntax. This, to me, seems to sit between the ease-of-use (if you can call it that) of SQL’s LIKE syntax, and the flexibility and power of regular expressions. To those of you who don’t immerse yourself in the PostgreSQL’s manual pages on a daily basis (you’re missing out), the syntax may be unfamiliar to you, or worse, be similar enough to SQL’s LIKE syntax that you mistake it for that when in fact it’s more flexible and powerful. However, it is hoped that the easy stuff is intuitive enough and that you can use this blog post and documentation as a guide, and failing that there is a whole wealth of non-Hydra-specific documentation on the syntax on the internet already.

As with most things, there’s a level of trust placed on the people creating the tokens, some of it obvious, some of it less so. This is a self service tool, where you can write your own mask. While testing of various inputs has been positive in terms of SIMILAR TO being resistent to ReDoS attacks, that is not an invitation to try! While I myself was not able to cause a timeout, that perhaps is more due to my own lack of imagination: PostgreSQL’s documentation itself warns that using SIMILAR TO is a potential vector for a DoS attack. As such, we will be monitoring the backend for malicious masks and all tokens will be forever associated with the username of the person who created it.

On the subject of performance, masks will only be referenced on record changes, because they are slow for lookups. Said another way, masks are not consulted for retrieving records. For most use-cases this will be fine, but it should be noted a token API request will be given all records belonging to its group regardless of masks, and such a token query may well provide a record that fails mask validations upon edit.

5. Who can create these masks, and what’s the timescale?

I said earlier that this functionality was completely detached from Groupstore, but in reality that was an oversimplification: If you are a manager of a Group in Groupstore, you will have the ability to create tokens for that group.

Much of the functionality is written and ready for deployment, but not all of it, and as such there is no firm release schedule. The reason that this blog post is being posted in advance of the feature’s (maybe) imminent release is that for those of you who are wishing to automate say ACME challenges, then a path of lower resistence and higher security is on the horizon, so please sit tight! Further firmer announcements will be made on the ict-a maillist. To start a discussion on the topic, please make use of the hydra-discuss maillist.

6. Conclusion

Hydra’s API, which up until now has been secured using SPNEGO authentication, will be augmented with a new method, Basic Authentication, using tokens. Further, these tokens may be further constrained by masks such that they may be shared with third parties while not exposing your entire IP and domain estate to them. The assignment of masks will be self-service.

Posted in DNS | Comments Off on Hydra: Token authentication

Comments are closed.