Skip to content

Instantly share code, notes, and snippets.

@tpaulshippy
Created May 14, 2025 13:02
Show Gist options
  • Select an option

  • Save tpaulshippy/1dd00f761a2f690ecd8ccacc9611b637 to your computer and use it in GitHub Desktop.

Select an option

Save tpaulshippy/1dd00f761a2f690ecd8ccacc9611b637 to your computer and use it in GitHub Desktop.
AWS credential provider example
# frozen_string_literal: true
require 'aws-sdk-core'
require_relative 'errors'
module MyApp
# Manages AWS credentials with automatic refresh capability
class AwsCredentialProvider
class << self
def instance
@instance ||= new
end
end
def initialize
refresh_credentials!
end
def access_key_id
refresh_if_expired!
@credentials&.access_key_id
end
def secret_access_key
refresh_if_expired!
@credentials&.secret_access_key
end
def session_token
refresh_if_expired!
@credentials&.session_token
end
attr_reader :expiration
def refresh_credentials!
fetch_and_set_credentials
end
def refresh_if_expired!
return unless expired?
refresh_credentials!
end
private
def fetch_and_set_credentials
if use_mock_credentials?
set_mock_credentials
else
fetch_and_set_real_credentials
end
end
def use_mock_credentials?
ENV['RAILS_ENV'] == 'test'
end
def set_mock_credentials
@credentials = Aws::Credentials.new(
'mock_access_key_id',
'mock_secret_access_key',
'mock_session_token'
)
@expiration = Time.now + 3600 # 1 hour
end
def fetch_and_set_real_credentials
ecs_credentials = Aws::CredentialProviderChain.new.resolve
raise ConfigurationError, 'Could not resolve AWS credentials' if ecs_credentials.nil?
refresh_if_supported(ecs_credentials)
assign_credentials(ecs_credentials)
end
def refresh_if_supported(credentials)
credentials.refresh! if credentials.respond_to?(:refresh!)
end
def assign_credentials(ecs_credentials)
if ecs_credentials.respond_to?(:credentials)
@credentials = ecs_credentials.credentials
@expiration = ecs_credentials.expiration if ecs_credentials.respond_to?(:expiration)
else
@credentials = ecs_credentials
@expiration = nil
end
end
def expired?
return false if @expiration.nil?
return true if @credentials.nil?
# Refresh if we're within 5 minutes of expiration
@expiration < Time.now + 300
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment