Skip to content

feat(auth): env-driven docente email allowlist - #159

Merged
LucasACH merged 1 commit into
mainfrom
feat/docente-email-allowlist
Jun 17, 2026
Merged

LucasACH merged 1 commit into
mainfrom
feat/docente-email-allowlist

Conversation

@LucasACH

Copy link
Copy Markdown
Owner

What

Adds BUSCASAM_DOCENTE_EMAIL_ALLOWLIST — a comma-separated set of exact emails that are granted the docente role regardless of their Google hd (hosted-domain) claim.

Motivation: demonstrate docente-only features (moderation) with a non-UNSAM account (e.g. a personal Gmail) without owning a @unsam.edu.ar account, and without hardcoding addresses in source.

How

  • role_from_claims (backend/src/buscasam/core/auth.py) checks the allowlist after the email_verified gate and before ROLE_BY_HD. So:
    • email_verified != True is still rejected — the override never bypasses verification.
    • Non-listed accounts keep the exact hd domain behavior.
  • BUSCASAM_DOCENTE_EMAIL_ALLOWLIST setting parsed into a normalized (lowercased, stripped) docente_emails frozenset. Empty by default → no-op.
  • The hd not-null users column is unaffected: complete_login already falls back to the email domain (e.g. gmail.com) when the claim is absent.

Security / docs

This is a deliberate exception to ADR-0005 item 2 (the hd claim as sole trust boundary). Documented as ADR-0005 item 17, with guidance to keep the list minimal and remove entries when no longer needed.

Tests

backend/tests/unit/test_auth_core.py (all green):

  • prod: allowlisted email → docente (case-insensitive)
  • prod: allowlisted but email_verified=False → rejected
  • prod: non-listed Gmail → rejected

Deploy

After merge + v* tag auto-deploy, set on the prod VM and restart the backend:

BUSCASAM_DOCENTE_EMAIL_ALLOWLIST=achaval.lucas@gmail.com

🤖 Generated with Claude Code

Add BUSCASAM_DOCENTE_EMAIL_ALLOWLIST: a comma-separated set of exact
emails granted the `docente` role regardless of their `hd` claim. This
is an escape hatch for demo / non-UNSAM accounts that must moderate,
without weakening the verification gate or hardcoding addresses.

role_from_claims checks the allowlist after the email_verified gate and
before ROLE_BY_HD, so email_verified != True is still rejected and the
hd domain map is unchanged for everyone else. Empty by default (no-op).

Documented as ADR-0005 item 17 (a deliberate exception to the
hd-is-sole-trust-boundary rule). Tests cover prod grant (case-
insensitive), the unverified-email rejection, and non-listed Gmail.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@LucasACH
LucasACH requested a review from MarcosACH as a code owner June 17, 2026 19:16
@LucasACH
LucasACH merged commit bdc43ba into main Jun 17, 2026
3 checks passed
@LucasACH
LucasACH deleted the feat/docente-email-allowlist branch June 17, 2026 19:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant