Skip to content

whitfin/ngx_aws_token

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ngx_aws_token

This repository provides a small Lua module for OpenResty that simplifies proxying traffic to AWS services in web requests. Authorization tokens are automatically rotated in shared storage, making it easier to proxy requests to AWS APIs.

The primary use case for ngx_aws_token is integrating a proxy layer with Amazon services requiring token based authentication for web requests, such as Amazon ECR or CodeArtifact. This module handles token rotation in the background, reducing boilerplace in your Nginx configuration.

Rather than programmatically retrieving tokens, ngx_aws_token opts to use the AWS to retrieve tokens. Therefore, the AWS CLI must be installed and available on your system to use this module.

Installation

This module is available via LuaRocks, so you can install the latest from there:

luarocks install ngx_aws_token

Or, because it really is just a single file, you can place ngx_aws_token.lua directly into your OpenResty installation at /usr/local/openresty/lualib.

For example if you're using a Docker build of OpenResty, you can add this module via an ADD instruction:

ADD https://github.com/whitfin/gx_aws_token/blob/<ref>/lua/ngx_aws_token.lua \
    /usr/local/openresty/lualib/ngx_aws_token.lua

Make sure to replace <ref> with either the branch name or commit hash you want to pin against. I'd recommend pinning a specific hash when fetching this way, as Docker caches based on the URL rather than the content.

Creating Tokens

Before you manage any tokens with ngx_aws_token, you need to configure a shared storage dictionary. The size of this dictionary depends on how many tokens you're going to be rotating, but in general 1m should be enough for most people.

# Create a shared memory between workers
lua_shared_dict my_aws_tokens 1m;

init_worker_by_lua_block {
    -- Import the ngx_aws_token module
    local ngx_aws_token = require("ngx_aws_token")

    -- Set the shared storage used by ngx_aws_token
    ngx_aws_token.set_storage(ngx.shared.my_aws_tokens)
}

You can then configure named tokens to rotate based on AWS CLI commands into the shared storage. The below example uses Amazon ECR token generation:

# Create a shared memory between workers
lua_shared_dict my_aws_tokens 1m;

init_worker_by_lua_block {
    -- Avoid running on many workers
    if ngx.worker.id() ~= 0 then
        return
    end

    -- Import the ngx_aws_token module
    local ngx_aws_token = require("ngx_aws_token")

    -- Set the shared storage used by ngx_aws_token
    ngx_aws_token.set_storage(ngx.shared.my_aws_tokens)

    -- Our token name and command to generate
    local token_name = "my_token_name"
    local token_command = "aws ecr get-authorization-token --query 'authorizationData[*].authorizationToken' --output text"

    -- Begin rotating a token inside our configured storage
    ngx_aws_token.rotate(token_name, token_command, function (token)
        return "Basic " .. token
    end)
}

Calling rotate/3 requires a token name, an AWS CLI command, and an optional function used to transform the result. In some cases the AWS CLI doesn't produce directly usable tokens (such as above) and a small transformation is required.

It's important to note that the above example will only run on worker 0 in order to avoid many workers spawning AWS commands. The storage is shared between all workers, so this is an effective pattern for token refresh.

Routing Requests

Once your token is configured, you can implement a simple Lua authentication block to read back your token for a request. You can read it back directly from your shared storage, or use ngx_aws_token if you prefer:

set_by_lua_block $ecr_token {
    local ngx_aws_token = require("ngx_aws_token")

    return ngx_aws_token.token("ecr")
}

With this block in place, you can use it alongside the proxy_set_header directive inside a location block to add it as an Authorization header:

proxy_set_header Authorization $ecr_token;

This will attach the latest token to the outgoing request, allowing you to route through to AWS transparently behind your own authentication layers or routing rules.

Contributing

This module is very small and I don't expect it'll grow or add many other things, but if you have suggestions or feedback please feel free to file an issue!

About

A Lua module for OpenResty to simplify proxying to AWS services

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages