Skip to content

Fulla v1.1.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 15:37
· 103 commits to master since this release

[1.1.0] - 2026-09-01

⚠️ Breaking (security hardening)

  • ⚠️ Breaking (security hardening) — legacy password hash rejected by default (#103): auth.allow_legacy_hash now 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.sql moved to benchmarks/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_origins is 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 codes WEBAUTHN_INVALID_ATTESTATION (3015) and WEBAUTHN_CHALLENGE_MISMATCH (3016).
  • ⚠️ Breaking (security hardening) — social login response shape change (#70): /api/{google,wechat}/login now 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 switch external_auth.auto_create_on_first_login, default true; when disabled, an unlinked login returns 403 AUTH_SOCIAL_ACCOUNT_NOT_LINKED (5003)); issuance is recorded via the SOCIAL_LOGIN_TOKEN_ISSUED audit 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.com

SPDX 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