aws-sdk-rails: the Rails wiring behind AWS SDK calls
Official repository for the aws-sdk-rails gem, which integrates the AWS SDK for Ruby with Ruby on Rails.
At a glance
- What is it?
- The aws-sdk-rails gem connects the AWS SDK for Ruby to a Rails application: session storage, mailers, job queues, logging and ActiveSupport notifications. Its Elastic Beanstalk worker middleware is the part with the sharpest edges.
- Who is it for?
- This gem suits Rails applications already running on AWS that want mail delivery through SES, sessions in DynamoDB, an SQS job backend or per-call instrumentation, and it suits almost nobody else. Do not adopt it if you only need a handful of API calls, since the underlying SDK gems are usable on their own.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 15 days ago.
- What is it written in?
- Mainly Ruby, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the plugin wires into a Rails application
The repository describes itself as a Ruby on Rails plugin that integrates AWS services with your application using the latest version of the AWS SDK for Ruby. Most of the value is in the integration points rather than in the AWS calls themselves, and the README lists them plainly: ActionDispatch DynamoDB session storage, ActionMailer delivery with Amazon Simple Email Service, ActionMailbox ingress with Amazon Simple Email Service, an ActiveJob SQS adapter, and AWS Record generators.
Each of those points at a separate gem rather than living in this repository, so aws-sdk-rails is a coordinating layer. The one piece implemented here directly is the ActiveSupport::Notifications instrumentation, which is enabled by default for every AWS SDK call. There is also a small Elastic Beanstalk specific middleware in lib/, described later, that turns SQS messages into ActiveJob executions on Elastic Beanstalk worker environments.
Adding the gem and the credential chain
Installation is a single line in the Gemfile. The gem depends on aws-sdk-core, which comes along with it.
gem 'aws-sdk-rails', '~> 5'Credentials are not part of that line, and the README is explicit that you must provide them yourself. It points to the AWS SDK for Ruby configuration documentation for the details. On Amazon EC2, the SDK checks instance metadata for credentials to load, using the IAM roles for Amazon EC2 mechanism. On a laptop or in CI, the SDK's own chain applies, which includes shared profiles in ~/.aws/credentials. The plugin does not invent a credential scheme of its own; it just sits on top of whatever the SDK already resolves, and that distinction matters when debugging a deployment.
Encrypted Credentials outrank environment credentials
For Rails 5.2 and later, the plugin will decrypt the application's encrypted credentials and load them under the :aws top level key. The README shows the shape of that file, including the command that opens it in an editor.
# config/credentials.yml.enc
# viewable with: `bundle exec rails credentials:edit`
aws:
access_key_id: YOUR_KEY_ID
secret_access_key: YOUR_ACCESS_KEY
session_token: YOUR_SESSION_TOKEN
account_id: YOUR_ACCOUNT_IDThe rule that catches people out is precedence. Encrypted Credentials take precedence over any other AWS credentials that may exist in your environment, for example credentials from profiles set in ~/.aws/credentials. On a developer machine that can mean the local key wins over the one you expected. The same mechanism covers ActiveStorage: if you use ActiveStorage with S3, you do not need to specify credentials in your storage.yml configuration because they are loaded automatically.
Every SDK call publishes a notification
Instrumentation is on by default, with one event published per client operation call. The event name has three parts: the operation, the service identifier, and the aws suffix, so S3's :put_object produces put_object.S3.aws. The service name always matches the namespace of the service client, for example Aws::S3::Client maps to S3, and the event payload is the SDK request context.
Subscribing works exactly as it does for other ActiveSupport::Notifications, either by exact event name or by regular expression.
ActiveSupport::Notifications.subscribe('put_object.S3.aws') do |name, start, finish, id, payload|
# process event
endA regex subscription catches every operation for one service, which is the convenient form when you want latency or error rates per service rather than per call.
# Or use a regex to subscribe to all service notifications
ActiveSupport::Notifications.subscribe(/S3[.]aws/) do |name, start, finish, id, payload|
# process event
endBecause instrumentation is enabled rather than opt-in, an application that subscribes to all notifications will see every AWS call in the same stream as its database and cache activity.
The Elastic Beanstalk worker middleware and its allowlist
This is the part of the plugin with security weight. Elastic Beanstalk worker environments can run ActiveJob without managing a worker process. The worker is configured to read from the SQS queue you want processed, and the AWS_PROCESS_BEANSTALK_WORKER_REQUESTS environment variable is set to true in the worker environment configuration. The SQS daemon posts messages to http://localhost/, and the ElasticBeanstalkSQSD middleware forwards each request to the appropriate job.
Two guards apply. Only job classes inheriting from ActiveJob::Base are executed, and you can restrict further with an allowlist checked in an initializer.
# config/initializers/aws.rb
Aws::Rails::Middleware::ElasticBeanstalkSQSD.configure do |config|
config.job_class_allowlist = [SomeJob, AnotherJob]
endThe allowlist is checked before the class name is resolved, so a request naming a class outside the list cannot cause that class to be loaded, and it applies to periodic task names from cron.yaml as well as to job messages. The middleware only processes requests from the SQS daemon and passes others on, so it does not interfere with other routes.
Port 80 and the Docker gateway caveat
The README is unusually blunt about the remaining risk, and the caveat is worth reading in full before deploying. The middleware only accepts daemon requests whose TCP peer address is loopback or the Docker gateway, which cannot be forged with a request header. On Docker based Elastic Beanstalk platforms, however, inbound traffic is proxied into the container by the host, so its peer address is genuinely the Docker gateway regardless of where the request originated.
The conclusion the README draws is that network level controls are the primary safeguard, with job_class_allowlist limiting what a request that does get through can reach. In practice that means the worker environment's port 80 must not be accessible from outside the instance, for example through security group rules. The allowlist is a second line of defence, not the first, and the header cannot be relied on to distinguish a legitimate daemon request on those platforms. Anyone enabling this feature on a Docker based worker should treat the security group rules as the actual control.
Long running jobs time out unless queued asynchronously
By default the middleware processes jobs synchronously and does not complete the request until the job has finished executing. The README states that for long running jobs, exceeding the configured nginix timeout on the worker, this may cause timeouts and incomplete executions.
The fix is a second environment variable, AWS_PROCESS_BEANSTALK_WORKER_JOBS_ASYNC, set to true in the worker environment. Jobs are then queued in a ThreadPoolExecutor and the request returns without waiting for completion. The trade is straightforward. Synchronous processing gives you a clear success or failure per delivery and no state to manage, at the price of tying the request to the job. Asynchronous processing keeps the daemon request short and survives the proxy timeout, at the price of jobs that fail after the response has already been sent, which means failures surface in the queue rather than in the request.
Eager loading, logging and release cadence
Two smaller behaviours are worth knowing. The AWS SDK is configured to use the built-in Rails logger for its output at the:info level, and the level can be changed through the:log_level key in Aws.config.
Aws.config.update(log_level: :debug)Separately, an initializer eager loads the AWS SDK, which you enable in config/application.rb.
config.eager_load = trueOn maintenance, the release list shows v5.0.0 on 2024-11-21, v5.1.0 on 2024-12-05 and v5.2.0 on 2026-08-11, and the last push was on 2026-10-08, so the 5.x line is still being worked on. The repository ships CHANGELOG.md, a Rakefile, tasks/, spec/, sample-app/ and doc-src/, and the recommended '~> 5' pin keeps you inside that line. One administrative note: the licence field is a custom one that GitHub cannot classify, and the terms live in LICENSE.txt at the repository root. Read that file rather than assuming the permissive licences of the surrounding AWS gems.
Editorial conclusion
This gem suits Rails applications already running on AWS that want mail delivery through SES, sessions in DynamoDB, an SQS job backend or per-call instrumentation, and it suits almost nobody else. Do not adopt it if you only need a handful of API calls, since the underlying SDK gems are usable on their own. Verify first which of the companion gems you actually need, confirm that the Elastic Beanstalk worker's port 80 is unreachable from outside the instance if you use the SQS daemon middleware, and check LICENSE.txt before shipping it, since the repository carries a custom licence rather than a standard open source one.
Frequently asked questions
How do I install the aws-sdk-rails gem in a Rails application?
Add gem 'aws-sdk-rails', '~> 5' to the Gemfile, and bundle it as usual. The gem also pulls in aws-sdk-core, and you still have to supply credentials for the SDK to use.
Where does aws-sdk-rails look for AWS credentials?
On Amazon EC2 the SDK checks instance metadata for credentials to load through IAM roles. For Rails 5.2 and later, encrypted credentials are decrypted and loaded under the :aws top level key, and those take precedence over other credentials in your environment such as profiles in ~/.aws/credentials.
How do I limit which jobs the Elastic Beanstalk SQS middleware will run?
Configure the allowlist in config/initializers/aws.rb with Aws::Rails::Middleware::ElasticBeanstalkSQSD.configure and set config.job_class_allowlist. The check happens before the class name is resolved, and it also applies to periodic task names from cron.yaml.
Can I subscribe to notifications for every AWS SDK call in aws-sdk-rails?
Yes. Instrumentation is enabled by default for all SDK calls, events are named <operation>.<serviceId>.aws, for example put_object.S3.aws, and you can subscribe with a regex such as /S3[.]aws/ to catch all operations for one service.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/aws-aws-sdk-rails)Was this useful?