Lua client for authorising actions with tinyauth on OpenResty/ngx_lua
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
example
lib/resty
LICENSE
README.md
dist.ini
docker-compose.yml

README.md

lua-resty-tinyauth

Lua client for authorising actions with tinyauth on OpenResty/ngx_lua.

Status

Alpha.

Features

  • User and group based ACLs for any service that can be proxied by nginx
  • Use URL maps to break down your API into multiple distinct actions to allow for fine grained permissions.

Synopsis

lua_package_path "/path/to/lua-resty-microauth/lib/?.lua;;";

server {
  location / {
    access_by_lua_block {
      local tinyauth = require('resty/tinyauth');
      local client = tinyauth.new("http://tinyauth:5000/api/v1/", "gatekeeper", "keymaster")

      client:authorize_token_for_url({
        {"/ip",         {"GET"},  "GetOriginIp"},
        {"/stream/.*",  {"GET"},  "StreamLines"},
      }, "ProxyRequest")
    }

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass   http://app;
  }
}

Connection

new

syntax: local client = tinyauth.new()

Creates the tinyauth object.

authorize_token_for_action

syntax: client:authorize_token_for_action(action)

All traffic that is subjected to this authorization will be treated as a single action type. This is useful if you either have access to an API or you do not.

authorize_token_for_url

syntax: client:authorize_token_for_url(uri_map)

syntax: client:authorize_token_for_url(uri_map, default)

Traffic URI is looked up in a table to find out what action to use when authorizing with tinyauth.

If no matches are found and default is not set then the access attempt will be forbidden.

If no matches are found and a default is set then the access attempt will be authorized with the default action.

uri_map is an array of 'routes'. If a route matches then we know what action to associate it with when querying tinyauth. The routes might look like:

local routes = {
  {"/ip",       {"GET"},    "GetIp"},
  {"/gzip",     {"GET"},    "GetGzippedData"},
  {"/stream/.*", {"GET"},   "StreamLines"},
}

authorize_login_for_action

syntax: client:authorize_login_for_action(action)

All traffic that is subjected to this authorization will be treated as a single action type. This is useful if you either have access to an API or you do not.

authorize_login_for_url

syntax: client:authorize_login_for_url(uri_map)

syntax: client:authorize_login_for_url(uri_map, default)

Traffic URI is looked up in a table to find out what action to use when authorizing with tinyauth.

If no matches are found and default is not set then the access attempt will be forbidden.

If no matches are found and a default is set then the access attempt will be authorized with the default action.

uri_map is an array of 'routes'. If a route matches then we know what action to associate it with when querying tinyauth. The routes might look like:

local routes = {
  {"/ip",       {"GET"},    "GetIp"},
  {"/gzip",     {"GET"},    "GetGzippedData"},
  {"/stream/.*", {"GET"},   "StreamLines"},
}

With these routes when a user accesses /stream/99 we can map that to StreamLines and ask tinyauth if we can authenticate that user to do the StreamLines action.

Checking out the example

This repo contains an example of using tinyauth to secure a mission critical service: httpbin.

The docker compose config will deploy httpbin running on gunicorn with an openresty reverse proxy in front of it. lua-resty-tinyauth will be running in the proxy and provide authorization by talking to a simple tinyauth setup (postgres + tinyauth).

In a terminal:

$ docker-compose build
$ docker-compose up

This will run the demo in the foreground. In another terminal window

$ docker-compose run --rm tinyauth tinyauth db upgrade
Starting luarestytinyauth_postgres_1 ... done
Postgres is up - continuing...
INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO  [alembic.runtime.migration] Will assume transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 276ef161b610, empty message
INFO  [alembic.runtime.migration] Running upgrade 276ef161b610 -> 0d42398b4cdc, empty message
INFO  [alembic.runtime.migration] Running upgrade 0d42398b4cdc -> 0d0c426e7b01, empty message
INFO  [alembic.runtime.migration] Running upgrade 0d0c426e7b01 -> 7db3f3cca1a9, empty message
INFO  [alembic.runtime.migration] Running upgrade 7db3f3cca1a9 -> 9efdb5e1f6fb, empty message

$ docker-compose run --rm tinyauth tinyauth createdevuser
Starting luarestytinyauth_postgres_1 ... done
Postgres is up - continuing...
'root' account created

$ curl -u admin:admin http://localhost:80/ip
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>openresty/1.11.2.5</center>
</body>
</html>

$ curl -u gatekeeper:keymaster http://localhost:80/ip
{
  "origin": "172.29.0.1"
}