Skip to content

Commit 9db0cd3

Browse files
Oleg Chaplashkinochaplashkin
Oleg Chaplashkin
authored andcommitted
Restrict access to metrics from the public network
Due to security reasons, access to the `/metrics` endpoint is restricted by basic HTTP Bearer Token authentication. If you make a request without the correct token, the server will respond with "Unauthorized Access". Close #43
1 parent b16fd7a commit 9db0cd3

File tree

5 files changed

+30
-3
lines changed

5 files changed

+30
-3
lines changed

README.md

+6-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ docker build -t docbot .
4242
Then run it like this:
4343

4444
```sh
45-
docker run -d -p5000:5000 -e GITHUB_TOKEN=<token> -e GITHUB_SIGN_KEY=<sign_key> --name docbot docbot
45+
docker run \
46+
-d -p5000:5000 \
47+
-e GITHUB_TOKEN=<token> \
48+
-e GITHUB_SIGN_KEY=<sign_key> \
49+
-e PROMETHEUS_TOKEN=<token> \
50+
--name docbot docbot
4651
```
4752

4853
To check that it works try to get `localhost:5000` - it will print the

docbot/app.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
from elasticapm.contrib.flask import ElasticAPM
44
from prometheus_flask_exporter import PrometheusMetrics
55
from flask import Flask, Response, request
6+
from flask_httpauth import HTTPTokenAuth
67

78
from .handlers import webhook_handler, list_events_handler
89
from .logging_config import LOGGING_CONFIG
9-
from .utils import is_verified_signature
10+
from .utils import is_verified_signature, is_verified_prometheus_token
1011

1112

1213
logging.config.dictConfig(LOGGING_CONFIG)
@@ -15,13 +16,19 @@
1516

1617

1718
app = Flask(__name__)
19+
auth = HTTPTokenAuth()
1820

1921
app.config['ELASTIC_APM'] = {
2022
'SERVICE_NAME': 'docbot',
2123
}
2224
apm = ElasticAPM(app, logging=True)
2325

24-
metrics = PrometheusMetrics(app, group_by='endpoint')
26+
metrics = PrometheusMetrics(app, group_by='endpoint', metrics_decorator=auth.login_required)
27+
28+
29+
@auth.verify_token
30+
def verify_token(token):
31+
return is_verified_prometheus_token(token)
2532

2633
@app.route("/", methods=['GET'])
2734
@metrics.do_not_track()

docbot/settings.py

+2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
token = os.environ.get('GITHUB_TOKEN')
44
github_signature = os.environ.get('GITHUB_SIGN_KEY')
5+
prometheus_token = os.environ.get('PROMETHEUS_TOKEN')
56
assert token is not None
67
assert github_signature is not None
8+
assert prometheus_token is not None
79
doc_requests = [' document\r\n', ' document\n']
810
bot_name = '@TarantoolBot'
911
title_header = 'Title:'

docbot/utils.py

+12
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,15 @@ def is_verified_signature(body, signature):
3939
if not hmac.compare_digest(expected_signature, signature):
4040
return False
4141
return True
42+
43+
def is_verified_prometheus_token(token):
44+
"""Verify that the payload was sent from Prometheus via Bearer token.
45+
46+
Returns True if the request is authorized, otherwise False.
47+
48+
Args:
49+
token: original request token to verify
50+
"""
51+
if token == settings.prometheus_token:
52+
return True
53+
return False

requirements.txt

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ click==8.1.3
55
ecs-logging==2.0.0
66
elastic-apm==6.9.1
77
Flask==2.2.5
8+
Flask-HTTPAuth==4.8.0
89
gunicorn==20.1.0
910
idna==3.3
1011
itsdangerous==2.1.2

0 commit comments

Comments
 (0)