Skip to main content

Fadebox 1.3

The 1.3 line: fadebox/fadebox:1.3 follows its newest release, and the 1.3 docs describe every release on it. Moving between releases is covered in Upgrading.

1.3.3 — 2026-09-17​

An instance can be personal. Until now any deployer in a project could stop, reset, redeploy or delete any instance in it, and the card never said whose it was. Every card now names its creator, and an instance is either shared with the project — what every instance was — or personal to whoever created it: only they, the project's editors and maintainers may operate a personal one, while everyone else still sees it, its status and its logs, and the controls they may not use say whom to ask. Which one a new instance starts as is the environment's New instances are shared switch; the creator or an editor can share or unshare it afterwards, and the CLI has --shared / --personal on instance create and up, and instance share / unshare. Each change is audited as instance.sharing_changed. See Ownership and Shared or personal instances.

The creator's email on the card is the administrator's to show. The name links to the creator's email so a blocked colleague can reach them; Administration → System has a switch to hide it for an installation that runs across contractors or partners. Audited as system.creator_email_changed.

Upgrade notes. One migration, applied on start. Every environment and instance you already have stays shared, so nothing anybody could do yesterday is refused today. An environment created after the upgrade starts with New instances are shared off, so its instances are personal to whoever creates them — a pipeline's, to its service account — until an editor switches it on or holds editor themselves; see Who gets which role. On the API, instances carry shared and createdByEmail, environments sharedInstances, and a call a deployer may not make on a personal instance answers 403 instance_personal naming the creator. Older CLI binaries keep working; the one served by the upgraded installation knows the new flags.

1.3.2 — 2026-09-15​

A field that only takes a slug now says so. A project's git repositories and both kinds of API key carry one identifier apiece, labelled Name but validated as a slug — so typing App repo was refused, after the fact, with Lowercase slug. All three now read Slug, and each says what the value is for: a repository's is the name a reference addresses it by ({{git:app-repo:main}}), a key's is how you tell which one to revoke. What the fields accept has not changed, and nothing already registered is renamed. See Register a repository.

Adding a catalog source starts with the name. Catalog → Add source asked for the slug first, the opposite of every other create form in the interface. It now leads with the name and fills the slug in from it as you type, still yours to edit before you save; the name stays optional, so a source can be registered by typing the slug alone, exactly as before. See Register a source.

Sheets fade in place. The side panels that carry the create and edit forms slid in over half a second, and a display that dropped a frame mid-slide showed a form cut off part-way — which is what made a busy page look broken rather than slow. They now fade in where they will sit, in the same 150ms as the backdrop behind them.

Upgrade notes. None. No migration, no setting, and nothing on the API side: the renamed fields were always slugs and the requests behind them are unchanged.

Documentation. The 1.2 docs are now archived — still published for the installations still on that line, and marked in the version picker as no longer maintained. Fixes land on 1.3; see Upgrading. The 1.0 and 1.1 docs remain archived.

1.3.1 — 2026-09-15​

The deploy history is a place, not a box. Every attempt already recorded what it ran — the images after every resolution pass, the overrides as applied, what it did to each container, the commit behind each git reference, the checks, the verdict, the captured log — and all of it was read through a small scroller in the status panel, which showed everything except the overrides. An attempt is now a page of its own: one block per service joining the image, the commit it came from, the override values as they were applied and whether its container was created, restarted, kept or removed, with the error, the checks, the verdict and the log download in full. It leads with what changed since the attempt before it — a tag, a variable, a commit, a service that arrived or left — and any other kept attempt can be chosen as the baseline, the choice travelling in the URL so a comparison can be pasted into a ticket. The instance's history is a page (history on the card, Full history in the status panel, whose Deploys section keeps one line per attempt), each row carrying its own short changed since, and two rows can be picked to compare. History on the environment page lists every kept attempt of every instance, paged and filterable by instance and outcome. Nothing about the record or its retention changes: the last 20 attempts per instance, as before. See Deploy history.

Upgrade notes. None. For API clients: GET …/environments/{envName}/deploys is new (viewer), paged, with repeatable instance and outcome filters (PENDING selects an attempt still in flight; an unknown value is a 400) and sort on startedAt, instance, outcome or kind; each row is {instance: {slug, name}, attempt}, the attempt in the shape GET …/instances/{slug}/deploys already returns, minus logs. The existing listing is unchanged.

1.3.0 — 2026-09-14​

This release is about the instance as a place people work, not only a thing that runs. An instance can now say why it exists, a pipeline can say what it found on it, a person can say yes or no to it, the record says which commit it came from, and its logs survive the stop. Beside that, a guessed password costs something.

An instance says why it exists. It always knew what it ran; what it could not know was which pull request, which customer demo, which bug somebody made it for. An instance now carries a purpose — one line under its name — and up to eight links, each a label and a URL: the merge request, the ticket, the design doc. Set them in the New Instance sheet, with --purpose and --link on fadebox instance up, or afterwards from the card's Describe… action; the instance list shows the purpose beside the slug. They describe the instance rather than what it is running, so no redeploy, reset or stop clears them. See What a copy is for.

A pipeline reports what it found, and a person says yes or no. A check is a named result a pipeline writes on the instance — build, e2e, smoke — as pending, passed or failed, with a one-line summary and a link to the run; reporting the same name again replaces it, which is how one suite says pending when it starts and passed when it ends. A verdict is a person's approved or rejected, with a note that is optional on a yes and required on a no. Both sit on the running deploy attempt, never on the instance: a redeploy starts a new attempt with no checks and no verdict, and the previous attempt keeps both — which is what answers the tester who says but it passed yesterday. On the card, checks are badges and the verdict a chip beside them; the status panel and every row of the deploy history carry the ones of that attempt. Approving, rejecting and reporting are deployer acts — fadebox instance check, approve, reject, verdict — and an agent can set a verdict but never report a check. See Checks and the verdict.

The record says which commit a git reference read. Every {{git:…}} reference the environment uses resolves to a commit when the instance deploys, and the attempt now records it: per repository and ref, the commit it answered from and which services read it. The card reads gitops · a7c48fe on master, and last Tuesday's attempt still names the commit it ran after the branch has moved on. Nothing to set and nothing extra fetched; the commit is a link to the forge's commit page on github.com, gitlab.com and codeberg.org over https, and plain text anywhere else. See Which commit a git reference read.

A pipeline can get through a sign-in gate. On a runtime whose instance URLs require a sign-in, a redirect to the sign-in page is no use to a test runner, so a pipeline could deploy an instance and then not open it. A project deployer can now mint the gate's cookie directly — fadebox instance token <slug>, or POST …/access-token — one value per hostname the instance holds, valid twelve hours, naming the pipeline's own service account. A runtime without the gate answers with an empty list rather than refusing, so one job step works against both, and nothing is stored: every call mints fresh values, and the audit log records which hostnames a call covered and never the values. fadebox instance up --print-token rolls the deploy and the mint into one step. See Letting a pipeline through.

The logs outlive the stop. Stopping or resetting an instance removed its containers, and a container's log went with them — worst for exactly the instance that failed, was stopped to free the runtime, and is now the subject of what did it actually say. Both now read every container's log before removing it and keep the capture beside the deploy attempt it belongs to. Nothing about reading changes: when no container is running, the same log tail and the same Download serve the capture and say so, in the status panel as captured at and over the API as a response header. Each history row keeps its own capture, downloadable after later attempts. A capture is scoped and capped exactly as an export is, can neither fail nor materially delay a stop, and is kept as long as its attempt — the last twenty per instance. A plain redeploy does not capture: what it leaves behind is a running instance. See Logs outlive a stop.

Guessing a password now costs something. Five consecutive failed sign-ins lock a password account for a minute, and every lock costs a fresh five failures — the window deliberately does not escalate, because an escalating lock lets anyone who knows a username hold the account shut for nothing, and the bootstrap makes admin a username everyone knows. Beside it, every failed credential check — sign-in, API key or agent token — spends one token from an allowance of ten per client address, refilled ten a minute, which is what covers one password sprayed across many usernames. A locked or throttled attempt answers exactly as a wrong password does — same page, same status, same delay — and the audit log is where the difference is written: an admin sees the lock and tells the user, and clears it early by resetting the password or reactivating the account. Single sign-on is untouched. See Guessing is expensive.

Fixed. On a host where SELinux is enforcing and the Docker daemon runs with its SELinux integration on — Fedora and RHEL by default — the managed ingress installed cleanly and routed nothing: the socket proxy could not open the bind-mounted daemon socket, Traefik never received a router, and every instance URL was Traefik's own 404 while both containers were Up and the dialog said up to date. The socket proxy now runs with the daemon option label=disable, a no-op anywhere else; Traefik never touches the socket and stays confined. The shipped compose file sets the same option on the app container, whose socket mount had the same problem. See SELinux hosts. On a crowded environment row the service name was the first thing to shrink — document-service read as documen… while the image tag beside it kept its full width; the name now keeps its width and the tag gives way, and the catalog badge folded into the template chip as a small icon leading to the same entry. The framework underneath moved to Quarkus 3.39.3.

Upgrade notes. Four migrations run on startup, V009 to V012: the purpose and links on an instance, the checks and the verdict on a deploy attempt, and the sign-in counter on a user. Existing rows get none of them. Add FADEBOX_LOGS_CAPTURE_DIR: /data/logs to the app service of your compose file, as the installation file now does — without it captures go to the container's own home directory and are lost when the container is recreated; the setting is in Log export. The sign-in lock and the throttle are on by default; an installation with a web application firewall doing this already switches them off with FADEBOX_AUTH_LOCKOUT_THRESHOLD=0 and FADEBOX_AUTH_THROTTLE_BURST=0, and one behind a reverse proxy that has not yet set QUARKUS_HTTP_PROXY_TRUSTED_PROXIES should know that until it does every client shares the proxy's one allowance — see Sign-in hardening. The lock works on every tier; the audit events that explain it are written only where the audit log is. A managed ingress stack installed by an earlier release shows outdated after the upgrade; Update recreates the socket proxy with label=disable, and only an SELinux host needs it — the manual deploy/ingress bundle carries the same option. An app container on an SELinux host wants the security_opt line the installation compose file now carries. For API clients: PUT …/instances/{slug}/purpose, PUT/DELETE …/instances/{slug}/checks/{name}, PUT/DELETE …/instances/{slug}/verdict and POST …/instances/{slug}/access-token are new (deployer), as is GET …/instances/{slug}/deploys/{id}/logs/export (viewer); an instance carries purpose and links, a deploy record carries checks, verdict, logs and resolved.references, and a stopped instance's status carries capturedLogs; the log tail answers with X-Fadebox-Log-Source and, for a capture, X-Fadebox-Log-Captured-At, and the export refuses its scoping parameters on a capture with a 400; PUT /api/users/{id} clears a lock when it resets the password or reactivates the account. New refusal codes: purpose_invalid, check_invalid, verdict_invalid, and instance_state for a check or a verdict on an instance with no running deploy. New audit actions: instance.purpose_updated, instance.check_reported, instance.check_removed, instance.verdict_set, instance.verdict_withdrawn, instance.access_token_issued, instance.logs_captured, user.login_locked. The CLI's instance list table gained a PURPOSE column between SLUG and STATUS; a script that cuts the table by column should read -o json instead. The MCP registry gained describe_instance and set_instance_verdict.

Documentation. The 1.3 docs are the ones served by default. The 1.2 docs stay published and maintained for as long as the 1.2 line receives fixes; the 1.0 and 1.1 docs remain archived.