Skip to content

Releases: voidvec/fulla

Fulla v1.3.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 13:16

[1.3.0] - 2026-09-14

⚠️ Breaking (client identity)

  • The first-party OAuth2 clients are renamed: vue-clientfulla-portal (user portal) and admin-consolefulla-admin-console (admin console). Deployments upgrading from ≤ 1.2.0 must rename the existing rows once so consents and tokens keep pointing at a live client (run before or right after starting the new version — the startup seeder fills in whatever is still missing):
UPDATE oauth2_clients SET client_id = 'fulla-portal' WHERE client_id = 'vue-client';
UPDATE oauth2_client_scopes SET client_id = 'fulla-portal' WHERE client_id = 'vue-client';
UPDATE oauth2_clients SET client_id = 'fulla-admin-console' WHERE client_id = 'admin-console';
UPDATE oauth2_client_scopes SET client_id = 'fulla-admin-console' WHERE client_id = 'admin-console';

Frontend deployments compiled with VITE_CLIENT_ID=vue-client must rebuild with the new id (the Docker images ship fulla-portal by default).

⚠️ Breaking (environment variables)

  • FULLA_VUE_CLIENT_SECRET / FULLA_VUE_REDIRECT_URI are renamed to FULLA_PORTAL_CLIENT_SECRET / FULLA_PORTAL_REDIRECT_URI; the old names remain honored as deprecated aliases. New: FULLA_ADMIN_CONSOLE_REDIRECT_URI registers the admin console's production redirect URI.

Added

  • Startup seeding of config-declared OAuth2 clients (#204): production had no path from the plugin config's clients block to the database, so a freshly deployed server failed login at code issuance with 3001. A startup seeder now inserts config-declared clients (both first-party clients ship declared in all configs) idempotently — production deployments no longer need any manual client SQL.

Fixed

  • Registration no longer leaves users guessing about email verification: the success screen now persists, names the address the verification email was sent to, and links to login explicitly.

Commit-level changes

  • oauth2: Rename first-party clients to fulla-portal / fulla-admin-console
  • oauth2: Declare fulla-portal + fulla-admin-console in all shipped configs
  • frontends: Portal client id becomes fulla-portal, admin becomes fulla-admin-console
  • user: Tell users to verify their email after registration
  • main: Correct OAuth2Plugin lookup and expose clients seed config publicly

Fulla v1.2.0

Choose a tag to compare

@github-actions github-actions released this 14 Sep 03:52

[1.2.0] - 2026-09-14

Added

  • website: Docusaurus blog module + launch-post draft frame
  • blog: Launch-post charts — five-scenario + cold-start, reproducible

Fixed

  • security: 2026-09 audit — P0 batch (nonce, revocation, issuance guards)
  • ci: PR #197 review — migration/api baselines, nonce length cap, branch coverage
  • ci: Strict-JSON configs — drop jsoncpp-only // comments
  • deploy: Rehearsal findings — migrate build section, doc drift, bootstrap password passthrough
  • deploy: PR #199 review — --build on migrate run, AUTO_MIGRATE drift sweep, zh-CN guide sync
  • auth: Send verification email on registration + unauthenticated resend (issue #198)
  • auth: Guard email-verification against memory-storage mode

Documentation

  • support: Route SDK users (Python/Go clients + C++ embed) to the right entry points
  • blog: Launch post — full draft prose (all five sections)

Testing

  • auth: Leave-no-trace cleanup in email-verification tests

Other

  • ci: Normalize test names to Unit_OAuth2_ prefix (naming gate)
  • ci: Test names follow Unit__ convention (naming gate)

Verification

Images are signed with cosign (keyless, GitHub OIDC):

cosign verify ghcr.io/voidvec/fulla-backend:1.2.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.2.0-linux-x86_64.tar.gz.sha256

Fulla v1.1.1

Choose a tag to compare

@github-actions github-actions released this 10 Sep 15:30

[1.1.1] - 2026-09-10

Added

  • frontend: Add en/zh-CN i18n via vue-i18n curated catalogs (ADR-0013)
  • Decision items #88-3 / #105 / #110 — client_id logout identification, coverage ratchet gate, signing-key rotation keystore
  • frontend: Reactive error locale, AOT i18n precompile + size gate, image build smoke
  • claude: Distill session experience into skills, rules, commands and hooks
  • claude: Add deployment runbook skill for docker env split and WSL prod staging

Fixed

  • admin: Nginx absolute_redirect off — redirects dropped the mapped host port
  • release: Splice curated breaking-change entries into release notes
  • frontend: Address PR #156 review — locale switcher reactivity, a11y, hardening
  • Issues batch 2 — #122/#144/#145/#146
  • #157 review: Session demotion after forced change, lockout on wrong old_password, dual-key revoke, mfa_pending ordering, gate assertions
  • tests: Drop unused execSql helper breaking -Werror=unused-function on GCC/Clang
  • #157 review round 2: Erase-first all re-writable session keys, lockout read side, portal-aware redirect, RNG fail-closed, JSON-only change endpoint
  • i18n: Integrate the forced-password-change form into the #156 catalogs
  • #176 review: RSA-only key guard, unopenable-pem hard fail, rotation-proof script assertions, JWKS cache note, workflow paths
  • ci: De-flake the expiry boundary test; make the gcov report pass loud and locatable
  • #176 review round 2: POST end_session client_id spec, keystore-dir gate test, baseline-keyed ratchet exemption, keystore filename hardening, changelog
  • ci: Grant pull-requests: read on the frontend call job for the image-smoke paths filter
  • frontend-user: Isolate image build type-check from cross-app test imports
  • oauth2: Device approval crash — shared-callback fix in DeviceCodeService
  • health: /health/ready Redis timeout guard; dashboard survives Redis outages
  • portal: Resume OAuth after login; drop zombie sessions; stop burning codes
  • identity: Generate usernames for blank registrations + backfill NULL rows
  • config: Point FULLA_VUE_CLIENT_SECRET at the OAuth2Plugin client entry
  • config: Drop the hardcoded vue-client secret from config.prod.json
  • server: Address PR #180 review M1/M2/M4/M5/M7
  • portal: Address PR #180 review M3/M6/M9
  • claude: Refresh stale facts and repair commit/format hooks
  • release: Codex review — SDK guide tag/push mismatch + regenerate openapi.json

Documentation

  • readme: Add PyPI and Go SDK badges
  • changelog: Fix compare links after v1.1.0
  • changelog: English for the v1.1.0 breaking entries
  • changelog: Unify the changelog in English
  • community: Add community health files (#106)
  • root: Neutralize vendor-specific CLAUDE.md / CODEBUDDY.md (#113)
  • issues: Add internal tracking issue template
  • website: Fix stale MIT references; land ubuntu-24.04 doc sync

Testing

  • scripts: Dedupe full-test manual endpoint layer via ctest JUnit proof (#119)
  • identity: Cover the new blank-username branches (coverage ratchet)

CI/Build

  • deps: Bump the actions-minor group across 1 directory with 2 updates
  • deps: Bump actions/upload-artifact from 4.6.2 to 7.0.1
  • deps: Bump docker/build-push-action from 6.9.0 to 7.3.0
  • deps: Bump actions/setup-python from 5.6.0 to 7.0.0
  • deps: Bump actions/download-artifact from 4.3.0 to 8.0.1

Miscellaneous

  • docker: Shrink the build context (node_modules, dist, docs, website, clients, benchmarks)
  • migrations: Ratify V029 into the migration-check baseline
  • api-diff: Ratify PortalUrl.h (additive) and the NOT NULL model regen
  • coverage: Seed the ratchet baseline from PR #176's own green CI run
  • deps-user: Bump the user-frontend-minor group
  • deps-admin: Bump the admin-frontend-minor group
  • deps: Coordinated frontend majors — TS7 (side-by-side TS6 API), vite 8, eslint 10, vue-router 5, plugin-vue 6
  • config: Dual loopback redirect URIs for vue-client; run_server path fix
  • hygiene: Scrub developer-local absolute paths from tracked files
  • api-diff: Ratify baseline for the env-override path fix
  • migrations: Ratify baseline for V030/V031
  • api-diff: Ratify baseline for DeviceCodeService callback signatures
  • claude: Remove dead OpenSpec commands and superseded release skill

Verification

Images are signed with cosign (keyless, GitHub OIDC):

cosign verify ghcr.io/voidvec/fulla-backend:1.1.1 \
  --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.1-linux-x86_64.tar.gz.sha256

Fulla v1.1.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 15:37

[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

Fulla v1.0.1

Choose a tag to compare

@github-actions github-actions released this 30 Aug 16:14

[1.0.1] - 2026-08-30

License

  • License change: MIT -> AGPL-3.0. Starting with this version the project
    is licensed under the GNU Affero General Public License v3.0; the v1.0.0
    release remains MIT. The core stays fully open source — individuals,
    study, self-hosting and internal use are unaffected. Vendors offering the
    software (modified or not) as a hosted service must release their
    modifications per AGPL-3.0 §13, or obtain a commercial license
    (open-core: enterprise features are distributed separately). A CLA is
    required for contributions so the project can keep dual-licensing.

Added

  • oauth2: VerifyJwt follow-ups — expectedAud, nbf, strict base64url, verifyAndDecode, ephemeral kid (#87)
  • config: Production gates for signing key and weak client secrets (#102)
  • identity: Unlink guard counts WebAuthn credentials + post-delete race recheck (#73)
  • social: Disable providers with empty/placeholder credentials (#111)
  • social: Server-side one-time link state, closing provider-code injection (#71)
  • ops: Schedule ensure_audit_partitions() on the cleanup cycle (#83)
  • security: Consent authentication gates + admin bootstrap + password policy (IAM hardening tranche 1)

Fixed

  • tests: Repoint FULLA_DOC_API_REFERENCE to docs/domains/ after IA restructure
  • docs: Keep error-table message strings catalog-exact in the EN api-reference
  • website: Localize sidebar/navbar/footer via official i18n files; categorize ADRs
  • oidc: End_session array-aud candidates + enveloped 400s (#88 items 1-2)
  • logout: Backchannel notifier matches both user_id subject forms (#82)
  • CI regressions from batch-1 (WERROR getenv, fallback guard scope, N2 wait, doc table, ignore wording)
  • tests: OAuth2Tests fail-fast 0xc0000409 — three causes, all test-side
  • ci: Ratify RateLimiter.getConfig() in api-diff baseline; exact-prefix oasdiff ignore line
  • ci,docs: Coverage workflow drogon_ctl PATH, API/deployment docs sync (#105, #112)
  • ci: Sanitizer link flags PUBLIC; memory-mode-safe partition test guard
  • mfa: Base32 bit-accumulation overflow (UB) found by the first UBSan run (#104)
  • ci,ubsan: TotpUtils drogon-lib UB + Redis AUTH in sanitizer/coverage workflows
  • ci,asan: Ubuntu 24.04 + RateLimiter UAF + coverage div-zero guard
  • benchmarks: GC jitter root cause analysis — WSL2 I/O scheduling pauses, not runtime GC
  • ubsan,werror: Base64UrlDecode shift UB + GCC 13 redundant-move
  • docker: Add WeChat env override, FULLA_VERSION, and consistency comments
  • config: Add /oauth2/device/approve rbac rule in all five configs
  • admin: Complete MFA login, device approval page, dashboard/log/user honesty fixes
  • user: WebAuthn register contract, real logout, consent user_id, backup codes
  • frontends: Consume MFA PKCE verifier on success, not on entry
  • frontends: Address PR #140 review — logout self-revoke race, mock envelopes, RT retention
  • tests: Drop unused constants breaking -Wunused-const-variable on clang
  • config: Move new auth knobs under custom_config.auth (repo convention)
  • review: Consent_csrf into OpenAPI contract, admin-api password floor, bootstrap self-heal, review cleanups

Documentation

  • readme: Capability map + module map, bilingual
  • readme: Fix zh anchor to the actual SDK layering heading
  • Documentation governance design v1 — triage of docs/ + Docusaurus content sourcing
  • governance: V2 — content-level verdicts from full-text deep review
  • governance: Phase A part 1 — contradiction fixes + triage execution
  • governance: Phase A part 2 — six merges, 12 ADRs, audience navigation
  • governance: Re-execute the history/locals untrack that git add -A had reverted
  • governance: Phase B — Docusaurus site skeleton, zero-copy docs/ sourcing
  • governance: User-only docs tree + IA-shaped restructure (review follow-up)
  • Pre-launch content quality pass (audit P0/P1 fixes)
  • api-reference: Unified simplified Chinese + OpenAPI governance flow
  • adr: Bring the three governance trust archives into the repo
  • Repoint root-facing doc links to the new IA + link fulla.dev
  • Phase C deep-dives + English-primary bilingual site (en + zh-CN)
  • Bilingual follow-up — zh README links to the zh-CN site, dual-write rule in CONTRIBUTING, changelog entry
  • P2 cleanup — ship the verification script, linkify ADR references
  • reports: Add runtime verification for Docker port binding (#112)
  • repo: Add nested AGENTS.md guides for libs/drogon, libs/storage-postgres, apps/server
  • deploy: Fix bootstrap flow, prod seed steps, TLS cert order

Testing

  • Rerun-safe DB seeds in integration tests (#72)
  • Event-driven Redis cache-fill waits replace fixed sleeps (#90)
  • admin: LastAdminGuard self-heals its sole-admin premise (#72)
  • admin: LastAdminGuard sweep must DELETE, not repoint (#72 follow-up)
  • naming: Rename consent gate tests to convention; clean probe

CI/Build

  • frontend: Add production builds to the fast frontend gate
  • frontend: Add production builds to the fast frontend gate
  • SHA-pin all workflow actions + dependabot.yml (#107)
  • Sanitizer gates (ASan+UBSan PR leg, nightly TSan) + UBSan support (#104)
  • frontend: Strict tsc, lint gate, e2e in CI — closing the frontend quality gap (#108)
  • sanitizer: Prepend drogon_ctl's Conan bin dir to PATH (port of the coverage fix)
  • deps: Bump anchore/sbom-action/download-syft
  • deps: Bump actions/setup-go from 5.6.0 to 7.0.0
  • deps: Bump actions/upload-pages-artifact from 3.0.1 to 5.0.0
  • deps: Bump sigstore/cosign-installer from 3.9.2 to 4.1.2
  • deps: Bump actions/cache from 4.3.0 to 6.1.0

Miscellaneous

  • community: Issue templates (bug / feature forms) + contact links
  • deploy: Loopback-bind dev compose data ports + credential warnings (#112)
  • sdk: Regenerate python/go clients from the #71 link-state spec
  • deps-admin: Bump the admin-frontend-minor group
  • deps-user: Bump the user-frontend-minor group
  • deps-admin: Bump pinia from 3.0.4 to 4.0.3 in /frontends/admin
  • deps-admin: Bump globals in /frontends/admin
  • deps-user: Bump pinia from 2.3.1 to 4.0.3 in /frontends/user
  • deps-user: Bump globals in /frontends/user
  • deps-admin: Bump eslint-plugin-vue in /frontends/admin
  • deps-user: Bump vue-tsc from 2.2.12 to 3.3.11 in /frontends/user
  • api-diff: Ratify WeChat env override additions (follow-up to #139)
  • gates: Ratify additive api-diff (RuleSet policy + AuthService legacy gate); oasdiff errata for register password minLength
  • gates: Oasdiff errata entry on one line for text matching
  • Untrack local qoder diff artifacts (not for the repo)
  • Ignore qoder diff artifacts
  • gates: Oasdiff errata — consent_csrf required param is the security fix itself

Other

  • Create CNAME
  • Professional landing page, brand theme, Chinese locale, local search

Verification

Images are signed with cosign (keyless, GitHub OIDC):

cosign verify ghcr.io/voidvec/fulla-backend:1.0.1 \
  --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.0.1-linux-x86_64.tar.gz.sha256

Fulla v1.0.0

Choose a tag to compare

@github-actions github-actions released this 26 Aug 04:11

[1.0.0] - 2026-08-26

Series reset note: the project was renamed from authforge to fulla
(Fulla is the keeper of Frigg's secret coffer in Norse mythology), and the
version series resets to 1.0.0 with this release — the rename is
treated as a new product identity; SemVer constrains package identities,
not the repository (the PyPI package fulla-oauth2, the
ghcr.io/voidvec/fulla-* images, and the CMake package fulla are all
new identities). Prior history is preserved in the repository CHANGELOG
(the authforge-era [1.0.0]–[1.4.1] entries) and in the full git history.

Rename & Branding

  • Repository-wide rename authforge → fulla: C++ namespaces and public
    header paths (#include <fulla/...>), CMake packages and targets
    (fulla::*), binaries (fulla-server / fulla-tests), the Go module
    path, the Helm chart, and the benchmark facility. The api-diff baseline
    was regenerated for the new symbol surface (179 headers, ratified with
    --force, PR #94).
  • Environment variable prefix unified to FULLA_* (previously
    OAUTH2_*, 903 occurrences; protocol class names such as OAuth2Plugin
    are unchanged).
  • Infrastructure naming normalized: database/role fulla_db /
    fulla_user, container names fulla-*, Redis key prefix fulla:cache:,
    Prometheus metrics fulla_* (upgrading invalidates the whole cache at
    once — expected one-time behavior).
  • Frontend branding: Fulla Admin / Fulla, package names fulla-admin /
    fulla-user.
  • Repository governance professionalized (PR #93): AI-tool workspaces
    untracked, kiro design docs moved to docs/history/design/kiro-specs/,
    .claude/ is the single authoritative rules source.

Compatibility

  • C++ SDK consumers: breaking (include paths, namespaces, and the CMake
    package name all changed); migration is essentially one sed pass (mapping
    table in docs/adr/rename-impact-fulla.md §3).
  • Existing JWTs / sessions / database schema: fully compatible (the
    protocol surface carries no project name; table names and migrations are
    unchanged).
  • The Python SDK package is renamed to fulla-oauth2; the old
    authforge-oauth2 is discontinued.

Verification

Images are signed with cosign (keyless, GitHub OIDC):

cosign verify ghcr.io/voidvec/fulla-backend:1.0.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.0.0-linux-x86_64.tar.gz.sha256