ruby-on-railsrspecrspec-railsrails-activestorageminio

Testing Ruby on Rails ActiveStorage direct upload by running S3 locally: authentication errors when trying to connect to MinIO


I would like to use S3-like storage also for my tests, and so I downloaded and installed MinIO on my machine. However when I run bin/bundle exec rspec --fail-fast spec/models/hanzi_spec.rb, I get authentication errors. I can't figure out to solve the error when running rspec:

An error occurred while loading ./spec/models/hanzi_spec.rb.
Failure/Error: require_relative '../config/environment'

Aws::Errors::InvalidSSOToken:
  Token is invalid and failed to refresh.
# ./config/environment.rb:5:in `<top (required)>'
# ./spec/rails_helper.rb:4:in `require_relative'
# ./spec/rails_helper.rb:4:in `<top (required)>'
# ./spec/models/hanzi_spec.rb:4:in `<top (required)>'
No examples found.

Finished in 0.00009 seconds (files took 5.67 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples

I have the feeling that somehow the test wants to use my production credentials, but I'm unable to find any documentation to investigate this further.

This is my config/storage.yaml:

test:
  # service: Disk
  # root: <%= Rails.root.join("tmp/storage") %>
  service: S3
  access_key_id: minioadmin
  secret_access_key: minioadmin
  bucket: storage
  endpoint: http://localhost:9000
  force_path_style: true

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

# Use bin/rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: eu-central-1
  bucket: mandarinbanana-default-<%= Rails.env %>

And in config/environments/test.rb I have config.active_storage.service = :test.

With running MinIO in the console I was able to upload a file using curl in the following script:

#!/bin/bash

# Usage: ./minio-upload my-bucket my-file.zip

bucket=$1
file=$2

host=localhost:9000
s3_key=minioadmin
s3_secret=minioadmin

resource="/${bucket}/${file}"
content_type="application/octet-stream"
date=`date -R`
_signature="PUT\n\n${content_type}\n${date}\n${resource}"
signature=`echo -en ${_signature} | openssl sha1 -hmac ${s3_secret} -binary | base64`

curl -X PUT -T "${file}" \
          -H "Host: ${host}" \
          -H "Date: ${date}" \
          -H "Content-Type: ${content_type}" \
          -H "Authorization: AWS ${s3_key}:${signature}" \
          http://${host}${resource}

So to me it looks like the MinIO configuration itself is fine; I basically didn't change anything. Of course I played around with bucket and access management, but reverted the changes each time. It should be equal to a vanilla configuration now.

Also, all the examples I found online didn't mention anything about specific authentication setup and seemed to work out of the box.

How can I solve the "InvalidSSOToken" error?


Solution

  • The aws-sdk-s3 gem is biased towards AWS and will look in your home folder for credentials in the .aws folder. Move ~/.aws to ~/.aws_backup to stop it and it will work.