We have half-implemented proper key management at our dev shop. We have a SOAP web service (the key management web service) that can be used to retrieve passwords for other systems. So for instance, I might make a request to this service for the password to, say, a production PostgreSQL DB. I hit the web service with my AD credentials, and it determines whether I’m authorized to receive the DB password or not. If I am, then it is sent in the response. I can then use this service across all other software components instead of storing the DB password in a static config file (like Tomcat’s context.xml
, etc.).
The problem, of course, is that with an automated process the AD credentials passed into the web service need to be stored somewhere. So, to obtain the password to a DB (or any other secured resource), one simply needs to gain access to what is used to store the AD credentials, and can then submit them to this web service, which will then authenticate/authorize them, and return the password for the requested resource. Classic key management problem.
Hence, I’m trying to figure out a way to protect the AD credentials used to access the service. Someone mentioned Kerberos to me and I’ve began to dig in a little bit.
My understanding is that, with Kerberos, there would be 3 components:
- A client of the key management web service
- The key management web service
- A Kerberos (ticket granting ticket, TGT) server
My understanding is that:
- The client (somehow) obtains a TGT from Kerberos
- The client then issues a a request for some resource, say, a DB, to the key management web service, but does not supply any AD credentials, but instead, supplies the TGT
- The key management web service is then reconfigured to take this TGT and ping the Kerberos server with an “is this TGT valid?“-type request
- The Kerberos server responds and says “yes” (or “no”) and honors the request for the DB password, sending it back to the client in the response
So first, if anything about my understanding is incorrect, please begin by correcting me!
Assuming I’m more-or-less correct, then I have a few questions about this setup:
- How would the client first obtain the TGT from Kerberos?
- Do Kerberos TGT’s have expiration dates? How would then client “re-request” a new TGT?
- Does the key management web service need to implement any specific TCP protocol to speak with Kerberos, or does HTTP suffice? If Kerberos has its own protocol, are there any Java libs that implement it? (I know its easy to Google “java kerberos” but not sure what specifically to be looking for because again, I’m not confident I understand the architecture here).
5
The client obtains a TGT (=ticket granting ticket) by sending credentials to the kerberos server.
And now this is the point where I see the first major problem. You need some credentials. Is there really enough advantage in having credentials A just so you can request credentials B that you actually need instead of having credentials B in the first place? One credentials or or other credentials. I don’t see how it would solve any problem.
Ok, so you sent credentials to the Kerberos server and received your ticket. You then use GSSAPI in the other protocol to authenticate yourself using your ticket and the service will ask kerberos what permissions it should grant you.
Well, so now you have credentials A that you pass to service W (kerberos), get credentials B (the ticket), you pass that to service X, get credentials C (which is again username and password, presumably) and use that to request the actual service Y. Now that is an extra step and didn’t really bring any benefit still. Fortunately you can get rid of that extra step. The service Y almost certainly can do GSSAPI too. PostgreSQL certainly does as does any Microsoft thing, because the authentication part of Active Domain is kerberos. So you can replace X with kerberos instead. You ask kerberos for a ticket and then just use that ticket to access the database.
So we are back at using credential A to request credential B, just replaced your in-house thing with industry standard. If you need credential A in the application configuration, we just gained absolutely nothing. There may be two advantages depending on other conditions:
-
You can use the same credentials for multiple services. That does not have any real benefit for credentials stored in config file, but it has big advantage for credentials provided by the user. So if the credentials A come from a user, you want to do this, so the user only needs one username and password.
-
The password is not sent in clear-text to the database server. If the connection is not encrypted and there is a risk of it being sniffed, then it is a point. But in such case you probably want to avoid the data being sniffed too, in which case you need SSL anyway and cleartext password in SSL is not a problem.
Technical details are too broad. Either you need to ask specifically (setting up kerberos authentication in language X using library Y etc.; that kind of questions should belong on Stack Overflow, not here) or you need to read the documentation.
2