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-ingressfor new installs and current documentation; auth-portalremains 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_ingressis 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_URLAUTH_INGRESS_SECRET_KEYAUTH_INGRESS_SESSION_COOKIEAUTH_INGRESS_SESSION_TTLAUTH_INGRESS_SECURE_COOKIESAUTH_INGRESS_RATE_LIMIT_ATTEMPTSAUTH_INGRESS_RATE_LIMIT_WINDOWAUTH_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_SENDERAUTH_INGRESS_SMTP_USERNAME,AUTH_INGRESS_SMTP_PASSWORD,AUTH_INGRESS_SMTP_STARTTLSAUTH_INGRESS_SMTP_TIMEOUTAUTH_INGRESS_USER_PAGE_SIZE(10–100; default: 50)AUTH_INGRESS_MANAGEMENT_RATE_LIMIT_ATTEMPTS,AUTH_INGRESS_MANAGEMENT_RATE_LIMIT_WINDOWAUTH_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=httpsand 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_NETWORKSvalue. - 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a54a0850652d849099d8ed5d90a31e85722d168d7f23c617a5f1c1a53fc7d823
|
|
| MD5 |
061f4796ec322d9d224739f94f56d71b
|
|
| BLAKE2b-256 |
c42eae9702e5aedc0566717cd4f4ad13d057b9652a9cbd6112e5055ffcc159d0
|
Provenance
The following attestation bundles were made for auth_ingress-0.1.0.tar.gz:
Publisher:
release.yml on zondatw/auth-ingress
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
auth_ingress-0.1.0.tar.gz -
Subject digest:
a54a0850652d849099d8ed5d90a31e85722d168d7f23c617a5f1c1a53fc7d823 - Sigstore transparency entry: 1934304960
- Sigstore integration time:
-
Permalink:
zondatw/auth-ingress@19e7681dc956105bc7ee12a47434d43ec553678e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/zondatw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@19e7681dc956105bc7ee12a47434d43ec553678e -
Trigger Event:
release
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
45e8cf8173db3bd86d4df7e9ed31075897e8295b0f2f12d45698a498e156c812
|
|
| MD5 |
d39dd11f61c8952d781253e5817ab0a0
|
|
| BLAKE2b-256 |
058223fb7bacbdd0125a201d2ecfdae2a4b0d0ef9ee79dee70670b4140ffd36f
|
Provenance
The following attestation bundles were made for auth_ingress-0.1.0-py3-none-any.whl:
Publisher:
release.yml on zondatw/auth-ingress
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
auth_ingress-0.1.0-py3-none-any.whl -
Subject digest:
45e8cf8173db3bd86d4df7e9ed31075897e8295b0f2f12d45698a498e156c812 - Sigstore transparency entry: 1934305083
- Sigstore integration time:
-
Permalink:
zondatw/auth-ingress@19e7681dc956105bc7ee12a47434d43ec553678e -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/zondatw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@19e7681dc956105bc7ee12a47434d43ec553678e -
Trigger Event:
release
-
Statement type: