Repository navigation
v1.4.0
·
145 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
fogwall 1.4.0
fogwall 1.4.0 turns the push gateway into a broader SCM control plane: it now proxies the SCM CLIs (gh, glab, tea, fj) so pull/merge requests, issues, comments and merges flow through the same inspection and audit path as pushes, and it links proxy users to their upstream SCM accounts (GitHub, GitLab, Forgejo/Gitea) for real identity enforcement. The default developer push workflow is unchanged, but operators upgrading from 1.3.2 have several config renames and tightened defaults to review below.
Breaking changes & upgrade notes
- Server mode routing —
/server/is now canonical,/push/is a deprecated alias. The mode formerly called "store-and-forward" is now "server mode", served at/server/<provider>/<owner>/<repo>.git. Existing/push/…remotes keep working through the alias, so nothing breaks on upgrade, but move remotes and scripts to/server/— the alias will be removed in a future release. The dashboard REST fieldpushPathis renamedserverPath. (#538, #540) - SSH is now a property of a provider entry, not a separate provider. One
providers:entry serves both HTTP and SSH to the same upstream, and identity/permissions/OAuth links apply across both. A top-levelssh://urino longer enables SSH and warns at startup — consolidate any separategithub-ssh-style entries into the HTTP entry. Additive config only, no DB migration. See https://rbc.github.io/fogwall/configuration/ssh-transport.html (#531, #534) commit.identity-verificationrenamed tocommit.attribution-policy. The old key still binds with a startup deprecation warning and will be removed in a future release. The legacycommit.*.email.domain.allow/local.blockkeys are likewise kept as deprecated aliases for one minor release. See https://rbc.github.io/fogwall/configuration/commit-attribution.html (#146, #552)- Tightened push size defaults. A new
server.max-object-size-bytes(default 512 MiB,0= off) bounds the decompressed size of any single object, and the shipped size defaults are lower than before. These apply only to deployments that omit the keys — operators who relied on the previous 256 MiB / 100 MiB behaviour should set the old values explicitly when upgrading. (#532) - Forwarded-header trust is now an explicit setting.
server.trust-forwarded-headers(defaulttrue) gates the forwarded-header filter. The default keeps existing ingress deployments working unchanged, but set it deliberately — when on, the listener must be reachable only through the ingress that sets the headers. See https://rbc.github.io/fogwall/configuration/server.html (#587, #635) - Dashboard API mutations are now default-deny. Every
POST/PUT/PATCH/DELETEunder/apirequiresROLE_ADMINunless it is an explicit user-facing exception (own profile, push review, issues, OAuth links). Reads are unchanged. Custom integrations that called a mutating endpoint as a non-admin will now get a 403. (#647) - Controls that cannot run now fail closed. Malformed pushes, a validation control whose dependency is unwired, and a secret scan whose objects cannot be resolved now block the push instead of silently passing; admin self-approval whose entitlement cannot be verified is rejected. Correctly-wired deployments see no change. (#532, #547, #558, #643)
- Database migrations V15, V16 and V17 apply automatically on startup (SCM API entities, SCM token/login cache, SCM API merge records). No action required.
New features
- Contribution lifecycle through the SCM API proxy. Open, edit, comment on, close and merge pull/merge requests and issues via
gh,glab,teaandfjrouted through fogwall, with the same content inspection applied to outbound PR/MR and comment bodies and a full audit record of every mutation. Enabled per provider underscm-api. See https://rbc.github.io/fogwall/configuration/scm-api.html and https://rbc.github.io/fogwall/admin/scm-api.html (#264, #565, #578, #606, #619) - SCM OAuth account linking with strict identity mode. Link proxy users to their GitHub, GitLab or Forgejo/Gitea accounts; in strict mode a push identity resolves only from OAuth-imported SSH keys and the push record names the account the token actually belongs to. See https://rbc.github.io/fogwall/configuration/scm-oauth.html (#40, #380, #528, #575, #599, #603)
- PROPOSE and MAINTAIN permission grants.
PROPOSEallows opening PRs/MRs, issues and comments;MAINTAINbundles push, propose and merge. Both assignable from the dashboard. See https://rbc.github.io/fogwall/configuration/permissions.html (#563, #564, #600, #604, #633) require-validated-headcontrol for contributions. Refuses a PR/MR-create whose head commit has no fogwall push record, keyed on the commit SHA. On by default. (#572, #619)- Commit-trailer policy and unified email-match rules. Enforce
Signed-off-byandCo-Authored-Bytrailers and match author/committer/trailer emails through one rule model; annotated tag messages are now content-validated and taggers held to the committer email policy. See https://rbc.github.io/fogwall/configuration/commit-attribution.html (#146, #474, #541, #552) - OpenTelemetry observability. Traces, metrics and log correlation across the push and SCM API proxy paths, opt-in via config. See https://rbc.github.io/fogwall/configuration/observability.html (#327, #641, #642, #648)
- Fetch toggle and configurable clone depth for server mode. Run a push-only gateway by disabling clone/fetch globally or per provider, and set the local mirror clone depth. (#476, #478, #537)
- Dashboard: admin, setup and inspection. Admin navigation grouped behind a dropdown with a responsive drawer; an in-app developer setup guide that generates git config and remote routing; an admin page to inspect and invalidate the local mirror cache; advanced push-record filters; error toasts with server detail and a per-provider SCM API availability badge; and an audit log of every administrative action with actor, target and outcome. (#98, #288, #340, #475, #548, #555, #585, #607, #626, #627, #628, #634)
- Runtime build version and commit exposed at runtime and in the dashboard. (#579, #596)
Security
- Closed an admin self-approval bypass of self-certify. An admin could approve their own push through admin override without holding self-certify, forwarding it end to end in the transparent proxy. Self-review now always runs the self-certify gate; admin override is redefined as break-glass for another user's push only, and a stale unentitled approval demotes to
ERRORon re-push. (#643) - Default-deny authorization for dashboard API mutations — a newly added mutating endpoint fails closed for non-admins instead of inheriting any-authenticated access. (#647)
- Secret scanning now reaches quarantined push objects. Since rejected-push objects moved to a quarantine store, gitleaks (which shells out to
git) could not resolve the pushed commits and recorded a falsePASS; the quarantine object directory is now exposed to the scan, which fails closed if the tip is unresolvable. (#558) - Bounded decompressed push size and fail-closed malformed pushes to cap resource use and reject truncated/malformed packs. (#532)
- Fail closed on missing control dependencies and bound permission-regex matching against pathological patterns. (#547)
- Stopped leaking configured API-key length via comparison timing, and routed unknown-op request diagnostics through slf4j with
Cookie/Proxy-Authorizationredaction. (#535) - OIDC ID tokens are always fully validated; two authorization read-path bugs affecting config-declared users were fixed (both already fail closed). (#524, #559)
Bug fixes
- Nested repository paths are preserved — GitLab subgroup paths are no longer truncated to two segments by URL rules and permissions. (#577, #590)
- Repository paths match case-insensitively in access rules and grants. (#576, #595)
- Push options are rejected in both proxy modes. (#594)
- Signed pushes are rejected by name instead of being misreported as multi-branch. (#536)
- One lifecycle record per push in server mode, not three. (#533)
checkTrailerspush feedback is consistent with the other validation steps. (#608, #609)- Adding a config-declared user to a group no longer 500s. (#631)
- Abandoned pending pushes expire and are superseded in transparent proxy mode. (#591, #615)
Performance
- Virtual-thread request handling finished — shared heartbeat scheduler and thread configuration. (#452, #557)
- Repository-cache concurrency — per-key clone lock, per-repo push serialization, and a server-tuned JGit pack cache. (#556, #561)
Maintenance
- PMD static analysis with a starter ruleset, constructor injection throughout the dashboard, a canonical
PushStepKindidentity for hooks and filters, a chain-drift guard test, a captured-fixture UI regression suite, and the guides split into pages published with mdBook. (#543, #549, #560, #586, #612, #613, #637, #639) - Renamed the contribution surface: "Contributions" in the UI, "SCM API" in config and internals. (#650)
Dependencies
- Java — grouped dependency updates plus a netty transitive pin at 4.1.137.Final. (#529, #583, #624, #629)
- Frontend (npm) — grouped dependency updates. (#525, #526, #584)
- GitHub Actions — grouped action and CodeQL updates. (#522, #523)
Upgrade
- Review the config renames above and update your YAML:
store-and-forward//push/→ server mode and/server/, SSH consolidated into the provider entry,commit.identity-verification→commit.attribution-policy. The old keys still bind with a deprecation warning, so this can be staged. - If you relied on the previous push size limits, set
server.max-object-size-bytesand the size keys explicitly — the shipped defaults changed. - Set
server.trust-forwarded-headersdeliberately for your ingress topology. - Confirm any non-admin integrations against
/apimutating endpoints still have the access they need — mutations are now default-deny. - Migrations V15, V16 and V17 apply automatically on first startup — no manual step.
- Pull the new images.
Full Changelog: v1.3.2...1.4.0