Fulla v1.1.0
[1.1.0] - 2026-09-01
⚠️ Breaking (security hardening)
⚠️ Breaking (security hardening) — legacy password hash rejected by default (#103):auth.allow_legacy_hashnow defaults to false (a missing config key is also treated as false); unsalted SHA-256 hashes are rejected outright on every path, including old-password verification during a password change. Existing legacy-hash users should migrate via email/admin-initiated password reset (a reset writes a PBKDF2 hash, completing the migration) or by temporarily reopening the window (login transparently re-hashes the credential); note that changing the password alone cannot self-migrate (the old-password check runs through the retired branch as well). Policy rejections do not count toward account lockout. Dev seeds and all scripts now use PBKDF2 (same passwords);bench_users.sqlmoved tobenchmarks/fulla/seed(no longer shipped in the production image).⚠️ Breaking (security hardening) — real WebAuthn signature verification (#142): registration and authentication now perform genuine W3C WebAuthn Level 2 verification (ES256 only, fmt="none"; challenge binding with 300 s TTL and unconditional consumption; UV required; signCount clone detection). V028 purges the existing credential table (all pre-existing rows are unverified client-asserted material — users must re-register their passkeys);webauthn.rp_originsis now a required config key (the finish endpoints fail closed when it is absent); the old request-body contracts ({credential_id, public_key}registration / bare credential_id login) are rejected, closing the hole that allowed impersonation with nothing but a credential_id. New error codesWEBAUTHN_INVALID_ATTESTATION(3015) andWEBAUTHN_CHALLENGE_MISMATCH(3016).⚠️ Breaking (security hardening) — social login response shape change (#70):/api/{google,wechat}/loginnow issues a first-party token pair instead of returning the provider profile (token rows store public_sub — this also fixes existing GitHub tokens 404ing across the /api/me family); the GitHub endpoint spec was corrected accordingly. All three providers now auto-create an account on first login (global switchexternal_auth.auto_create_on_first_login, default true; when disabled, an unlinked login returns 403AUTH_SOCIAL_ACCOUNT_NOT_LINKED(5003)); issuance is recorded via theSOCIAL_LOGIN_TOKEN_ISSUEDaudit event (not a consent row).
Added
- frontend: P0 "Machined Trust" foundation — OKLCH tokens, palette codemod, fonts, brand mark
- frontend: P1 component layer — UI kit retune, DData machine voice, user kit adoption
- frontend: P2 trust facades — vault-door auth forms, consent receipt, admin login
- frontend: P3 data plane — mono metrics, table density, device giant input, user detail pills
- frontend: P4 dark theme + motion — theme store, ramp inversion, stamp pulse
- security: #103 retire legacy unsalted-SHA256 password verification
- social: #70 Google/WeChat logins consume subject mappings and issue first-party tokens
- security: #142 real WebAuthn attestation/assertion verification (ES256, fmt none)
Fixed
- review: PR #148 review — C1/C2 criticals, I1-I6 importants, test gaps
- identity: #143 local subject mapping three-layer fix for consent 500
- test: Fallout from the full-suite run — bootstrap salt, packaging dep, quoting, regression formula
- review: PR #149 adversarial-review findings — async retry lifetime, passkey liveness gate, UV alignment
- build: Cross-platform conan.lock — hand-add libcbor entry instead of regenerating
- test: WERROR fallout in WebAuthnHttpTest — merged #include line, dead placeholder helper
- test,warnings: Cross-compiler blind spots found on the local CP936 toolchain
- scripts: CREATEDB self-heal + precise guidance in setup-database
- scripts: Root-cause classification for setup-database failures
- scripts: Name both causes in the undroppable-database hint
- review: External PR review findings — crossOrigin gate, challenge sweep, signCount CAS, client registration check
- ci-scripts: Fail-soft guard when the staged tests config is missing before the config.ci.json swap
- release: Docker builder base ubuntu:22.04 -> 24.04 (GCC 11 linker ICE on libcbor)
Documentation
- frontend: Design-tokens header reflects the dark-override seat and theme wiring
- changelog: Unreleased entries for #143/#103/#70/#142
Testing
- e2e: Stub /oauth2/token in the google-callback test
- e2e: Poll for the google-callback token storage instead of a fixed sleep
- e2e: Assert the google-callback flow against the real token-storage contract
Other
- frontend: Align the new SocialCallbackPage error box with the #148 token system
Verification
Images are signed with cosign (keyless, GitHub OIDC):
cosign verify ghcr.io/voidvec/fulla-backend:1.1.0 \
--certificate-identity-regexp 'https://github.com/voidvec/fulla/.github/workflows/release.yml.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.comSPDX SBOMs for the three images and the source tree are attached,
as is the SDK tarball checksum:
sha256sum -c fulla-sdk-1.1.0-linux-x86_64.tar.gz.sha256