Credential Management - Part 1

When using AWS, it is important to keep your access credentials secure. It can be challenging to make your credentials available to your application securely. The AWS SDK for Ruby provides a number of helpful interfaces for configuring your credentials that help you keep your secrets safe.

This blog post focuses on securely configuring the aws-sdk gem with your credentials. I will follow up with additional blog posts about rotating credentials, and using roles for instances.

Credential Configuration

The aws-sdk gem requires that you provide your access credentials before making a request. The gem tries to locate your credentials in a number of default locations. If it is unable to find your credentials, it raises an error. The locations it searches are:

  • AWS.config
  • ENV
  • EC2 instance metadata
  • Rails Configuration (RAILS_ROOT/config/aws.yml)

AWS.config

You can use AWS.config to statically configure your credentials for all AWS requests. Simply call AWS.config with your :access_key_id and :secret_access_key (you may also provide a :session_token).

require 'aws-sdk'

AWS.config(:access_key_id => '...', :secret_access_key => '...')

Alternatively, you may provide credentials directly to the service interfaces. This can be helpful if you are working with multiple sets of credentials for multiple AWS accounts (or IAM users).

s3 = AWS::S3.new(:access_key_id => '...', :secret_access_key => '...')    

As tempting as it might be, you should never put access credentials in source code. This makes your secrets available to anyone with access to your source code. It also creates a maintenance burden when you need to rotate your credentials. There are many alternatives, including loading credentials from a configuration file that is not tracked with source control.

require 'aws-sdk'
require 'yaml'

# configure aws-sdk gem from a yaml configuration file
AWS.config(YAML.load_file(path_to_configuration_file))

In the preceding example, the YAML file might look like this:

:access_key_id: 'YOUR_ACCESS_KEY_ID'
:secret_access_key: 'YOUR_SECRET_ACCESS_KEY'

ENV

You can alternatively provide credentials to your application via ENV. By default, the aws-sdk gem searches ENV using two different prefixes for your keys ('AWS' and 'AMAZON').

ENV['AWS_ACCESS_KEY_ID']
ENV['AWS_SECRET_ACCESS_KEY']
ENV['AWS_SESSION_TOKEN']

EC2 Instance Metadata

The aws-sdk gem supports loading credentials from the instance metadata service on Amazon EC2 instances. If you have started your instance using an AWS IAM instance profile, this will just work, no configuration required. I will dive into this deeper in a followup blog post.

Credential Loading in Rails (RAILS_ROOT/config/aws.yml)

If you are using the aws-sdk gem in a Rails application, the gem attempts to load credentials from RAILS_ROOT/config/aws.yml. This file is ERB-parsed and then loaded by YAML. This file should be formatted in the same way as RAILS_ROOT/config/database.yml. It should have one top-level entry for the Rails.env you are running.

# RAILS_ROOT/config/aws.yml
development:
  access_key_id: DEV_ACCESS_KEY_ID
  secret_access_key: DEV_ACCESS_KEY_ID

If this file contains your secrets in plain text and does not use ERB to load them securely, you should not track this file with source control.

You can now read part two in this series: Rotating Credentials.

Comments