\href{https://travis-ci.org/github/mhart/aws4}{\texttt{ }}

A small utility to sign vanilla Node.\+js http(s) request options using Amazon\textquotesingle{}s \href{https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html}{\texttt{ AWS Signature Version 4}}.

If you want to sign and send AWS requests in a modern browser, or an environment like \href{https://developers.cloudflare.com/workers/}{\texttt{ Cloudflare Workers}}, then check out \href{https://github.com/mhart/aws4fetch}{\texttt{ aws4fetch}} – otherwise you can also bundle this library for use \href{./browser}{\texttt{ in older browsers}}.

The only AWS service that {\itshape doesn\textquotesingle{}t} support v4 as of 2020-\/05-\/22 is \href{https://docs.aws.amazon.com/AmazonSimpleDB/latest/DeveloperGuide/SDB_API.html}{\texttt{ Simple\+DB}} (it only supports \href{https://github.com/mhart/aws2}{\texttt{ AWS Signature Version 2}}).

It also provides defaults for a number of core AWS headers and request parameters, making it very easy to query AWS services, or build out a fully-\/featured AWS library.\hypertarget{md_sfcode_node_modules_aws4_README_autotoc_md3623}{}\doxysection{Example}\label{md_sfcode_node_modules_aws4_README_autotoc_md3623}

\begin{DoxyCode}{0}
\DoxyCodeLine{var https = require('https')}
\DoxyCodeLine{var aws4  = require('aws4')}
\DoxyCodeLine{}
\DoxyCodeLine{// to illustrate usage, we'll create a utility function to request and pipe to stdout}
\DoxyCodeLine{function request(opts) \{ https.request(opts, function(res) \{ res.pipe(process.stdout) \}).end(opts.body || '') \}}
\DoxyCodeLine{}
\DoxyCodeLine{// aws4 will sign an options object as you'd pass to http.request, with an AWS service and region}
\DoxyCodeLine{var opts = \{ host: 'my-\/bucket.s3.us-\/west-\/1.amazonaws.com', path: '/my-\/object', service: 's3', region: 'us-\/west-\/1' \}}
\DoxyCodeLine{}
\DoxyCodeLine{// aws4.sign() will sign and modify these options, ready to pass to http.request}
\DoxyCodeLine{aws4.sign(opts, \{ accessKeyId: '', secretAccessKey: '' \})}
\DoxyCodeLine{}
\DoxyCodeLine{// or it can get credentials from process.env.AWS\_ACCESS\_KEY\_ID, etc}
\DoxyCodeLine{aws4.sign(opts)}
\DoxyCodeLine{}
\DoxyCodeLine{// for most AWS services, aws4 can figure out the service and region if you pass a host}
\DoxyCodeLine{opts = \{ host: 'my-\/bucket.s3.us-\/west-\/1.amazonaws.com', path: '/my-\/object' \}}
\DoxyCodeLine{}
\DoxyCodeLine{// usually it will add/modify request headers, but you can also sign the query:}
\DoxyCodeLine{opts = \{ host: 'my-\/bucket.s3.amazonaws.com', path: '/?X-\/Amz-\/Expires=12345', signQuery: true \}}
\DoxyCodeLine{}
\DoxyCodeLine{// and for services with simple hosts, aws4 can infer the host from service and region:}
\DoxyCodeLine{opts = \{ service: 'sqs', region: 'us-\/east-\/1', path: '/?Action=ListQueues' \}}
\DoxyCodeLine{}
\DoxyCodeLine{// and if you're using us-\/east-\/1, it's the default:}
\DoxyCodeLine{opts = \{ service: 'sqs', path: '/?Action=ListQueues' \}}
\DoxyCodeLine{}
\DoxyCodeLine{aws4.sign(opts)}
\DoxyCodeLine{console.log(opts)}
\DoxyCodeLine{/*}
\DoxyCodeLine{\{}
\DoxyCodeLine{  host: 'sqs.us-\/east-\/1.amazonaws.com',}
\DoxyCodeLine{  path: '/?Action=ListQueues',}
\DoxyCodeLine{  headers: \{}
\DoxyCodeLine{    Host: 'sqs.us-\/east-\/1.amazonaws.com',}
\DoxyCodeLine{    'X-\/Amz-\/Date': '20121226T061030Z',}
\DoxyCodeLine{    Authorization: 'AWS4-\/HMAC-\/SHA256 Credential=ABCDEF/20121226/us-\/east-\/1/sqs/aws4\_request, ...'}
\DoxyCodeLine{  \}}
\DoxyCodeLine{\}}
\DoxyCodeLine{*/}
\DoxyCodeLine{}
\DoxyCodeLine{// we can now use this to query AWS}
\DoxyCodeLine{request(opts)}
\DoxyCodeLine{/*}
\DoxyCodeLine{<?xml version="{}1.0"{}?>}
\DoxyCodeLine{<ListQueuesResponse xmlns="{}https://queue.amazonaws.com/doc/2012-\/11-\/05/"{}>}
\DoxyCodeLine{...}
\DoxyCodeLine{*/}
\DoxyCodeLine{}
\DoxyCodeLine{// aws4 can infer the HTTP method if a body is passed in}
\DoxyCodeLine{// method will be POST and Content-\/Type: 'application/x-\/www-\/form-\/urlencoded; charset=utf-\/8'}
\DoxyCodeLine{request(aws4.sign(\{ service: 'iam', body: 'Action=ListGroups\&Version=2010-\/05-\/08' \}))}
\DoxyCodeLine{/*}
\DoxyCodeLine{<ListGroupsResponse xmlns="{}https://iam.amazonaws.com/doc/2010-\/05-\/08/"{}>}
\DoxyCodeLine{...}
\DoxyCodeLine{*/}
\DoxyCodeLine{}
\DoxyCodeLine{// you can specify any custom option or header as per usual}
\DoxyCodeLine{request(aws4.sign(\{}
\DoxyCodeLine{  service: 'dynamodb',}
\DoxyCodeLine{  region: 'ap-\/southeast-\/2',}
\DoxyCodeLine{  method: 'POST',}
\DoxyCodeLine{  path: '/',}
\DoxyCodeLine{  headers: \{}
\DoxyCodeLine{    'Content-\/Type': 'application/x-\/amz-\/json-\/1.0',}
\DoxyCodeLine{    'X-\/Amz-\/Target': 'DynamoDB\_20120810.ListTables'}
\DoxyCodeLine{  \},}
\DoxyCodeLine{  body: '\{\}'}
\DoxyCodeLine{\}))}
\DoxyCodeLine{/*}
\DoxyCodeLine{\{"{}TableNames"{}:[]\}}
\DoxyCodeLine{...}
\DoxyCodeLine{*/}
\DoxyCodeLine{}
\DoxyCodeLine{// The raw RequestSigner can be used to generate CodeCommit Git passwords}
\DoxyCodeLine{var signer = new aws4.RequestSigner(\{}
\DoxyCodeLine{  service: 'codecommit',}
\DoxyCodeLine{  host: 'git-\/codecommit.us-\/east-\/1.amazonaws.com',}
\DoxyCodeLine{  method: 'GIT',}
\DoxyCodeLine{  path: '/v1/repos/MyAwesomeRepo',}
\DoxyCodeLine{\})}
\DoxyCodeLine{var password = signer.getDateTime() + 'Z' + signer.signature()}
\DoxyCodeLine{}
\DoxyCodeLine{// see example.js for examples with other services }

\end{DoxyCode}
\hypertarget{md_sfcode_node_modules_aws4_README_autotoc_md3624}{}\doxysection{API}\label{md_sfcode_node_modules_aws4_README_autotoc_md3624}
\hypertarget{md_sfcode_node_modules_aws4_README_autotoc_md3625}{}\doxysubsection{aws4.\+sign(request\+Options, \mbox{[}credentials\mbox{]})}\label{md_sfcode_node_modules_aws4_README_autotoc_md3625}
Calculates and populates any necessary AWS headers and/or request options on {\ttfamily request\+Options}. Returns {\ttfamily request\+Options} as a convenience for chaining.

{\ttfamily request\+Options} is an object holding the same options that the Node.\+js \href{https://nodejs.org/docs/latest/api/http.html\#http_http_request_options_callback}{\texttt{ http.\+request}} function takes.

The following properties of {\ttfamily request\+Options} are used in the signing or populated if they don\textquotesingle{}t already exist\+:


\begin{DoxyItemize}
\item {\ttfamily hostname} or {\ttfamily host} (will try to be determined from {\ttfamily service} and {\ttfamily region} if not given)
\item {\ttfamily method} (will use `\textquotesingle{}GET'{\ttfamily if not given or}\textquotesingle{}POST\textquotesingle{}{\ttfamily if there is a}body{\ttfamily ) -\/}path{\ttfamily (will use}\textquotesingle{}/\textquotesingle{}{\ttfamily if not given) -\/}body{\ttfamily (will use}\textquotesingle{}\textquotesingle{}{\ttfamily if not given) -\/}service{\ttfamily (will try to be calculated from}hostname{\ttfamily or}host{\ttfamily if not given) -\/}region{\ttfamily (will try to be calculated from}hostname{\ttfamily or}host{\ttfamily or use}\textquotesingle{}us-\/east-\/1\textquotesingle{}{\ttfamily if not given) -\/}sign\+Query{\ttfamily (to sign the query instead of adding an}Authorization{\ttfamily header, defaults to false) -\/}headers\mbox{[}\textquotesingle{}Host\textquotesingle{}\mbox{]}{\ttfamily (will use}hostname{\ttfamily or}host{\ttfamily or be calculated if not given) -\/}headers\mbox{[}\textquotesingle{}Content-\/\+Type\textquotesingle{}\mbox{]}{\ttfamily (will use}\textquotesingle{}application/x-\/www-\/form-\/urlencoded; charset=utf-\/8\textquotesingle{}{\ttfamily  if not given and there is a}body{\ttfamily ) -\/}headers\mbox{[}\textquotesingle{}Date\textquotesingle{}\mbox{]}{\ttfamily (used to calculate the signature date if given, otherwise}new Date\`{} is used)
\end{DoxyItemize}

Your AWS credentials (which can be found in your \href{https://portal.aws.amazon.com/gp/aws/securityCredentials}{\texttt{ AWS console}}) can be specified in one of two ways\+:


\begin{DoxyItemize}
\item As the second argument, like this\+:
\end{DoxyItemize}


\begin{DoxyCode}{0}
\DoxyCodeLine{aws4.sign(requestOptions, \{}
\DoxyCodeLine{  secretAccessKey: "{}<your-\/secret-\/access-\/key>"{},}
\DoxyCodeLine{  accessKeyId: "{}<your-\/access-\/key-\/id>"{},}
\DoxyCodeLine{  sessionToken: "{}<your-\/session-\/token>"{}}
\DoxyCodeLine{\}) }

\end{DoxyCode}



\begin{DoxyItemize}
\item From {\ttfamily process.\+env}, such as this\+:
\end{DoxyItemize}


\begin{DoxyCode}{0}
\DoxyCodeLine{export AWS\_ACCESS\_KEY\_ID="{}<your-\/access-\/key-\/id>"{}}
\DoxyCodeLine{export AWS\_SECRET\_ACCESS\_KEY="{}<your-\/secret-\/access-\/key>"{}}
\DoxyCodeLine{export AWS\_SESSION\_TOKEN="{}<your-\/session-\/token>"{} }

\end{DoxyCode}


(will also use {\ttfamily AWS\+\_\+\+ACCESS\+\_\+\+KEY} and {\ttfamily AWS\+\_\+\+SECRET\+\_\+\+KEY} if available)

The {\ttfamily session\+Token} property and {\ttfamily AWS\+\_\+\+SESSION\+\_\+\+TOKEN} environment variable are optional for signing with \href{https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html}{\texttt{ IAM STS temporary credentials}}.\hypertarget{md_sfcode_node_modules_aws4_README_autotoc_md3626}{}\doxysection{Installation}\label{md_sfcode_node_modules_aws4_README_autotoc_md3626}
With \href{https://www.npmjs.com/}{\texttt{ npm}} do\+:


\begin{DoxyCode}{0}
\DoxyCodeLine{npm install aws4 }

\end{DoxyCode}


Can also be used \href{./browser}{\texttt{ in the browser}}.\hypertarget{md_sfcode_node_modules_aws4_README_autotoc_md3627}{}\doxysection{Thanks}\label{md_sfcode_node_modules_aws4_README_autotoc_md3627}
Thanks to \href{https://github.com/jed}{\texttt{ @jed}} for his \href{https://github.com/jed/dynamo-client}{\texttt{ dynamo-\/client}} lib where I first committed and subsequently extracted this code.

Also thanks to the \href{https://github.com/aws/aws-sdk-js}{\texttt{ official Node.\+js AWS SDK}} for giving me a start on implementing the v4 signature. 