Amazon Web Services API Security
Here’s an obvious question when dealing with third-party proxies: If these tools act on your behalf, how does Amazon Web Services (AWS) know that the person on whose behalf they’re acting is in fact you? In other words, how can AWS authenticate your identity to ensure that the commands it receives are from you?
In fact, the same question is valid even if you interact with the AWS API directly. How can AWS validate your identity to ensure that it executes commands only for you?
One way, of course, is for you to include your account username and password in the API calls. Though some cloud providers take this approach, Amazon does not.
Rather than rely on a username and password, it relies on two other identifiers to authenticate its API service calls: the access key and the secret access key. It uses these keys in service calls to implement security in a way that’s much more secure than using only your username and password.
So how does it work? When you sign up for an account with AWS, you have the opportunity to create an access key and to have a secret access key sent to you. Each one is a lengthy string of random characters, and the secret access key is the longer of the two. When you download the secret access key, you should store it somewhere very secure because it is the key (sorry — bad pun) to implementing secure service calls.
After you do this, both you and Amazon have a copy of the access key and the secret access key. Retaining a copy of the secret access key is crucial because it’s used to encrypt information sent back and forth between you and AWS, and if you don’t have the Secret Access Key, you can’t execute any service calls on AWS.
The way the two keys are used is conceptually simple, although somewhat challenging in detail.
Essentially, for every service call you want carried out, you (or a tool operating on your behalf) do the following:
Create the service call payload.
This is the data you need to send to AWS. It may be an object you want to store in S3 or the image identifier of an image you want to launch. (You’ll also attach other pieces of information to the payload, but because they vary according to the specifics of the service call, they’re not listed here. One piece of data is the current time.)
Encrypt the payload using the secret access key.
Doing so ensures that no one can examine the payload and discover what’s in it.
Digitally sign the encrypted payload by adding the secret access key to the encrypted payload and performing a digital signature process using the secret access key.
Secret access keys are longer and more random than typical user passwords; the lengthy secret access key makes the encryption performed with it more secure than it would be if it were performed with a typical user password.
Send the total encrypted payload, along with your access key, to AWS via a service call.
Amazon uses the access key to look up your secret access key, which it uses to decrypt the payload. If the decrypted payload represents readable text that can be executed, AWS executes the service call. Otherwise, it concludes that something is wrong with the service call (perhaps that it was called by a malevolent actor) and doesn’t execute the service call.
In addition to the encryption just described, AWS has two other methods it uses to ensure the legitimacy of the service call:
The first is based on the date information included with the service call payload, which it uses to determine whether the time associated with the making of the service call is appropriate; if the date in the service call is much different from what it should be (much earlier or later than the current time, in other words), AWS concludes that it isn’t a legitimate service call and discards it.
The second additional security measure involves a checksum you calculate for the payload. (A checksum is a number that represents the content of a message.) AWS computes a checksum for the payload; if its checksum doesn’t agree with yours, it disallows the service call and doesn’t execute it.
This checksum approach ensures that no one tampers with the contents of a message and prevents a malevolent actor from intercepting a legitimate service call and changing it to perform an unacceptable action. If someone tampers with the message, when AWS calculates a checksum, that checksum no longer matches the one included in the message, and AWS refuses to execute the service call.
If, like most AWS users, you use a proxy method to interact with AWS — the AWS management console, a language library, or a third-party tool — you need to provide your access key and secret access key to the proxy. When the proxy executes AWS service calls on your behalf, it includes the access key in the call and use the secret access key to perform payload encryption.
Because of the critical role that these keys fulfill in AWS, you should share them only with entities you trust. If you want to try out a new third-party tool and you don’t know much about the company, set up an AWS test account for the trial instead of using your production AWS account credentials.
That way, if you decide not to go forward with the tool, you can drop it, terminate the test AWS account, and move forward, unconcerned about potential security vulnerabilities in your main production accounts. Of course, you can always create new access keys and secret access keys, but using your production keys for tests and then changing the keys creates a lot of work, because you need to update every place that makes reference to your existing keys.
If you’re like many other AWS users, you’ll use a number of tools and libraries, and going back to them to update your keys is a pain. You’re better off using nonproduction accounts to test new tools.