Skip to main content

A small authenticated ingress portal for internal services

Project description

auth-ingress

A small server-rendered FastAPI portal that authenticates internal users before allowing them to enter downstream services that do not implement their own login flow.

Install from PyPI

auth-ingress requires Python 3.12 or newer. Install a stable release in a virtual environment and pin the version in managed deployments:

python -m venv .venv
source .venv/bin/activate
python -m pip install "auth-ingress==0.1.0"
auth-ingress --help

The distribution name is auth-ingress, the Python import namespace is auth_ingress, and the preferred command is auth-ingress:

from auth_ingress.main import create_app

Rename compatibility

auth-ingress is the current product, package, repository, command, and operator-facing configuration identity. The previous distribution name auth-entry-portal, command auth-portal, and AUTH_PORTAL_* configuration prefix may still appear in historical release notes, old automation, audit evidence, and migration examples. During the migration window:

  • use auth-ingress for new installs and current documentation;
  • auth-portal remains available as a compatibility command;
  • AUTH_INGRESS_* settings take precedence when both prefixes are present;
  • AUTH_PORTAL_* settings are still accepted when the preferred key is absent;
  • auth_ingress is the Python import namespace for runtime code;
  • cookie names and signed-token salts may retain old internal labels to avoid breaking active sessions or historical evidence.

Before first use, configure a high-entropy secret and an explicit database URL, then initialize the schema:

export AUTH_INGRESS_SECRET_KEY="replace-with-a-high-entropy-secret"
export AUTH_INGRESS_DATABASE_URL="sqlite:////absolute/path/auth_ingress.db"
auth-ingress init-db
auth-ingress serve --host 127.0.0.1 --port 8000

Upgrade only after reviewing CHANGELOG.md, then install the exact new version and rerun application smoke checks:

python -m pip install --upgrade "auth-ingress==<new-version>"
auth-ingress --help

Verify the installed version with python -m pip show auth-ingress. Remove the package with python -m pip uninstall auth-ingress; database files and external configuration are intentionally retained and must be removed separately if no longer needed.

Trust boundary

The portal is an access-control boundary only when downstream services are reachable exclusively from the portal or a trusted internal network. Never configure a publicly reachable downstream URL: users who know it could bypass the portal. Destinations are restricted to loopback, private IP addresses, .internal hosts, and local mock:// demo targets. Embedded credentials, query parameters, and fragments are rejected.

Credentials are Argon2-hashed. Browser cookies contain only a signed opaque reference to a server-side session and use HttpOnly and SameSite protections. Production deployments must set AUTH_INGRESS_SECRET_KEY to a high-entropy value, enable AUTH_INGRESS_SECURE_COOKIES=true, terminate TLS, and protect the SQLite file at the operating-system level.

Setup and operation

For a production-style first installation, create the first administrator with the one-time local bootstrap command. It prompts twice without echoing or accepting the password as an argument:

uv run auth-ingress bootstrap-admin \
  --email admin@example.com \
  --display-name "Administrator"
uv run auth-ingress serve --host 127.0.0.1 --port 8000

Before bootstrap, sign-in displays local setup guidance and never exposes a registration form. Repeating the command after any identity exists makes no change. If setup fails before completion, correct the reported non-secret input or storage problem and safely retry the same command.

For disposable development data only:

uv sync --extra test
uv run auth-ingress init-db
uv run auth-ingress seed-demo
uv run auth-ingress serve --host 127.0.0.1 --port 8000

Configuration uses these environment variables:

  • AUTH_INGRESS_DATABASE_URL
  • AUTH_INGRESS_SECRET_KEY
  • AUTH_INGRESS_SESSION_COOKIE
  • AUTH_INGRESS_SESSION_TTL
  • AUTH_INGRESS_SECURE_COOKIES
  • AUTH_INGRESS_RATE_LIMIT_ATTEMPTS
  • AUTH_INGRESS_RATE_LIMIT_WINDOW
  • AUTH_INGRESS_AUDIT_RETENTION_DAYS (minimum/default: 90)
  • AUTH_INGRESS_PASSWORD_RESET_TTL (minimum: 300 seconds; default: 1800)
  • AUTH_INGRESS_SMTP_HOST, AUTH_INGRESS_SMTP_PORT, AUTH_INGRESS_SMTP_SENDER
  • AUTH_INGRESS_SMTP_USERNAME, AUTH_INGRESS_SMTP_PASSWORD, AUTH_INGRESS_SMTP_STARTTLS
  • AUTH_INGRESS_SMTP_TIMEOUT
  • AUTH_INGRESS_USER_PAGE_SIZE (10–100; default: 50)
  • AUTH_INGRESS_MANAGEMENT_RATE_LIMIT_ATTEMPTS, AUTH_INGRESS_MANAGEMENT_RATE_LIMIT_WINDOW
  • AUTH_INGRESS_DOWNSTREAM_TIMEOUT

Demo accounts use the addresses shown by the seed implementation. seed-demo prompts for each password, or reads the local-only AUTH_INGRESS_DEMO_ADMIN_PASSWORD, AUTH_INGRESS_DEMO_MEMBER_PASSWORD, and AUTH_INGRESS_DEMO_OUTSIDER_PASSWORD values. Each must contain at least 12 characters. The CLI deliberately does not print credentials. Remove all demo accounts and unset these variables before deployment.

Administrators manage users at /admin/users or with auth-ingress users. Memberships remain the only per-user access-list input; user detail explains all groups granting each service. Page and CLI mutations preview first and reject a stale user revision. Creating a user generates a one-time temporary password that is shown only in the create response; the user must change it immediately after first sign-in. Later password resets can still use configured SMTP links; reset secrets are stored only as digests and never shown to an operator. Deactivation is the reversible soft-delete path; permanent removal deletes the user account and authentication state while retaining audit history. See docs/user-management.md for commands, exit codes, conflict recovery, lifecycle controls, and delivery troubleshooting.

Audit and recovery

Sign-in attempts, sign-out, allowed and denied service entry, and administrative changes create structured database audit events. Context is allowlisted to a correlation ID and coarse client category; passwords, cookies, session IDs, secrets, request bodies, and unnecessary personal data are excluded. Retain events for at least 90 days and back up the database according to organizational policy.

If a downstream service fails, the portal returns a generic unavailable response without retrying unsafe requests or exposing internal details. Operators should use the response correlation ID and audit events to investigate. Revoke access by disabling a user, removing group membership, disabling a service, or revoking its active sessions; authorization is re-evaluated on every protected request.

Full web-app proxy deployment

Full proxy mode gives every service an isolated browser origin. Production deployments require:

  • A dedicated portal host configured with AUTH_INGRESS_HOST.
  • Wildcard DNS and TLS for *.AUTH_INGRESS_PROXY_BASE_DOMAIN.
  • AUTH_INGRESS_PROXY_SCHEME=https and secure cookies.
  • Private network routing from the portal to every downstream destination; downstream services must remain unreachable from user networks.
  • A narrow comma-separated AUTH_INGRESS_TRUSTED_DOWNSTREAM_NETWORKS value.
  • Explicit request/response byte limits, launch-ticket lifetime, upstream timeout, and WebSocket maximum lifetime appropriate to the deployment.

Relevant settings are AUTH_INGRESS_PROXY_BASE_DOMAIN, AUTH_INGRESS_PROXY_SCHEME, AUTH_INGRESS_PROXY_COOKIE, AUTH_INGRESS_PROXY_LAUNCH_TTL, AUTH_INGRESS_PROXY_MAX_REQUEST_BYTES, AUTH_INGRESS_PROXY_MAX_RESPONSE_BYTES, AUTH_INGRESS_PROXY_WEBSOCKET_LIFETIME, and AUTH_INGRESS_TRUSTED_DOWNSTREAM_NETWORKS.

Enable proxy mode per service only after its compatibility check succeeds. Applications should use relative or root-relative URLs, or be configured with their public service origin. Fixed private origins embedded in JavaScript are not rewritten. Roll back by disabling proxy mode for the service; the legacy simple entry flow remains available for non-proxy service entries.

Validation

uv run pytest

The full manual journey is documented in specs/002-full-web-app-proxy/quickstart.md.

Project details


Download files

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

Source Distribution

auth_ingress-0.1.0.tar.gz (96.8 kB view details)

Uploaded Source

Built Distribution

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

auth_ingress-0.1.0-py3-none-any.whl (72.4 kB view details)

Uploaded Python 3

File details

Details for the file auth_ingress-0.1.0.tar.gz.

File metadata

  • Download URL: auth_ingress-0.1.0.tar.gz
  • Upload date:
  • Size: 96.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for auth_ingress-0.1.0.tar.gz
Algorithm Hash digest
SHA256 a54a0850652d849099d8ed5d90a31e85722d168d7f23c617a5f1c1a53fc7d823
MD5 061f4796ec322d9d224739f94f56d71b
BLAKE2b-256 c42eae9702e5aedc0566717cd4f4ad13d057b9652a9cbd6112e5055ffcc159d0

See more details on using hashes here.

Provenance

The following attestation bundles were made for auth_ingress-0.1.0.tar.gz:

Publisher: release.yml on zondatw/auth-ingress

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

File details

Details for the file auth_ingress-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: auth_ingress-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 72.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for auth_ingress-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 45e8cf8173db3bd86d4df7e9ed31075897e8295b0f2f12d45698a498e156c812
MD5 d39dd11f61c8952d781253e5817ab0a0
BLAKE2b-256 058223fb7bacbdd0125a201d2ecfdae2a4b0d0ef9ee79dee70670b4140ffd36f

See more details on using hashes here.

Provenance

The following attestation bundles were made for auth_ingress-0.1.0-py3-none-any.whl:

Publisher: release.yml on zondatw/auth-ingress

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

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page