Last active
December 13, 2022 13:18
-
-
Save francesco-racciatti/c90a302d1c7b426fa9ac937df369c5a3 to your computer and use it in GitHub Desktop.
Interact with AWS API via cURL
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
#!/bin/bash | |
set -ex | |
# References: | |
# - https://docs.aws.amazon.com/general/latest/gr/create-signed-request.html#create-canonical-request | |
# - https://docs.aws.amazon.com/secretsmanager/latest/apireference/Welcome.html | |
sha256() { | |
local data="$1" | |
echo $(echo -e -n "$data" | openssl dgst -sha256 | sed 's/(stdin)=[[:space:]]//') | |
} | |
hmacSha256() { | |
local key="$1" | |
local data="$2" | |
echo $(echo -e -n "$data" | openssl dgst -sha256 -mac HMAC -macopt $key | sed 's/(stdin)=[[:space:]]//') | |
} | |
callAwsApi() { | |
local service="$1" | |
local target="$2" | |
local requestPayload="$3" | |
# Step 0 - Fetch ECS metadata | |
local metadataHost=$(echo "$ECS_CONTAINER_METADATA_URI_V4" | grep -Eo "([0-9]{1,3}[\.]){3}[0-9]{1,3}") | |
local ecsSecrets=$(curl http://$metadataHost$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) | |
local accessKeyId=$(jq -r '.AccessKeyId' <<< $ecsSecrets) | |
local secretAccessKey=$(jq -r '.SecretAccessKey' <<< $ecsSecrets) | |
local token=$(jq -r '.Token' <<< $ecsSecrets) | |
local amzDateAndTime=$(date -u +"%Y%m%dT%H%M%SZ") | |
local date=$(date -u +"%Y%m%d") | |
local region=$AWS_REGION | |
local host="$service.$region.amazonaws.com" | |
local endpoint="https://$host/" | |
# Step 1 - Create Canonical Request | |
local httpMethod="POST" | |
local canonicalURI="/" | |
local canonicalQueryString="" | |
local canonicalHeaders="content-type:application/x-amz-json-1.1\nhost:$host\nx-amz-date:$amzDateAndTime\nx-amz-security-token:$token\nx-amz-target:$target" | |
local signedHeaders="content-type;host;x-amz-date;x-amz-security-token;x-amz-target" | |
local hashedPayload=$(sha256 $requestPayload) | |
local canonicalRequest="$httpMethod\n$canonicalURI\n$canonicalQueryString\n$canonicalHeaders\n\n$signedHeaders\n$hashedPayload" | |
# Step 2 - Create a hash of the Canonical Request | |
local canonicalRequestHash=$(sha256 $canonicalRequest) | |
# Step 3 - Create the string to sign | |
local algorithm="AWS4-HMAC-SHA256" | |
local requestDateTime="$amzDateAndTime" | |
local credentialScope="$date/$region/$service/aws4_request" | |
local hashedCanonicalRequest="$canonicalRequestHash" | |
local stringToSign="$algorithm\n$requestDateTime\n$credentialScope\n$hashedCanonicalRequest" | |
# Step 4 - Calculate the signature | |
local kDate=$(hmacSha256 "key:AWS4$secretAccessKey" $date) | |
local kRegion=$(hmacSha256 "hexkey:$kDate" $region) | |
local kService=$(hmacSha256 "hexkey:$kRegion" $service) | |
local kSigning=$(hmacSha256 "hexkey:$kService" "aws4_request") | |
local signature=$(hmacSha256 "hexkey:$kSigning" "$stringToSign") | |
# Step 5 - Add the signature to the request | |
curl -vvv $endpoint \ | |
-X $httpMethod \ | |
-H "content-type: application/x-amz-json-1.1" \ | |
-H "host: $service.$region.amazonaws.com" \ | |
-H "x-amz-date: $amzDateAndTime" \ | |
-H "x-amz-target: $target" \ | |
-H "x-amz-content-sha256: $hashedPayload" \ | |
-H "x-amz-security-token: $token" \ | |
-H "authorization: $algorithm Credential=$accessKeyId/$date/$region/$service/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-security-token;x-amz-target, Signature=$signature" \ | |
-d $requestPayload | |
} | |
fetchAsmSecret() { | |
local secretId="$1" | |
local service="secretsmanager" | |
local target="$service.GetSecretValue" | |
local requestPayload="{\"SecretId\":\"$secretId\"}" | |
callAwsApi $service $target $requestPayload | |
} | |
checkBinaries() { | |
local binaries=(curl openssl jq) | |
for b in "${binaries[@]}" | |
do | |
if ! command -v $b &> /dev/null | |
then | |
echo "$b could not be found" | |
exit 1 | |
fi | |
done | |
} | |
checkBinaries | |
fetchAsmSecret $1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment