Tests / test (pull_request) Successful in 1m10s
Brings preauth from 18/34 to 30/34 conformance (auth-gateway profile). The
remaining four checks all depend on files this branch cannot change (see below).
PHP toolchain (§1)
- require.php >=8.4 -> ^8.5, and pin config.platform to 8.5.0. The old
constraint also permitted PHP 9, which is not a promise we can keep.
composer.lock regenerated with --lock: content-hash + platform-overrides
only, zero dependency version movement.
- friendsofphp/php-cs-fixer * -> ^3.95. A wildcard meant CI was not
reproducible.
PHPStan (§2.2)
- vendor the shared phpstan.neon.dist (level 6) + a generated baseline.
187 errors are captured rather than fixed; the baseline should only shrink
from here.
- add phpstan/phpstan:^2.1 to require-dev.
Code style (§8.2)
- vendor the shared .php-cs-fixer.dist.php (@Symfony + @Symfony:risky +
declare_strict_types) and apply it: 59 of 67 files reformatted.
- Verified this is a formatting change, not a behaviour change: all 313 tests
pass after the reformat, all in_array() calls already passed strict=true,
and the remaining edits are @Symfony:risky idiom (yoda conditions, \count(),
self:: over the class name).
Repository layout (§4.4)
- docs/{Caddyfile,compose.yaml,example.env} -> docs/examples/, with
example.env becoming the conventional .env.example. This is the layout
GUIDING-LIGHT already cites preauth as doing correctly — it just needed
renaming.
- update the four readme.md references and a stale compose.yaml comment.
- docs/v1.1-plan.md references are left alone deliberately: it is a historical
plan recording what was done at the time, not live documentation.
Licence and security policy (§7)
- add LICENSE (uniform MIT, matching composer.json).
- add SECURITY.md describing the actual threat model: per-request
allow/intercept, no caching of the login flow, app-set security headers,
TOTP, and the fact that REMOTE_USER is trusted input.
Mobile accessibility (§3.3a)
- templates/base.html.twig: drop maximum-scale=1 and add viewport-fit=cover.
preauth was the one app already past the font-size precondition (controls
render at 21.6px = 0.9em x 24px), so removing the lock is safe here and
restores pinch-zoom for Android users.
Conformance tooling (§8.2)
- vendor .ci/conformance.sh and .ci/css-control-size.py so the check runs
from a checkout rather than fetching from the LAN-only private/ci.
- .editorconfig synced from the version that keeps the Caddyfile tab rule.
Not included (blocked by the .gitea/workflows pre-receive hook):
- ci-composer-audit, ci-composer-validate, ci-reusable-workflows.
Workflow files may only change via a trusted ref, so the caller files are
staged but not committed.
Also not included: dockerfile-nonroot (§6.4). Adding USER to an image with
VOLUME [/config, /data] changes volume ownership and needs an actual container
build/run to verify, so it goes in its own change.
86 lines
3.6 KiB
Bash
86 lines
3.6 KiB
Bash
# --- main options ---
|
|
|
|
# URI containing secret and config for TOTP, which determines the token to login
|
|
# app will generate one, if not provided, but you should copy it to your .env file
|
|
# format: "otpauth://totp/<label>?secret=<secret-key>"
|
|
#TOTP_URI='' # blank to have the app generate one at random
|
|
|
|
# how long will someone stay logged in, measured in seconds, zero for DEFAULT
|
|
#COOKIE_TTL=2592000 # default 30 days
|
|
|
|
# we can use a central auth, so that users only need to login once to have access to
|
|
# multiple services. Requires using sub-domains under the same domain.
|
|
# IE: if enabled have "service-one.example.com" redirect "auth.example.com", and after
|
|
# successful auth, user can visit "service-two.example.com" without having to login again.
|
|
#SUBDOMAIN_REDIRECT=false # default disabled, boolean
|
|
#AUTH_SUBDOMAIN='' # blank, hostname we send user to, to see login page
|
|
|
|
# --- extra options ---
|
|
|
|
# how long do we allow *ALL* traffic from an ip address after successful login
|
|
# could be useful if you have a system which does not handle cookies
|
|
#IP_TTL=0 # default disabled, time in seconds
|
|
|
|
# once blocked, do we respond with "I'm a teapot", false to use "Too many requests"
|
|
#TEAPOT=true # default enabled, boolean
|
|
|
|
# --- server / worker options ---
|
|
|
|
# (container/deployment only) restart each FrankenPHP worker thread after
|
|
# this many requests, containing memory growth across long uptime;
|
|
# matching the default from the old runtime/frankenphp-symfony package.
|
|
# 0 disables restarts. consumed by the Caddyfile, not the PHP app.
|
|
#MAX_REQUESTS=500 # default 500
|
|
|
|
# --- remote-user header ---
|
|
# Controls the value sent in the Remote-User header on successful auth.
|
|
# session: the session id (default, backward-compatible)
|
|
# static: a fixed string (set via REMOTE_USER_STATIC)
|
|
# mapped: look up session id in REMOTE_USER_MAP (format: id1:user1,id2:user2)
|
|
# none: do not send the Remote-User header at all
|
|
#REMOTE_USER=session
|
|
#REMOTE_USER_STATIC=authenticated
|
|
#REMOTE_USER_MAP=''
|
|
|
|
# --- rate limiting ---
|
|
|
|
# Note: rate limiting can *NOT* be disabled, but you could allow hundreds of logins a second
|
|
# rate limiting, default is the lower of 2 per 30 seconds or 10 per hour
|
|
#BURST_COUNT=2 # 2 per 30 seconds
|
|
#BURST_TIME=30 # seconds
|
|
#UPPER_COUNT=10 # 10 per hour
|
|
#UPPER_TIME=3600 # seconds (1 hour)
|
|
|
|
# --- public access (rate-limited, no auth required) ---
|
|
# Comma-separated path patterns for public access. Wildcards:
|
|
# * matches any chars within one path segment (not crossing /)
|
|
# ** matches any chars including / (crosses path segments)
|
|
# Optional host prefix: host.example.com/path/**
|
|
# When empty (default), the feature is fully disabled.
|
|
#PUBLIC_PATHS=''
|
|
#PUBLIC_BURST_COUNT=100 # max requests per burst window per IP
|
|
#PUBLIC_BURST_TIME=60 # burst window in seconds
|
|
#PUBLIC_UPPER_COUNT=500 # max requests per sustained window per IP
|
|
#PUBLIC_UPPER_TIME=3600 # sustained window in seconds (1 hour)
|
|
|
|
# --- styling options ---
|
|
|
|
#TITLE='Pre-Authentication System'
|
|
#BG_COLOR='#029386' # teal
|
|
#FG_COLOR='#ffffff' # white
|
|
#ERROR_COLOR='#ffb16d' # apricot (light orange)
|
|
#ID_NAME='Session ID'
|
|
#TOKEN_NAME='Authentication Token'
|
|
#SUBMIT_NAME='Submit'
|
|
#ERROR_MESSAGE='Unsuccessful login attempt'
|
|
# title and message to use on block page, if teapot is true
|
|
#TEAPOT_TITLE="I'm a teapot"
|
|
#TEAPOT_MESSAGE='I refuse to brew coffee'
|
|
# title and message to use on block page, if teapot is false
|
|
#TOO_MANY_TITLE='Too many requests'
|
|
#TOO_MANY_MESSAGE='Try again later'
|
|
|
|
# --- debug options ---
|
|
#SHELL_VERBOSITY=0 # set to "3" to log debug
|
|
|