Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
43 changes: 32 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ curl http://localhost:5000/metrics # Prometheus text, for a scr
curl http://localhost:5000/metrics?fmt=json | jq # the same numbers, for a human
```

#### Responses

| **Code** | **When** |
| -------- | ------------------------------------------------------------------------------------------ |
| `200` | The counters, in the format named by `fmt` |
| `400` | `fmt` was something other than `prometheus` or `json` |
| `401` | A token is configured and the request did not carry it. Carries `WWW-Authenticate: Bearer` |
| `500` | An unexpected failure, rendered by the catch-all handler like on any other endpoint |

#### How collection works

Everything is counted **in this process, in memory**. There is no database and no external dependency, and the counters
Expand Down Expand Up @@ -548,27 +557,39 @@ which is `null` rather than absent when nothing has been recorded yet, so the sh

#### Protecting the endpoint

`/metrics` is **open by default**, which is what a local run and the Docker instructions above
expect. Set the `METRICS_TOKEN` environment variable on the server to require a bearer token
instead:
`/metrics` is **open unless a token is configured**, through the `METRICS_TOKEN` environment
variable.

| `METRICS_TOKEN` | Behaviour of `/metrics` |
| --------------- | ---------------------------------------------------------------------- |
| unset | Open. A credential sent anyway is **ignored, not rejected** |
| blank | Same as unset β€” an empty value means "no token", not "the empty token" |
| set | Every request must carry that token, in both formats |

```bash
TOKEN=$(openssl rand -hex 32) # keep it: whatever scrapes the endpoint needs the same value
docker run --name pesu-auth -d -p 5000:5000 -e METRICS_TOKEN="$TOKEN" pesu-auth
# Deployed: an environment variable on the service
docker run --name pesu-auth -d -p 5000:5000 -e METRICS_TOKEN=<token> pesu-auth

# Running from source: pass it to the process
METRICS_TOKEN=<token> uv run python -m app.app
```

With it set, a request must carry that token or the endpoint answers `401` with
`WWW-Authenticate: Bearer` and the same error body as every other failure. Both formats are
covered, so `?fmt=json` is not a way around it.
`.env` is read by the test suite, never by the application, so a token there does not protect a
running server.

A rejection carries `WWW-Authenticate: Bearer` and the same error body as every other failure.

```bash
curl http://localhost:5000/metrics # 401
curl -H "Authorization: Bearer <token>" http://localhost:5000/metrics # 200
```

The variable is read once at startup, so changing it needs a restart. Leaving it blank counts as
unset. No other endpoint is affected β€” `/health` in particular stays open, since uptime monitors
and the hosting platform's own health check send no credentials.
The interactive docs at `/` carry an **Authorize** button for it. Paste the token there with no
`Bearer ` prefix; Swagger adds that itself.

The variable is read once at startup, so changing it needs a restart. No other endpoint is
affected β€” `/health` in particular stays open, since uptime monitors and the hosting platform's own
health check send no credentials.

#### Scraping the endpoint

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pesu-auth"
version = "4.3.0"
version = "4.4.0"
description = "A simple API to authenticate PESU credentials using PESU Academy."
readme = "README.md"
requires-python = ">=3.14"
Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading