petter2025 commited on
Commit
9d3d2c3
·
1 Parent(s): 6fbc8ca

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. docs/authentication.md +15 -1
docs/authentication.md CHANGED
@@ -12,9 +12,23 @@ Current status
12
  this service. The last four were unauthenticated until this was fixed — see
13
  `tests/test_deps.py` for the tests that verify the dependency itself actually rejects what
14
  it should, not just that it's wired in.
 
 
 
 
 
 
 
 
 
15
  - `routes_admin.py`: individual `/admin/*` endpoints require an `admin_key` query parameter,
16
  verified against `ARF_ADMIN_API_KEY` (`app/api/deps.py`, or the local `verify_admin`
17
- dependency in that router). Also fails closed if unset.
 
 
 
 
 
18
  - `routes_pricing.py`: individual `/pricing/*` endpoints require a real per-customer API key
19
  (`Authorization: Bearer <key>` or `?api_key=`), verified against the tracked/tenant-scoped
20
  `enforce_quota` dependency (`app/core/usage_tracker.py`) — a different mechanism from
 
12
  this service. The last four were unauthenticated until this was fixed — see
13
  `tests/test_deps.py` for the tests that verify the dependency itself actually rejects what
14
  it should, not just that it's wired in.
15
+ - `routes_incidents.py`'s `POST /report_incident` requires the same `X-Internal-Key`
16
+ dependency as above — it did not until a later audit found it had none at all, unlike every
17
+ other route in this file, despite its own docstring saying it's meant for internal monitoring
18
+ tools only. Anyone could previously write arbitrary events into the incident history that
19
+ feeds the causal explainer and `GET /history`. That history is now also a bounded
20
+ `deque(maxlen=10_000)` (`app/core/storage.py`), not an unbounded list — the same audit found
21
+ `POST /report_incident` and `GET /history` were reading/writing two _different_ Python lists
22
+ with the same name, so `GET /history` had in fact always returned empty regardless of what was
23
+ reported; both routers now share the one list in `app.core.storage`.
24
  - `routes_admin.py`: individual `/admin/*` endpoints require an `admin_key` query parameter,
25
  verified against `ARF_ADMIN_API_KEY` (`app/api/deps.py`, or the local `verify_admin`
26
+ dependency in that router). Also fails closed if unset. Includes
27
+ `POST /admin/keys/{key_id}/rotate` — deactivates a key and issues a new one on the same
28
+ tenant/tier in one transaction, for when a key needs to be revoked without losing the
29
+ tenant's identity or history. `api_keys` itself lives in Postgres (`DATABASE_URL`), shared
30
+ with arf-gateway (both must use the identical `ARF_KEY_PEPPER`) — see the comments on those
31
+ two variables in `.env.example` for why.
32
  - `routes_pricing.py`: individual `/pricing/*` endpoints require a real per-customer API key
33
  (`Authorization: Bearer <key>` or `?api_key=`), verified against the tracked/tenant-scoped
34
  `enforce_quota` dependency (`app/core/usage_tracker.py`) — a different mechanism from