anomalizer/ngx_aws_auth

nginx module to proxy to authenticated AWS services

C

475

105 commits

updated Sep 28, 2026

See the code

README

AWS proxy module

CI Gitter chat

This nginx module can proxy requests to authenticated S3 backends using Amazon's V4 authentication API. The first version of this module was written for the V2 authentication protocol and can be found in the AuthV2 branch.

License

This project uses the same license as ngnix does i.e. the 2 clause BSD / simplified BSD / FreeBSD license

Usage example

Implements proxying of authenticated requests to S3.

  server {
    listen     8000;

    aws_access_key your_aws_access_key; # Example AKIDEXAMPLE
    aws_key_scope scope_of_generated_signing_key; #Example 20150830/us-east-1/service/aws4_request
    aws_signing_key signing_key_generated_using_script; #Example L4vRLWAO92X5L3Sqk5QydUSdB0nC9+1wfqLMOKLbRp4=
    aws_s3_bucket your_s3_bucket;

    location / {
      aws_sign;
      proxy_pass http://your_s3_bucket.s3.amazonaws.com;
    }

    # This is an example that does not use the server root for the proxy root
    location /myfiles {

      rewrite /myfiles/(.*) /$1 break;
      proxy_pass http://your_s3_bucket.s3.amazonaws.com/$1;

      aws_access_key your_aws_access_key;
      aws_key_scope scope_of_generated_signing_key;
      aws_signing_key signing_key_generated_using_script;
    }

    # This is an example that use specific s3 endpoint, default endpoint is s3.amazonaws.com
    location /s3_beijing {

      rewrite /s3_beijing/(.*) /$1 break;
      proxy_pass http://your_s3_bucket.s3.cn-north-1.amazonaws.com.cn/$1;

      aws_sign;
      aws_endpoint "s3.cn-north-1.amazonaws.com.cn";
      aws_access_key your_aws_access_key;
      aws_key_scope scope_of_generated_signing_key;
      aws_signing_key signing_key_generated_using_script;
    }
  }

Security considerations

The V4 protocol does not need access to the actual secret keys that one obtains from the IAM service. The correct way to use the IAM key is to actually generate a scoped signing key and use this signing key to access S3. This nginx module requires the signing key and not the actual secret key. It is an insecure practise to let the secret key reside on your nginx server.

Note that signing keys have a validity of just one week. Hence, they need to be refreshed constantly. Please useyour favourite configuration management system such as saltstack, puppet, chef, etc. etc. to distribute the signing keys to your nginx clusters. Do not forget to HUP the server after placing the new signing key as nginx reads the configuration only at startup time.

A standalone python script has been provided to generate the signing key

./generate_signing_key -h
usage: generate_signing_key [-h] -k SECRET_KEY -r REGION [-s SERVICE]
                            [-d DATE] [--no-base64] [-v]

Generate AWS S3 signing key in it's base64 encoded form

optional arguments:
  -h, --help            show this help message and exit
  -k SECRET_KEY, --secret-key SECRET_KEY
                        The secret key generated using AWS IAM. Do not confuse
                        this with the access key id
  -r REGION, --region REGION
                        The AWS region where this key would be used. Example:
                        us-east-1
  -s SERVICE, --service SERVICE
                        The AWS service for which this key would be used.
                        Example: s3
  -d DATE, --date DATE  The date on which this key is generated in yyyymmdd
                        format
  --no-base64           Disable output as a base64 encoded string. This NOT
                        recommended
  -v, --verbose         Produce verbose output on stderr


./generate_signing_key -k wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY -r us-east-1
L4vRLWAO92X5L3Sqk5QydUSdB0nC9+1wfqLMOKLbRp4=
20160902/us-east-1/s3/aws4_request

Supported environments

CI runs the test suite against a matrix of target environments (see .github/workflows/ci.yml):

DistroArchlibcCompiler
Ubuntu 26.04 LTSx86_64glibcgcc
Ubuntu 24.04 LTSaarch64glibcclang
Fedora (latest)x86_64glibcgcc
Alpine (latest)x86_64muslclang
Alpine (latest)aarch64muslgcc

Tests run against a pinned stable nginx release (see NGINX_VERSION in .github/workflows/ci.yml). ARM jobs run on native aarch64 runners, not emulation.

The unit-test dependency (cmocka) is vendored as a git submodule pinned to cmocka-2.0.2; make test bootstraps the submodule and builds it in-tree as a static library (cmake is required, but nothing is installed system-wide).

To reproduce a build locally, run the same commands in any OCI container, e.g. with podman:

podman run --rm -v "$PWD":/src:ro docker.io/library/alpine:latest sh -c '
  apk add --no-cache build-base wget git cmake openssl-dev pcre2-dev zlib-dev &&
  cp -a /src/. /build/ && cd /build &&
  export NGINX_VERSION=1.30.5 &&
  make prepare-nginx nginx test'

CC selects the compiler (e.g. CC=clang) and NGX_CC_OPT passes extra compiler flags to nginx's build via --with-cc-opt. The alpine+clang CI job sets -Wno-error=sign-compare because nginx's -Werror trips over musl's CMSG_NXTHDR macro.

Known limitations

The 2.x version of the module currently only has support for GET and HEAD calls. This is because signing request body is complex and has not yet been implemented.

Pre-built Packages (Ubuntu / Debian)

Pre-built packages for this module are freely available from the GetPageSpeed repository:

# Install the repository keyring
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://extras.getpagespeed.com/deb-archive-keyring.gpg \
  | sudo tee /etc/apt/keyrings/getpagespeed.gpg >/dev/null

# Add the repository (Ubuntu example - replace 'ubuntu' and 'jammy' for your distro)
echo "deb [signed-by=/etc/apt/keyrings/getpagespeed.gpg] https://extras.getpagespeed.com/ubuntu jammy main" \
  | sudo tee /etc/apt/sources.list.d/getpagespeed-extras.list

# Install nginx and the module
sudo apt-get update
sudo apt-get install nginx nginx-module-aws-auth

The module is automatically enabled after installation. Supported distributions include Debian 12/13 and Ubuntu 20.04/22.04/24.04 (both amd64 and arm64). See the complete setup instructions.

Credits

Original idea based on http://nginx.org/pipermail/nginx/2010-February/018583.html and suggestion of moving to variables rather than patching the proxy module.

Subsequent contributions can be found in the commit logs of the project.

aws-s3
nginx

Significant stargazers

Piotr Sikora

368 followers · starred Dec 2010

Ted Mielczarek

197 followers · starred Jan 2015

Ee Durbin

895 followers · starred Jul 2014

anomalizer/ngx_aws_auth

nginx module to proxy to authenticated AWS services

C

475

105 commits

updated Sep 28, 2026

See the code

README

AWS proxy module

CI Gitter chat

This nginx module can proxy requests to authenticated S3 backends using Amazon's V4 authentication API. The first version of this module was written for the V2 authentication protocol and can be found in the AuthV2 branch.

License

This project uses the same license as ngnix does i.e. the 2 clause BSD / simplified BSD / FreeBSD license

Usage example

Implements proxying of authenticated requests to S3.

  server {
    listen     8000;

    aws_access_key your_aws_access_key; # Example AKIDEXAMPLE
    aws_key_scope scope_of_generated_signing_key; #Example 20150830/us-east-1/service/aws4_request
    aws_signing_key signing_key_generated_using_script; #Example L4vRLWAO92X5L3Sqk5QydUSdB0nC9+1wfqLMOKLbRp4=
    aws_s3_bucket your_s3_bucket;

    location / {
      aws_sign;
      proxy_pass http://your_s3_bucket.s3.amazonaws.com;
    }

    # This is an example that does not use the server root for the proxy root
    location /myfiles {

      rewrite /myfiles/(.*) /$1 break;
      proxy_pass http://your_s3_bucket.s3.amazonaws.com/$1;

      aws_access_key your_aws_access_key;
      aws_key_scope scope_of_generated_signing_key;
      aws_signing_key signing_key_generated_using_script;
    }

    # This is an example that use specific s3 endpoint, default endpoint is s3.amazonaws.com
    location /s3_beijing {

      rewrite /s3_beijing/(.*) /$1 break;
      proxy_pass http://your_s3_bucket.s3.cn-north-1.amazonaws.com.cn/$1;

      aws_sign;
      aws_endpoint "s3.cn-north-1.amazonaws.com.cn";
      aws_access_key your_aws_access_key;
      aws_key_scope scope_of_generated_signing_key;
      aws_signing_key signing_key_generated_using_script;
    }
  }

Security considerations

The V4 protocol does not need access to the actual secret keys that one obtains from the IAM service. The correct way to use the IAM key is to actually generate a scoped signing key and use this signing key to access S3. This nginx module requires the signing key and not the actual secret key. It is an insecure practise to let the secret key reside on your nginx server.

Note that signing keys have a validity of just one week. Hence, they need to be refreshed constantly. Please useyour favourite configuration management system such as saltstack, puppet, chef, etc. etc. to distribute the signing keys to your nginx clusters. Do not forget to HUP the server after placing the new signing key as nginx reads the configuration only at startup time.

A standalone python script has been provided to generate the signing key

./generate_signing_key -h
usage: generate_signing_key [-h] -k SECRET_KEY -r REGION [-s SERVICE]
                            [-d DATE] [--no-base64] [-v]

Generate AWS S3 signing key in it's base64 encoded form

optional arguments:
  -h, --help            show this help message and exit
  -k SECRET_KEY, --secret-key SECRET_KEY
                        The secret key generated using AWS IAM. Do not confuse
                        this with the access key id
  -r REGION, --region REGION
                        The AWS region where this key would be used. Example:
                        us-east-1
  -s SERVICE, --service SERVICE
                        The AWS service for which this key would be used.
                        Example: s3
  -d DATE, --date DATE  The date on which this key is generated in yyyymmdd
                        format
  --no-base64           Disable output as a base64 encoded string. This NOT
                        recommended
  -v, --verbose         Produce verbose output on stderr


./generate_signing_key -k wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY -r us-east-1
L4vRLWAO92X5L3Sqk5QydUSdB0nC9+1wfqLMOKLbRp4=
20160902/us-east-1/s3/aws4_request

Supported environments

CI runs the test suite against a matrix of target environments (see .github/workflows/ci.yml):

DistroArchlibcCompiler
Ubuntu 26.04 LTSx86_64glibcgcc
Ubuntu 24.04 LTSaarch64glibcclang
Fedora (latest)x86_64glibcgcc
Alpine (latest)x86_64muslclang
Alpine (latest)aarch64muslgcc

Tests run against a pinned stable nginx release (see NGINX_VERSION in .github/workflows/ci.yml). ARM jobs run on native aarch64 runners, not emulation.

The unit-test dependency (cmocka) is vendored as a git submodule pinned to cmocka-2.0.2; make test bootstraps the submodule and builds it in-tree as a static library (cmake is required, but nothing is installed system-wide).

To reproduce a build locally, run the same commands in any OCI container, e.g. with podman:

podman run --rm -v "$PWD":/src:ro docker.io/library/alpine:latest sh -c '
  apk add --no-cache build-base wget git cmake openssl-dev pcre2-dev zlib-dev &&
  cp -a /src/. /build/ && cd /build &&
  export NGINX_VERSION=1.30.5 &&
  make prepare-nginx nginx test'

CC selects the compiler (e.g. CC=clang) and NGX_CC_OPT passes extra compiler flags to nginx's build via --with-cc-opt. The alpine+clang CI job sets -Wno-error=sign-compare because nginx's -Werror trips over musl's CMSG_NXTHDR macro.

Known limitations

The 2.x version of the module currently only has support for GET and HEAD calls. This is because signing request body is complex and has not yet been implemented.

Pre-built Packages (Ubuntu / Debian)

Pre-built packages for this module are freely available from the GetPageSpeed repository:

# Install the repository keyring
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://extras.getpagespeed.com/deb-archive-keyring.gpg \
  | sudo tee /etc/apt/keyrings/getpagespeed.gpg >/dev/null

# Add the repository (Ubuntu example - replace 'ubuntu' and 'jammy' for your distro)
echo "deb [signed-by=/etc/apt/keyrings/getpagespeed.gpg] https://extras.getpagespeed.com/ubuntu jammy main" \
  | sudo tee /etc/apt/sources.list.d/getpagespeed-extras.list

# Install nginx and the module
sudo apt-get update
sudo apt-get install nginx nginx-module-aws-auth

The module is automatically enabled after installation. Supported distributions include Debian 12/13 and Ubuntu 20.04/22.04/24.04 (both amd64 and arm64). See the complete setup instructions.

Credits

Original idea based on http://nginx.org/pipermail/nginx/2010-February/018583.html and suggestion of moving to variables rather than patching the proxy module.

Subsequent contributions can be found in the commit logs of the project.

aws-s3
nginx

Significant stargazers

Piotr Sikora

368 followers · starred Dec 2010

Ted Mielczarek

197 followers · starred Jan 2015

Ee Durbin

895 followers · starred Jul 2014