Skip to main content

simple_module_site_lock

Optional site-wide password gate for simple_module apps — a staging / pre-launch door. When enabled, every visitor must enter one shared password before they can see anything: not the landing page, not the API, not even that a login form exists.

Off by default. Installing this module changes nothing until an operator turns it on.

Install

Add the package to your host and re-sync — discovery picks it up from the simple_module entry point, no host code changes:

# host/pyproject.toml
dependencies = ["simple_module_site_lock"]
uv sync --all-packages

Or scaffold a new app with it selected: smpy new --modules site_lock.

Usage

  1. Sign in as an admin and open Settings → Modules → SiteLock.
  2. Set password (and optionally message), tick enabled, and Save. Saving with a blank password is refused — the error appears on the enabled field and nothing is persisted.
  3. Anyone without the password now gets the gate page at /__unlock on every URL. They enter the password once and are returned to where they were heading.
  4. To lift the gate, untick enabled and save. To rotate the password, set a new one — every already-unlocked visitor is logged back out of the gate.

Keep your own session alive while you do this: an admin with a live session skips the gate, which is what lets you undo a mistake (see Admin bypass below).

How it works

The module installs a single middleware that runs before AuthMiddleware. That ordering is the whole point — an anonymous visitor gets the gate rather than a redirect to the login page, so a locked site never reveals that it has one.

It achieves that ordering by declaring depends_on=["Settings", "Auth"]: modules are installed in topological order and Starlette's add_middleware is LIFO, so sorting after Auth makes this middleware wrap outermost.

Unlock state lives in the signed session cookie. The stored marker is a fingerprint of the current password, so rotating the password immediately invalidates every unlocked session.

Enabling it

Settings → Site Lock:

Field Default Meaning
enabled false Master switch
password "" The shared password. Masked in the admin UI
message "" Optional line shown on the gate page

Changes apply immediately — no restart. Enabling with a blank password is rejected by a validator, so you cannot accidentally gate the site behind the empty string.

What stays reachable when locked

  • /health — always. Gating it would fail Kubernetes liveness/readiness probes and get the pod killed.
  • /__unlock — the gate page itself.

Everything else is gated. Requests under /api/, and any request carrying an Authorization header, get 403 {"detail": "Site is locked"} rather than a redirect — a 401 would invite an auth flow that cannot succeed while the site is locked. Browser requests get a 302 to the gate.

That includes the login API itself, so while the gate is on there is no programmatic way in: CI smoke tests, uptime monitors, mobile clients and webhook senders all get 403 no matter what credentials they hold. Only a browser that has passed the gate (or an admin holding a live session) can reach anything. Pause those integrations before enabling the gate, or point uptime checks at /health, which stays open.

Admin bypass, and the lockout you can still cause

A user who already holds a session with the admin role skips the gate. This is the intended escape hatch: if you enable the gate and mistype the password, you are still holding the session that lets you go straight back to Settings and fix it.

It only rescues a live session. If no admin is currently signed in and the password has been forgotten, there is no in-app recovery. Clear the override directly in the database:

DELETE FROM settings_setting
 WHERE scope = 'system' AND key = 'site_lock.enabled';

Then restart the app (or save any setting) so the module re-hydrates.

Brute-force protection

The unlock endpoint tracks failures per client IP in memory: 10 failures within 5 minutes trigger a 15-minute cooldown returning 429. These thresholds are module constants, not settings — they are the only defence on a single shared secret, so they are not an operator-tunable surface.

The limiter is process-local, which is adequate for the single-process staging deployments this module targets.

What this is not

This is not user authentication or authorisation — that is what the auth, users, and permissions modules are for. The site lock is one shared secret in front of everything, with no notion of identity.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

simple_module_site_lock-0.0.33.tar.gz (14.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

simple_module_site_lock-0.0.33-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

Details for the file simple_module_site_lock-0.0.33.tar.gz.

File metadata

  • Download URL: simple_module_site_lock-0.0.33.tar.gz
  • Upload date:
  • Size: 14.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for simple_module_site_lock-0.0.33.tar.gz
Algorithm Hash digest
SHA256 472880a80b7615bfdc98f71620cf52491c68a1c706aa5d0c9c8b9f5e77d3c96c
MD5 5c4f6e414891c0fa94477c0bc3111345
BLAKE2b-256 7f5a1d2367b748132319a402ed1dddb1e6c3a6c2b97310d8cb94c0430ec29c42

See more details on using hashes here.

Provenance

The following attestation bundles were made for simple_module_site_lock-0.0.33.tar.gz:

Publisher: release.yml on antosubash/simple_module_python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file simple_module_site_lock-0.0.33-py3-none-any.whl.

File metadata

File hashes

Hashes for simple_module_site_lock-0.0.33-py3-none-any.whl
Algorithm Hash digest
SHA256 d3f76c72ed1b98cbc50dff358c19ff243ce7c61f506303766788b09201fd59ce
MD5 c62674aada5285b28942b4d2e4d78f1f
BLAKE2b-256 2cb63c2a77acad1c28f00aea93ecf02ebc255aa677b4e5f7e7c3b12408335009

See more details on using hashes here.

Provenance

The following attestation bundles were made for simple_module_site_lock-0.0.33-py3-none-any.whl:

Publisher: release.yml on antosubash/simple_module_python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.0.33 This release

2 files

0.0.32

2 files

0.0.31

2 files

0.0.30

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page