Commit Graph
2 Commits
Author SHA1 Message Date
kevinveenbirkenbachandClaude Opus 5 1bd8cd5619 fix(yourls): let every replica salt from the same cookie key
YOURLS_COOKIEKEY salts both yourls_cookie_value() and yourls_create_nonce()
through yourls_salt(). The role never exported it, so config-container.php
took its `getenv('YOURLS_COOKIEKEY') ?: 'modify this text with something
random'` fallback and the image entrypoint replaced that placeholder with
`head -c1m /dev/urandom | sha1sum` - once per container.

In compose that is invisible: one container, one key. In swarm the replica
count follows the inventory group, and the group holds three hosts, so three
tasks each salted differently. A login form rendered by one replica carried a
nonce the next could not verify, and YOURLS answered the POST with
yourls_die( 'Unauthorized action or expired link', 'Error', 403 ) - the exact
403 body captured in run 34687966607, job 103540992501. The login cookie fails
the same way, which is why the page snapshot shows YOURLS's own login screen
again and the administrator persona reported no reachable logout control.

Only the SSO-less variant can show it. With sso enabled oauth2-proxy carries
the identity and the native login, and with it the nonce path, is never
exercised.

The key becomes a stored credential beside administrator_password, same
algorithm and validation, so it is generated once per deployment and read back
identical. With the variable present the getenv branch wins and the entrypoint
leaves the placeholder alone.

Unchanged in origin/main, where env.j2 carries no COOKIEKEY and the variants
and replica lookup are identical, so any swarm deployment running YOURLS
without SSO on more than one replica has the same defect.

The first deploy after this invalidates existing sessions and open nonces,
because the salt changes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 16:30:20 +02:00
kevinveenbirkenbachandClaude Opus 5 ef5ea7cb55 refactor(roles): name the credential file meta/secrets.yml
meta/schema.yml held credential definitions and their runtime values, but the
name said 'schema' and read like structural metadata next to services.yml and
volumes.yml. Nothing in the file is a schema in the sense the other meta files
use the word, and a contributor had to open it to learn it holds secrets.

62 role files renamed. ROLE_FILE_META_SCHEMA becomes ROLE_FILE_META_SECRETS and
keeps its role as the SPOT the path is built from.

Two readers bypassed that constant and spelled the name themselves:
utils/cache/applications.py built meta_dir / 'schema.yml' twice, and
plugins/lookup/application_gid.py carries the filename in the marker list it
detects application roles by. Left behind, the rename would not have raised —
credentials would have resolved empty and the role would have stopped counting
as an application.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 12:08:06 +02:00