Add security headers and Cache-Control: no-store to API responses
Los mantenedores suelen responder en 1 día
@nutellasando ya está trabajando en esto.
Desde el 9/10/2026.
Evaluación
- Dificultad
- 3/5
- Tiempo estimado
- 1-2 días
- Aptitud para principiantes
- 84/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bien especificado
- Estado de actividad
- Activo
- Área
- api, authentication, security
Línea de trabajo
Start with app/app.py and the metrics_middleware pattern, then read the middleware lifecycle comment in app/metrics/middleware.py. Use tests/integration/test_app_integration.py and its TestClient patterns, and run the curl commands or uv run python scripts/run_tests.py. Done means the specified headers appear on the listed routes, tests retain 100% coverage, the README documents them, and pre-commit passes.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
🔄 Updated for v5.0.0 (2026-10-08). Still open and unchanged in substance: 5.0.0 adds no response headers. The profile now carries more personal data (17 fields, including
genderanddateOfBirth), which makesCache-Control: no-storemore important. The description of the data and the version example are updated.
🌱 This is a beginner-friendly issue. You'll write a small FastAPI middleware and learn how a response passes through pesu-auth's middleware and exception handlers on its way out. It's a small change with a visible result: new headers you can see with
curl -i. Ask questions in the comments at any point.
⚠️ Who can take this issue
- Anyone. This change can be tested fully offline. If you have PESU credentials, run the live tests too; if you don't, say so in your PR and CI will run them after merge.
- Wait until you're assigned. Comment to ask for the issue, then wait for a maintainer to assign it to you before writing any code. PRs for unassigned issues are closed without review.
The problem
A successful /authenticate response can contain a student's name, mobile number, email address, gender and date of birth. Nothing in the response tells browsers, proxies or CDNs not to store it. pesu-auth also sends none of the basic security headers that security scanners and the OWASP REST Security Cheat Sheet recommend for every API.
Try it with the app running:
curl -i -X POST http://localhost:5000/authenticate -H 'Content-Type: application/json' -d '{}'
You'll see content-type and content-length, and nothing else.
What you'll build
| Header | Value | On which responses | Why |
|---|---|---|---|
Cache-Control |
no-store |
/authenticate, success and error |
Personal data must never be written to any cache |
X-Content-Type-Options |
nosniff |
every response | Stops browsers guessing a different content type |
Referrer-Policy |
no-referrer |
every response | Nothing to leak, but it's the safe default |
X-Frame-Options |
DENY |
every response | No page here should ever be framed by another site |
Not in scope:
Content-Security-Policy: the Swagger UI at/loads scripts from a CDN, so a CSP needs care. That's a separate issue if wanted.Strict-Transport-Security: Render terminates HTTPS, so it belongs there.
#168 is adding Cache-Control: no-store to /health. Don't change /health here; if #168 has merged, make sure the two don't fight.
Step-by-step guide
Step 1: Explore how responses leave the app
app/app.py: findmetrics_middleware(@app.middleware("http")). This is the pattern you'll copy.- Read the long comment in
record_request_metricsinapp/metrics/middleware.py. It explains that handled errors (400, 401, 502 …) become normal responses below the middleware, so a middleware sees them, but an unhandled 500 is rendered above it and isn't seen. That's fine for this issue; mention it in a comment.
Step 2: Write the middleware
Add a second @app.middleware("http") function, security_headers_middleware, that awaits call_next(request) and then sets the headers on the response. Put the header values in a module-level constant, and set Cache-Control: no-store only when request.url.path == "/authenticate". Give it a docstring and type annotations like the rest of app/app.py (ruff will check).
Step 3: See it work
Run uv run python -m app.app --debug and repeat the curl -i above (a 400), then curl -i http://localhost:5000/health and curl -i http://localhost:5000/metrics. The headers should appear as described in the table.
Step 4: Write tests
Follow the patterns in tests/integration/test_app_integration.py (it uses TestClient):
-
/authenticatesuccess (patchapp.app.pesu_academy.authenticate) has all four headers, includingno-store. -
/authenticate400 and 401 responses also haveno-store. -
/healthand/metricshave the three general headers. - The Swagger UI at
/still loads (200).
Run uv run python scripts/run_tests.py. Coverage must stay at 100%.
Step 5: Document it
Add a short "Response headers" note to the README's /authenticate section.
Step 6: Open your PR
- Bump the minor version in
pyproject.toml(for example5.0.0→5.1.0), then runuv lock. CI checks this. If someone else's PR merges first, bump again from the new version. - Run
uv run pre-commit run --all-filesand fix anything it reports. - Open the PR from your fork, against the
devbranch. - Use a Conventional Commit title, e.g.
feat: add security headers and no-store to API responses. - Write
Closes #191in the PR description.
Done when
- Every response carries the three general headers, and
/authenticatealso carriesCache-Control: no-store - Tests cover success, error and non-auth routes, and coverage is 100%
- The README mentions the headers
- Pre-commit passes, the version is bumped, and the PR is from your fork against
dev
Want to go deeper?
The repo has detailed guides in .agents/pesudev-skills/auth/docs/. Run git submodule update --init if the folder is empty. architecture.md (the request lifecycle, including middleware order) and security.md are the most useful ones for this issue.
- Lenguaje dominante
- Python
- Estrellas
- 22
- Forks
- 29
- Merge medio
- 1 d 2 h
- PR fusionados (30 d)
- 20
Preparar el entorno
- Incluye un Dockerfile o un archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de pesu-dev/auth
-
Check the README for dead links and fix the misleading Docker Hub badgeQuizá libre de nuevo @knownshah la tomó hace 19 días y no hay ningún pull request abierto. Abiertodocumentation good first issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
pesu-dev/auth#220 · 2 comentarios ·
Los mantenedores suelen responder en 1 día
-
bug documentation enhancement
Dificultad 3/5 1-2 días Aptitud para principiantes 54/100
Los mantenedores suelen responder en 1 día
-
Commit SHA should be used instead of tag git based deployPosiblemente ocupada @aditeyabaral la tomó hace 13 días. Abiertobug
pesu-dev/auth#236 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Private Functions in `app.py` needs to be in separate filePosiblemente ocupada @aditeyabaral la tomó hace 13 días. Abiertoapi enhancement
pesu-dev/auth#235 · 1 comentario · 1 asignado ·
Los mantenedores suelen responder en 1 día
-
Gather the campus mapping and other shared values into constants modulesPosiblemente ocupada @edgelordlinux la tomó hace 13 días. Abiertoapi enhancement good first issue pesuacademy student profile tests and ci/cd
pesu-dev/auth#230 · 3 comentarios · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de pesu-dev/auth
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
aws-samples/sample-per-model-bedrock#295 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 76/100
pyrevitlabs/pyRevit#3792 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 69/100
zephyrproject-rtos/reqmgmt#177 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
polarsource/polar#15580 ·
Los mantenedores suelen responder en 1 día
-
[开源推荐] Windows 系统维护工具箱,支持后台任务队列Abierto
Dificultad 1/5 Menos de una hora Aptitud para principiantes 85/100
521xueweihan/HelloGitHub#4011 ·