Networking and Security • 31:40
This session covers the Authorization API which shipped in Mac OS X. This API provides a centralized and secure way to know if an operation is permitted, such as requesting administrator privileges for installers.
Speaker: Michael Brouwer
Unlisted on Apple Developer site
Transcript
This transcript was generated using Whisper, it has known transcription errors. We are working on an improved version.
Good morning and thank you for coming to the Authorization API session. I want to apologize for the misprint that you might have seen which showed this as authentication. That's my fault. I got the changes in at the wrong time and they didn't get reflected out on the website.
So we will be talking about authorization in this session, not authentication. I'm Craig Keithley. I'm the Security and Cryptography Technology Manager in Apple's Worldwide Developer Relations Group. I work closely with the engineers on all security aspects and I'm pleased to bring up Michael Brouwere to talk about the Authorization APIs. Thanks.
We're going to talk about authorization and authentication on Mac OS X. I'll start off by talking about some recommended ways to use the Authorization API and what you as developers can do to make OS X more secure by using the Authorization API.
[Transcript missing]
Authorization is the answer to the question of "may I do something" or "can I do this" rather than "who am I?" Authentication answers the "who am I" question. Authorization makes the access control decision. I'll talk about some of the things, what it does and doesn't do, and finally I'll go over the actual API.
[Transcript missing]
So, why use authorization as the authorization we're providing? So one of the reasons is that it's much better than the current ad hoc methods used for performing authorization. To give you an example, the way UNIX determines whether you can log in is if you're in the UNIX password database and you happen not to be in the /etc/no/login file, then you're okay.
The way FTP lets you log in is a similar mechanism, but yet again slightly different. Each protocol and each way to access the system, traditionally in UNIX, uses its own ad hoc method. And in many cases, authorization isn't even performed. It's just as soon as you've authenticated, it's assumed that you also may access this service.
By using authorization, you're making an explicit decision, which means you can have a user in the system which doesn't automatically mean he can use every single service available in the system. So, you can control access to which parts of the system you want people to have access to.
Some of the benefits of having a centralized Authorization API, as we're providing, is it makes your applications easier to audit. Like I said before, one of the things I'll talk about later is the ability for you to split your application into two components, one component running non-privileged and one running with elevated privileges. The part with elevated privileges is going to be much smaller depending on less external frameworks, which will make it easier for you to audit.
Unlike on Mac OS 9, on Unix when you're running something with root privileges, you really want to make sure you walk through every single line of code to make sure that your application isn't causing the next cert advisory security vulnerability against our operating system. Because it would make you and your company look really bad.
Michael Brouwere So, the other thing, it's configurable, it's securable, which means that in the default out-of-the-box experience, the way we'll ship it, it'll just be easy to use and your app probably won't work any different from how it worked on OS 9. However, once administrative tools become available to have more fine-grained control over who can do what, it can be used in situations other than you've anticipated.
And used to set up a system that's more secure. Michael Brouwere So, we're aiming to make it scale all the way from my mother using her iMac at home to a corporate or government institution that needs a totally secure system. and it's flexible. And like I said before, we're doing explicit, you're making explicit access control decisions rather than just doing it ad hoc.
So, here's the recommended architecture for you writing an application. The application is your actual app with the GUI and whatnot. The tool is the component of your application which will run with elevated privileges. There are different ways to make that happen. One of the ways is to have the installer install a setuidroot component. So your application will launch the tool on demand when it needs to perform a privilege operation.
Now, there's a third thing in this picture which is a security server, and that's a process running on Mac OS X all the time, which is essentially the part of the system that holds onto all the security-sensitive information. It's--for example, it's the basis for storing keys in the keychain, and it's the basis for storing state for the Authorization API, as you'll So, first thing that happens is your application obtains authorization to perform a certain operation.
The security server will actually go out and do any necessary UI at this point. So, even if your application is not actually a GUI app, but let's say it's a command line tool or some other application, we can still do UI for you if you pass us the flag saying do whatever UI is needed. The security server actually launches a separate process and does the UI there.
So, it doesn't matter whether you're Carbon or Cocoa or whatever, we'll present the UI in a consistent way to the user. So now, after you've obtained the authorization, the security server remembers some state about the fact that you've gotten this authorization. The next thing is you externalize that authorization and pass it from your application to your tool. And there are a couple of different ways to do that and I'll show you that later. Okay.
Then, the tool, which is a Situated Root program, which means that anyone can execute it and potentially have it do something, before it does anything at all, the first thing it does is it checks the rights of the passed in authorization to see if they allow what the tool has been asked to do by the application.
So, even though your tool is actually running with elevated privileges, it won't do anything unless, unless, unless you've, you know, you've checked and made sure that what you've been asked to do is actually allowed. And finally, the tool performs the operation. And you can launch the tool each time you do this, or you can write a tool that keeps on running as long as your application runs. There's different models for this.
So, a little bit about what it does and doesn't do. Currently, it's password-based only using that info. So that means that it uses users and groups from that info and you authenticate using a password just like when you log into Mac OS X. It answers the "Do I have the right to do this?" question, but it doesn't in and of itself grant access.
You still need--you need to already be privileged and have the privileges to perform the operation. Authorization API in and of itself doesn't give you the privilege to do it, but what it helps you do is determine whether or not you should do it. So it lets you make tools that don't compromise system security. And it's up to the administrator of the system, whether that be you, the owner, or some actual administrator in the lab, to determine who can do what rather than you having to make that decision.
Michael Brouwere So, just to make this clear, Mac OS X is not a capability-based operating system. There aren't really any capability-based commercial operating systems out there today. It would be really cool to have that, which would basically mean that in asking for the right to do something, you would now also be able to do it. Unfortunately, that's not something that Kernel and the whole Unix environment supports today. There is some work going on in that.
Michael Brouwere So, the reason why we're doing this is because we're not really going to be able to do it. We're not going to be able to do it in the open source community and in other communities. So, maybe a couple years down the road, we will have that. Just today, the Authorization API lets you solve this problem by splitting your app into two components.
And finally, we provide user interaction when necessary, so you don't have to go and program the UI for getting all this information, et cetera. One thing I do want to say is that even though today it's password-based only, we are looking into making the backend for the Authorization API pluggable, which means we might support other forms of authentication in the future. Think of smart card-based or biometrics and whatnot.
and when that happens, your applications won't have to change, which means if you're using the Authorization API today and those things get added to the system, if an administrator configures it that you need a smart card to reboot your server, then that automatically happens without you or need a smart card to access the administration interface of your database engine or whatever it is that you wrote. That'll happen without you having to rev your product.
So, a little bit about the API itself. First thing, the naming of rights. Authorization API works with things called rights. Basically, you ask for the right to perform a certain operation, and a right is really nothing more than a string, a C string. We have some proposed naming for rights. Of course, we list a number of rights that we internally use in the system, but we can't predict which rights your application would want to use.
I mean, an example of a right might be com.mycompany.initialize.database, which we can't predict what kind of operations you want to perform authorization for. So, you get to make a list of rights. And then, once you make up those names for rights, we'll give you some guidelines on what they should look like.
[Transcript missing]
So, naming of writes. Writes are mapped into a hierarchical namespace, sort of like a DNS-like with dots. We define like different high level domains, but like I said, we don't define each individual write since the needs of each application are different. And some example of write names that we currently use would be system.logon.console, which is the ability to log on in login window. System.logon.remote would be... The ability to log on, let's say, through Telnet. You could further qualify that, let's say, system.login.remote.telnet, system.login.remote.rlogin, etc. One of the things we allow in the configuration is wildcard matching on prefixes of write names.
So that means if you choose your hierarchy of names, you might want to think of it in a--you might want to name writes in a way that if someone puts some prefix star, it actually makes sense for your application so that you'd qualify the details towards the end of the name. We explicitly didn't want to allow for, like, arbitrary regular expressions of write names in the rules configuration because if we do that, it's going to be very unclear which rule gets matched in certain situations for an administrator.
So we want to try and keep it simple so that someone administering this can actually understand this can actually understand what's going to happen in a particular situation. And there's some others here. One that's the particularly noticeable one is the system.privilege.admin, which is the right that gives you the ability to run an arbitrary process as a root using the API for installers.
So, like I said before, application communication, one of the things it enables you to do is to split off, I can't stress this enough, is to split off the security sensitive operations into small well understood tools that are auditable, that don't depend on like the entire OS 10 stack and don't depend on core graphics and whatnot and App Kit and Carbon so that the amount of code running with elevated privileges is as little as possible and you actually know what's going on there. and to do that we provide APIs to pass authorization tokens between processes.
So, there's a slight, something I didn't mention before, there's a slight difference between authorization and pre-authorization, and that's when an application asks for authorization in the original first step, it would be, let's say you present a button that says, "Press this button to unlock the UI so you can make changes to the administrator," whatever. That's called pre-authorization.
At that point, you're asking for permission to do something in the future, but you're not actually doing it at this point. When you actually go off in your tool and perform the operation, you're doing actual authorization. And the reason we want to make that distinction is that certain operations might be so sensitive that we don't, that an administrator doesn't want to allow them to be pre-authorized.
Which means when you do the pre-authorization, you'll get an answer back saying, "Yes, you can do that." And then you'll be like, "Yes, you can do this, but we can't confirm it until later, until you actually go and do it." In Mac OS X today, whenever you ask for a write in the current configuration, things can be pre-authorized and your authorization stays valid for five minutes, which basically means if you go into one app and authorize to a panel there using admin privileges, you go to a different app, you're still authorized for the next five minutes, which we chose to do this. It's a slight balance between security and usability.
It means that the traditional OS 9 user, after you log in, if you go directly to system preferences and make some changes, you're still authorized. Five minutes later, you're not. You'd be asked for your password again. It also means if you go to 15 different panels, it's all have different writes. You don't have to type your password 15 different times if you're changing them all at once.
Of course, in more security-sensitive environments, people might want to tighten that down, which we allow for. The decision whether or not that happens actually happens in the configuration rather than in your application. If you're alarmed about this happening today and you might want to think about trying to tie that down, we recommend you not do that because we really want to have the administrator be able to control how that works rather than the application developers.
So, the first thing that happens is that with the pre-authorization, I should probably skip to the next slide and come back to this later. So I'll get back to this one in a second. First thing that happens when you're using the Authorization API is you create an authorization ref, which is basically a handle to the security server that represents the rights you have.
You can create an authorization ref and figure out what's currently allowed by using copyrights. The way you use copyrights is you ask for all the rights--you list all the rights that you might potentially be interested in having and figure out which of them are currently allowed. Since, like I said before, we have this notion of this five-minute timeout by default, it could be that when your app gets launched, it's already allowed to do everything you would possibly ever want to do, in which case you show your UI unlocked and show all the fields editable. Okay.
If it's not, you can lock down the UI and when the user wants to make changes by clicking a button or some other, whatever UI you want to use for that, I mean, traditionally OS X uses a little press to the lock button to make changes here. So that's probably what you should do if you want to be consistent.
You perform a pre-authorization using copyrights, which the pre-authorization basically just means you're passing an extra flag to copyrights saying, please do a pre-authorization instead of a regular one. And you ask for the same rights again. The only difference is this time you say, and do any UI that's needed to get these rights. In which case, we'll go off, do the UI, and extend whatever rights you have to match what you're asking for.
If your application is willing to deal with only getting part of the rights that you need, you can pass a flag for that and you'd have to check the returned rights to see which of the ones you've asked for have actually come in. So if you want all or nothing, you just don't ask for partial rights and will fail if you don't get everything you asked for.
Then you can pass that authorization ref to your privileged tool or daemon by calling authorization externalize or create external form, I think is what the API is called. And then we get to the tool. So you pass that ref to your tool, preferably through any method other than the environment or command line arguments, since Both of those can actually be snooped by running PS. So you'd want to pass it out through pipe or using CF messages or Mach IPC or whatever communication mech-- There's a number of different communication mechanisms available on OS X. We just recommend you not do it through the environment, the Unix environment or the command line.
So then your tool calls create from external to basically create the authorization ref, which is essentially the same one as in the application. And then it calls copyrights to determine whether the right that is needed to do what it needs to do has been granted. Michael Brouwer When it's doing that, it can also pass in the flag saying, "And do any UI that's needed to really have this happen." Which means that even though your tool isn't a Cocoa or Carbon or whatever app, we'll still go off and do whatever UI is needed to make the actual operation happen.
Which, the reason we want you to do that is if for some reason a particular operation can't be preauthorized, the UI won't actually happen until you get here. So if you don't pass that flag, in certain setups, the operation will not be able to be preauthorized. might fail. And then you perform the requested operations if copyright says you can.
So, just coming back to this slide, the pre-authorization again, you... do the preauthorization-- is my mic still on? You do the preauthorization in the app, but not in the tool. And so one of the other reasons we want you to have the preauthorization is to keep the final call to copyrights as close as possible to the operation. So you make the call, saying, this is when I'm going to do it, and then do it.
This also allows us to add audit logging to the authorization system in the future, which means we could actually track what things have actually been done on the system, which rights have been granted to which processes. And so that you could later go back and look and see who's done what to your computer.
And it allows for a zero length timeout, which essentially means that you have to enter the password or whatever authentication is needed to perform this right exactly when it happens, rather than having it be valid for the next five minutes. And for example, removable tokens like smart cards and things like that in the future.
So, strange title for this slide, but this is what the UI currently looks like that we present. This is actually directory setup. I don't know if any of you have been to that session. So it presents a dialog that, with a text telling the user, you need to enter administrator name and password to make changes in directory setup.
So, this is what the UI looks like. One of the things we'd like to have some feedback on is ways to improve this. I know that there's been some comments from people where you would like to have the UI be more custom to your application. And during the Q&A we can go over some of those things.
One of the issues we have is we don't want to have it be possible for the application to mislead the user in what he's really granting access to. So, there needs to be balance between how much of the user is really granted access to the UI and how much of the user is not granted access to the UI.
So, there needs to be balance between how much of the user is really granted access to the UI and how much of the user is not granted access to the UI. can be customized. So right now we actually hint the user name of the current user that's logged in if he would be allowed to perform that operation.
And like I said, we're looking into ways to making all of this pluggable, which means you actually, as a plug-in developer, be able to provide your own completely custom UI that says put your finger on the fingerprint reader or enter your magic passphrase now or whatever, or speak your name.
So, finally is the temporary solution for third party installers, and that's the API is called Authorization Execute with Privileges. The right required to use that is system.privilege.admin. So basically you need to create an authorization ref that grants the right system.privilege.admin, and then you can call system--call Authorization Execute with Privileges. Now, this is a way to sort of work around the problem of having to be installed, set your ID root and whatnot, and just launch your tool with root privileges.
However, depending on what the right is that your tool is needing to do, let's say if it's a web server and all it's really doing is binding to port 80, we can configure it in such a way that the asking for the right to bind to port 80 really doesn't do any UI at all in the common case because it's like, well, if my mother launches her personal web sharing, why should she have to enter an admin password? If you're using this API, we're always going to do UI.
So we really--because basically we're letting you execute an arbitrary binary with root privileges. And this is currently the only way to do it on OS X other than going through sudo on the command line. So, it's there, but we'd really like you to use the Authorization API as I've talked about the rest of the session, rather than just shortcut everything and use this API.
[Transcript missing]
You ask for a right to do something, having that right doesn't actually let you do it yet. You still need to actually have those privileges in the first place to be able to perform the operation. So like I said before, what we do is help you make the decision of should I do this on behalf of the user.
Your application should not run with root privileges. You want to split that off into the separate tool. And you want to pre-authorize the rights, then pass them to the tool, and then actually do the operation. And finally, keep the privilege tool as small as possible and audit it.
I can't stress this enough. I mean, any of you familiar with Unix or Linux know that anything that's set your ID root, or anything that even isn't set your ID root but you run using authorization execute with privileges, needs to be very carefully examined because any potential security hole in that can compromise the whole system.
So here are some resources to go look at. There's a developer page. The CDSA spec, all of our security work that we've been doing in the last two years is based on CDSA 2.0, which is an open group standard. And all of the work CDSA and below, actually even up to the Authorization API, is now open source and is available on the cvs.opensource.apple.com server.
And you can follow the PCSC links for the smart card access stuff. So, there's a number of related sessions. There's a security overview that you already missed. and there's a Kerberos session later this week. Actually, there's also a Keychain session right after this session, which is well worth attending if you're interested in security.
And then finally there's the feedback forum. So any questions that you can't get answered today, you can all come to the feedback forum and talk about it there. Craig, who was here before me, is the person in contact with any technical or developer questions related to this. And he'll make sure it gets forwarded to the appropriate people in our team.