Skip to content

Enforce authentication globally with a fail-closed public-route allowlist #8

Description

@jzhao234

Problem

Authentication is currently enforced manually inside individual route handlers with is_logged_in(). Existing protected routes include /, /email, and /attachment, but a future route can accidentally be added without the check.

For an application that exposes client email archives, authentication should fail closed by default.

Desired behavior

Enforce authentication once at the application/router boundary with middleware or an equivalent global dependency. Maintain a small explicit allowlist of public endpoints rather than requiring every private route to opt in.

Expected public surface:

  • /login and its required local-auth actions when local password mode is configured
  • /static/*
  • A minimal /health endpoint that returns no sensitive configuration or identity data

Everything else should require a valid identity from the configured authentication provider. The design must remain compatible with both deployment modes:

  • Existing Elcano elcano_auth verification
  • Isolated local username/password sessions for client deployments

Each deployment should configure exactly one provider and fail startup on an unknown or incomplete auth configuration.

Acceptance criteria

  • All current sensitive routes are protected without route-local authentication checks.
  • A newly added test route is protected by default.
  • Missing, expired, malformed, and revoked sessions fail closed.
  • Elcano mode preserves the current redirect to central login.
  • Local mode redirects browser navigation to the local login page and returns an appropriate unauthorized response for non-browser/API requests.
  • Only the documented public allowlist bypasses authentication.
  • Identity headers supplied by an external client are ignored unless they come through an explicitly trusted proxy boundary.
  • Tests enumerate the public allowlist and verify protection of /, /email, and /attachment.

Security impact

This removes an easy future authentication-bypass class: adding a sensitive route and forgetting to copy an is_logged_in() check.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions