mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 02:54:26 +00:00
Blocking a persona removes the only end-to-end proof that a role's auth chain works. docs/contributing/artefact/files/role/playwright.specs.js.md:146 has always required each flag to carry a one-line nocheck stating the role contract that justifies it, plus a matching paragraph in the role's README or TODO. Nothing enforced it, so 89 flags across 46 roles carried neither. The lint mirrors test_has_spec's shape and uses is_suppressed_at with mode="line-above", so the marker must sit directly above its flag -- a blank line between them breaks the association, which is what the persona helper's reader will look at. A literal =false blocks nothing and is exempt; the sso-conditional ternary is not, because it blocks in every variant that pins services.sso.enabled false. Writing 89 reasons turned out to be the point. Five roles audited in one pass blocked for five entirely different mechanisms, all of which read as the same shrug behind a bare =true: pgAdmin's login id is the account e-mail rather than the Keycloak username; phpMyAdmin authenticates as the MariaDB root account; GitLab's seeded password belongs to the built-in root, not the administrator; Mastodon's tootctl accounts create never sets a password; phpLDAPadmin binds with an LDAP DN and a different secret. Further out: MediaWiki removes the form that would accept the Keycloak secret ($wgPluggableAuth_EnableLocalLogin=false) and bounces anonymous requests back into the IdP, so the unauthenticated landing the contract asserts can never be observed; Mattermost Team Edition has no native OIDC, so Keycloak rides the GitLab OAuth slot behind a relabelled link; MinIO's console returns redirectRules: null and renders no SSO button at all; XWiki's administrator is an XWikiUsers object with no password property. Two flags turned out to be unjustifiable and are gone rather than annotated. web-app-mailu gated PERSONA_GUEST_BLOCKED on services.dashboard.enabled, but runGuestFlow does one anonymous goto and asserts no signed-in marker -- it never touches the dashboard. A leftover from a helper version that entered through the dashboard account menu. And web-app-mig's rationale claimed the role is an in-app module of web-app-dashboard; it has its own compose stack, healthcheck and canonical domain, and dashboard is merely a tile consumer. Nine of the reasons say plainly that the block is not a role property but a gap in the shared persona helpers -- decidim's sign-out is a data-method link the generic click cannot activate, fider's SSO entry is a two-step modal, taiga, wordpress, xwiki, odoo and penpot bind OIDC on a path the personas never visit, jenkins blocks unconditionally although its OIDC variant looks runnable, and opentalk's own spec proves both personas work. That list did not exist before; it is the actual yield here, not the 89 comment lines. 45 pre-existing comments came into the comment lint's scope because this sweep touched their files -- it only inspects files that differ from HEAD. 28 of them were the banner "Service gate flags rendered for closure.", every one sitting above a line that is not a service gate flag at all, orphaned by the alphabetical re-sort these templates once got. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
36 lines
2.3 KiB
Bash
36 lines
2.3 KiB
Bash
ADMIN_PASSWORD={{ lookup('users', 'administrator').password | dotenv_quote }}
|
|
|
|
ADMIN_USERNAME={{ lookup('users', 'administrator').username | dotenv_quote }}
|
|
|
|
APP_BASE_URL={{ lookup('tls', application_id, 'url.base') }}
|
|
|
|
BIBER_PASSWORD={{ lookup('users', 'biber').password | dotenv_quote }}
|
|
|
|
BIBER_USERNAME={{ lookup('users', 'biber').username | dotenv_quote }}
|
|
|
|
CANONICAL_DOMAIN={{ lookup('domain', application_id) | dotenv_quote }}
|
|
|
|
# nocheck: playwright-service-gate — covered by sys-svc-mail integration tests, not the persona surface
|
|
EMAIL_SERVICE_ENABLED={{ lookup('config', application_id, 'services.email.enabled') | string | lower }}
|
|
|
|
LOGOUT_SERVICE_ENABLED={{ lookup('config', application_id, 'services.logout.enabled') | string | lower }}
|
|
|
|
MATOMO_BASE_URL={{ lookup('tls', 'web-app-matomo', 'url.base') | dotenv_quote }}
|
|
|
|
MATOMO_SERVICE_ENABLED={{ lookup('config', application_id, 'services.matomo.enabled') | string | lower }}
|
|
|
|
NODE_TLS_REJECT_UNAUTHORIZED=0
|
|
|
|
OIDC_ISSUER_URL={{ OIDC.CLIENT.ISSUER_URL | dotenv_quote }}
|
|
|
|
# nocheck: persona-block-rationale — Postmarks has no account system at all: its only native credential is the single shared ADMIN_KEY typed into the /admin password form (templates/env.j2:7, files/sso/header_auth.js:6, README "Single sign-on"), which is not the Keycloak administrator secret the persona types, and only the trusted-header bridge behind the oauth2-proxy mints an owner session — so the sso: false variants leave no admin login to drive (see README "Persona contract opt-outs").
|
|
PERSONA_ADMINISTRATOR_BLOCKED={{ 'false' if (lookup('config', application_id, 'services.sso.enabled') | bool) else 'true' }}
|
|
|
|
# nocheck: persona-block-rationale — the oauth2-proxy admits only the web-app-postmarks administrator RBAC group (meta/services.yml:12-13) and the bridge re-checks X-Forwarded-Groups against it (files/sso/header_auth.js:63-78), so biber is denied before Postmarks is reached; with SSO off the only credential left is the shared ADMIN_KEY (templates/env.j2:7), which belongs to no user account (see README "Persona contract opt-outs").
|
|
PERSONA_BIBER_BLOCKED=true
|
|
|
|
POSTMARKS_BASE_URL={{ lookup('tls', application_id, 'url.base') | dotenv_quote }}
|
|
|
|
SSO_SERVICE_ENABLED={{ lookup('config', application_id, 'services.sso.enabled') | string | lower }}
|
|
|