Created
August 10, 2017 07:08
-
-
Save tristanmorgan/8fe883f89db4537ce35e0a23f6a537b6 to your computer and use it in GitHub Desktop.
An attempt at calling Hashicorp Vault IAM Auth backend in Ruby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Authenticate via the AWS EC2 authentication method (IAM method). If authentication is | |
# successful, the resulting token will be stored on the client and used | |
# for future requests. | |
# | |
# @example | |
# Vault.auth.aws_ec2_iam("dev-role-iam", "vault.example.com") #=> #<Vault::Secret lease_id=""> | |
# | |
# @param [String] role | |
# @param [String] iam_auth_header_value | |
# | |
# @return [Secret] | |
def aws_ec2_iam(role, iam_auth_header_value) | |
uri_string = 'http://169.254.169.254/latest/dynamic/instance-identity/document' | |
uri = URI.parse(uri_string) | |
http = Net::HTTP.new(uri.host, uri.port) | |
request = Net::HTTP::Get.new(uri_string) | |
document = JSON.parse(http.request(request)) | |
uri_string = 'http://169.254.169.254/latest/meta-data/iam/security-credentials/' | |
uri = URI.parse(uri_string) | |
http = Net::HTTP.new(uri.host, uri.port) | |
request = Net::HTTP::Get.new(uri_string) | |
response = http.request(request) | |
uri_string += response | |
uri = URI.parse(uri_string) | |
http = Net::HTTP.new(uri.host, uri.port) | |
request = Net::HTTP::Get.new(uri_string) | |
credentials = JSON.parse(http.request(request)) | |
t = Time.now.utc | |
amzdate = t.strftime('%Y%m%dT%H%M%SZ') | |
date_stamp = t.strftime('%Y%m%d') | |
region_name = document['region'] | |
k_date = OpenSSL::HMAC.digest('sha256', 'AWS4' + credentials['SecretAccessKey'], date_stamp) | |
k_region = OpenSSL::HMAC.digest('sha256', k_date, region_name) | |
k_service = OpenSSL::HMAC.digest('sha256', k_region, 'iam') | |
k_signing = OpenSSL::HMAC.digest('sha256', k_service, 'aws4_request') | |
iam_auth_header_value ||= IAM_SERVER_ID_HEADER | |
request_body = Base64.strict_encode64('Action=GetCallerIdentity&Version=2011-06-15') | |
headers_hash = { | |
'Content-Length' => [request_body.length.to_s], | |
'User-Agent' => ['aws-sdk-go/1.4.12 (go1.7.1; linux; amd64)'], | |
'X-Vault-AWSIAM-Server-Id' => [iam_auth_header_value], | |
'X-Amz-Date' => [amzdate], | |
'Content-Type' => ['application/x-www-form-urlencoded; charset=utf-8'], | |
'Authorization' => [ | |
"AWS4-HMAC-SHA256 Credential=#{credentials['AccessKeyId']}/#{date_stamp}/#{region_name}/iam/aws4_request, "\ | |
"SignedHeaders=content-length;content-type;host;x-amz-date;x-vault-server, Signature=#{k_signing}" | |
] | |
} | |
payload = { | |
role: role, | |
iam_http_request_method: 'POST', | |
iam_request_url: Base64.strict_encode64('https://sts.amazonaws.com/'), | |
iam_request_headers: Base64.strict_encode64(JSON.dump(headers_hash)), | |
iam_request_body: request_body | |
} | |
json = client.post('/v1/auth/aws/login', JSON.fast_generate(payload)) | |
secret = Secret.decode(json) | |
client.token = secret.auth.client_token | |
secret | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have some errors here as found by @maschwenk in hashicorp/vault-ruby#161 , but I'm happy I got things moving a little further on this.