Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TheGraph Auth-Layer-Proxy #43

Merged
merged 21 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3fc24d7
Adding POC Results for auth-layer, this could be used as the beginnig…
AlfredoG87 Jan 4, 2024
a44d6f9
Adding white lines EOF
AlfredoG87 Jan 4, 2024
9e2ee75
Add example.env
AlfredoG87 Jan 4, 2024
ef95661
Add example.env
AlfredoG87 Jan 4, 2024
64c4643
improvements on docs
AlfredoG87 Jan 4, 2024
f24cce5
Removed some commented lines, addded licence header to filters script…
AlfredoG87 Jan 18, 2024
7351e43
Clean up redis POC, and leaved only PG Example so we can continue wor…
AlfredoG87 Jan 22, 2024
b717b75
Missing changes to complete cleanup
AlfredoG87 Jan 22, 2024
dabf8c9
cleanup of dockerfile to remove installation of redis module, since w…
AlfredoG87 Jan 22, 2024
00d5f1f
Removed Json HTTP Filter script and config, since is possible to do i…
AlfredoG87 Jan 23, 2024
5d5ba60
Improvements and further cleanup
AlfredoG87 Jan 24, 2024
8f6ddf0
Refactor and re-did the TokenVerificationFilter to use an OAuth token…
AlfredoG87 Feb 7, 2024
03904bc
moved files to more descriptive project folder
AlfredoG87 Mar 7, 2024
bacc19e
improvements to README, example.env and Lua Filter
AlfredoG87 Mar 7, 2024
b1b9373
Adding UnitTests coverage for filter/TokenVerificationFilter.lua
AlfredoG87 Mar 22, 2024
2d21d65
removed dummy env variable used for testing
AlfredoG87 Mar 22, 2024
ff60c45
removed print directory step used for debug of GHA WF
AlfredoG87 Mar 22, 2024
f4613e9
adding blank lines EOF where missing
AlfredoG87 Mar 22, 2024
600a2da
Improvements on Documentation
AlfredoG87 Mar 25, 2024
fff4e0e
Improvements on Documentation
AlfredoG87 Mar 25, 2024
8b43fa0
improvements on documentation and test name on GHA WF
AlfredoG87 Mar 28, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/proxy-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: Auth Layer Proxy Tests

on:
pull_request:
branches: [ main, release/**]
push:
branches: [ main, release/*]
tags: [ v* ]

jobs:
proxy-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Install Lua
uses: leafo/gh-actions-lua@v8
with:
luaVersion: '5.3'

- name: Install LuaRocks
uses: leafo/gh-actions-luarocks@v4

- name: Install lunatest
run: luarocks install lunatest

- name: Install luacov
run: luarocks install luacov

- name: Install luacov-console
run: luarocks install luacov-console

- name: Install cjson
run: luarocks install lua-cjson

- name: Install luasocket
run: luarocks install luasocket

- name: Run tests
run: lua test.lua
working-directory: auth-layer-proxy/tests

- name: Generate coverage report
run: luacov
working-directory: auth-layer-proxy/tests

- name: Generate Console Report
run: luacov-console ../filters/ && luacov-console ../filters/ -s && luacov-console ../filters/ -s > coverage.txt
working-directory: auth-layer-proxy/tests
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,7 @@ charts/auth-layer-server/Chart.lock

# DS_Store
.DS_Store
auth-layer-proxy/tests/coverage.txt
auth-layer-proxy/tests/luacov.report.out
auth-layer-proxy/tests/luacov.report.out.index
auth-layer-proxy/tests/luacov.stats.out
13 changes: 13 additions & 0 deletions auth-layer-proxy/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM envoyproxy/envoy:v1.28-latest

# Copy the Filter Scripts
COPY /filters/ /filters/

# Install Lua and Luarocks
RUN apt-get update && apt-get install -y lua5.1 luarocks git

# Install Lua modules
RUN luarocks install lua-cjson

# Install http socket module
RUN luarocks install luasocket
189 changes: 189 additions & 0 deletions auth-layer-proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# Readme

This is a token verification auth-layer-proxy for Hedera-The-Graph implementation that will allow a node operator to publish a secured `admin port` of the-graph deployment for Hedera.

Uses EnvoyProxy as a reverse proxy that handles the token verification. The token is verified using the OAuth 2.0 token server and the token claims are validated for the required roles and subgraph access.

```mermaid
---
title: Overall Architecture
---
flowchart LR
A[Graph Cli] --->|1. Create / Deploy Subgraph| B(Auth-Layer)
B ---> | 4. Relay Request on Admin Port| F(TheGraph Service)
B --> | 3. 401 Unauthorized | A
F ---> | 5. response| B --> | 6. response| A
B <--> | 2. Check Token| db[(Database)]

linkStyle 2 stroke:#ff0000,stroke-width:2px;
linkStyle 3 stroke:#00ff00,stroke-width:2px;
linkStyle 4 stroke:#00ff00,stroke-width:2px;

```
More information on the **Authorization Layer** can be found [here](https://github.com/hashgraph/hedera-the-graph/blob/main/docs/design/auth-layer.md)

## Overview

This is an implementation of EnvoyProxy filters for authentication and authorization. It is a custom config with http filters using Lua scripts for performing the following actions:

1. JSON Validation
2. Token Extraction
4. Payload Params Extraction
5. Token Validation using JWT and Instrospect endpoint
6. Proxy Routing Configuration (using EnvoyProxy itself)

it includes a Dockerfile for building the image and a docker-compose file for running the container.

## Pre-requisites

### OAUTH 2.0 Token Server
This auth-token validation proxy layer relies on an OAuth 2.0 token server for token issuace and validation. The token server should be able to issue and validate the token using the `client_id` and `client_secret` provided in the `.env` file.

So make sure to have a token server running that is previously configured with a Client ID and Client Secret, and the `/token` and `/token/introspection` endpoints are accessible.

### Token structure

Make sure that the access token has the following claims:
Nana-EC marked this conversation as resolved.
Show resolved Hide resolved
- realm_access.roles: A list of roles that the user has. The roles are used to determine the access level of the user.
- subgraph_access: A list of subgraph names that the user has access to. The subgraph names are used to determine the access level of the user.
- active: A boolean value that indicates if the user is active or not.
- email_verified: A boolean value that indicates if the user's email is verified or not.
- email: The email of the user.

```json
{
"exp": 1711427468,
"iat": 1711391468,
"jti": "2fab170f-beb1-4821-acb4-ac19a71c9abe",
"iss": "http://host.docker.internal:8080/realms/HederaTheGraph",
"aud": "account",
"sub": "f60ffb03-d17f-4aa2-a34a-2c4891059c3c",
"typ": "Bearer",
"azp": "htg-auth-layer",
"session_state": "79fbb78a-3279-463e-8ee0-6ab37e06bcc2",
"acr": "1",
"allowed-origins": [
"/*"
],
"realm_access": {
"roles": [
"default-roles-hederathegraph",
"subgraph_remove",
"subgraph_create",
"subgraph_deploy",
"offline_access",
"uma_authorization",
"subgraph_resume",
"subgraph_pause"
]
},
"scope": "profile subgraph_access email",
"subgraph_access": "<CSV of subgraph names>",
"email_verified": true,
"active": true,
"email": "[email protected]",
"client_id": "htg-auth-layer"
}
```

For instructions on how to set-up the Auth Provider using KeyCloak, refer to the `Auth-Layer-Server` [README](https://github.com/hashgraph/hedera-the-graph/tree/main/charts/auth-layer-server)

## Usage

### Build the image

```bash

docker build -t envoy-auth-proxy .

```

### Configure the environment

Add Postgres or Redis credentials to the .env file

```
# OAuth
CLIENT_ID=<clientId>
CLIENT_SECRET=<client_secret>
TOKEN_INTROSPECTION_URL=http://host.docker.internal:8080/realms/HederaTheGraph/protocol/openid-connect/token/introspect

```

### Configure the details of the service to be proxied on the envoy.yam
Edit `envoy-auth.yaml` file with config needs, by default will be proxying/relaying the request to address: `host.docker.internal` and port `8020`

```yaml
clusters:
- name: local_service
connect_timeout: 5s
type: LOGICAL_DNS
load_assignment:
cluster_name: local_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: host.docker.internal
port_value: 8020
```


### Run the container


**Start the container:**

```bash
docker-compose up
```

### Test the service

```bash
curl --location 'http://localhost:10000' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer 12345' \
--data '{
"jsonrpc": "2.0",
"id": "2",
"method": "deploy_subgraph",
"params": {
"name": "test"
}
}'
```


## Testing

The tests are written using lunatest and can be run using the following command:

Make sure to have installed the following prerequisites:
1. lua
2. luarocks

Install the following luarocks packages:

```bash
luarocks install lua-cjson
luarocks install luasocket
luarocks install lunatest
luarocks install luacov
luarocks install luacov-console
```

Open a terminal and navigate to the folder containing the `tests` folder and run the following command:

```bash
lua test.lua
```

to show the coverage report, run the following command:

```bash
luacov
luacov-console ../filters/
luacov-console ../filters/ -s
```
49 changes: 49 additions & 0 deletions auth-layer-proxy/configs/envoy-auth.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 10000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: edge
http_filters:
- name: envoy.filters.http.lua
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
default_source_code:
filename: /filters/TokenVerificationFilter.lua

- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
route_config:
virtual_hosts:
- name: all_domains
domains: ["*"]
routes:
- match:
prefix: "/"
headers:
name: ":method"
exact_match: "POST"
route:
cluster: local_service

clusters:
- name: local_service
connect_timeout: 5s
type: LOGICAL_DNS
load_assignment:
cluster_name: local_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: host.docker.internal
port_value: 8020
16 changes: 16 additions & 0 deletions auth-layer-proxy/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: '3'

services:
envoy:
image: envoy-auth-layer:latest
command: -c /configs/envoy-auth.yaml
env_file:
- .env
volumes:
- ./configs/:/configs/
- ./filters/:/filters/
ports:
- "9901:9901"
- "10000:10000"
stdin_open: true
tty: true
4 changes: 4 additions & 0 deletions auth-layer-proxy/example.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# OAuth
CLIENT_ID=htg-auth-layer
CLIENT_SECRET=0cyYtDVVbVvaZjrDViiw4p2kegTy9Q5X
TOKEN_INTROSPECTION_URL=http://host.docker.internal:8080/realms/HederaTheGraph/protocol/openid-connect/token/introspect
Loading
Loading