You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Sign Out button in the side navigation can now be hidden with HIDE_NAV_LOGOUT=true, or console.ui.hideNavLogout on the Helm
chart. It is presentation only — the user menu in the page header
keeps its own Sign Out, so the ability to log out is unchanged.
Bug Fixes
The UAA token endpoint is now checked at the point the request is made,
rather than trusted from wherever it was built. It must be an absolute
http(s) URL with a plain host and path — no user info, query or
fragment. The first-run setup form supplies this value on an
unauthenticated request, so an unconfigured console could be pointed at
an arbitrary URL of a caller's choosing.
Jetstream serves its own HTTPS again where it terminates TLS itself.
Echo v5 resolves a certificate path through a filesystem rooted at the
working directory, which rejects an absolute path outright, and the
certificate was still being passed as a path — so no HTTPS listener
started at all. The Kubernetes chart, and the dev and CI configurations,
all use path shapes that hit this. Deployments on Cloud Foundry were
unaffected, since the router terminates TLS there.
Helm chart files and chart icons no longer 404 on Kubernetes. File
serving now goes through the same rooted filesystem, which accepts an
absolute path only beneath the working directory; the chart sets a cache
folder outside it, so every chart file and icon answered 404 for a file
plainly present on disk. Analysis reports and an absolute UI_PATH had
the same exposure whenever the process was not started from an ancestor
directory.
Jetstream logs through one logger again. Echo v5 logs via log/slog
and defaults to writing JSON to standard output, which meant its
messages interleaved with Jetstream's own text-formatted logs on the
same stream and ignored LOG_LEVEL. Echo's output is now routed into
the application logger, so format and level apply to everything.
API request logs keep the format they had under Echo v4 and remain
gated by LOG_API_REQUESTS; they now also respect LOG_LEVEL.
Deployed logs are no longer written with ANSI colour escapes. Colour was
forced on rather than detected, so every line from a deployed Jetstream
carried escape codes — visible in cf logs, where nothing is a terminal.
A developer running the binary in a terminal still gets colour. The
analysis container had the same problem.
Two boot lines reporting the resolved Cloud Foundry paging overrides were
written before the log handler was installed, so they came out through
the standard library formatter. Under LOG_TO_JSON a collector got two
unparseable records on every start. Boot output is JSON all the way down
now.
A LOG_LEVEL typo used to silence the backend almost completely.
logrus returned its panic level for an unrecognised name and the
error was discarded, so LOG_LEVEL=inof suppressed nearly every
message. An unusable value is now reported and the current level
kept.
Under LOG_TO_JSON, the log level line and the API request log each
emitted a record with a duplicate key, because both passed an
attribute named for a key slog writes itself. Decoders generally take
the last occurrence, so an aggregator read the configured level
string in place of the record's real severity, and the request start
time in place of the record timestamp.
Deploying an application from a private Git repository wrote the
supplied access token to the debug log. The source information line
logged the whole client message, whose payload carries the token.
Only the source type is logged now.
Several failures were reported as success or reported without a
cause: a Helm chart icon whose cache folder could not be created was
returned as a valid path, a truncated chart archive was served as
though it had extracted cleanly, an analysis report that failed to
serialise returned HTTP 200, and both analysis runners logged
completion before checking whether the run had failed.
Two paths that could dereference a nil pointer are fixed: the Helm
client stored a configuration it had already failed to build, and the
Kubernetes dashboard proxy used a URL it had failed to parse.
Numerous log lines that named the wrong function, shared one message
between unrelated failures, or discarded the error they were
reporting now identify what actually happened.
The JSON schema form no longer emits a <form> inside a <form>. The
renderer recurses into itself for nested object schemas and rooted every
level in a form element, which is invalid HTML — the DOM API builds it
anyway, and browsers scope submission and reset in ways the markup did
not intend. Nothing in that template submits, so it is a plain container.
Connecting a Kubernetes endpoint through OIDC or a kubeconfig works
again. RFC 7519 defines the token expiry claim as a number of seconds
since the epoch; it was being read as an RFC 3339 string, so no
conformant token could satisfy it and every attempt failed with
"can not get Access Token expiry time claim".
Artifact Hub is available again when it is enabled. The flag was renamed
from "enabled" to "disabled" when Artifact Hub support landed, but the
test against it was not inverted, so requests were rejected as disabled
precisely when the feature was on — which is the default.
A Helm release whose manifest contains a malformed custom resource is
now reported to the console as having manifest errors. That branch
logged the parse failure but left the flag unset, unlike the branch
beside it.
kube-score analysis jobs are evicted from the job map when they finish.
The busy flag was cleared for popeye runs and never for kube-score, and
the cleanup pass skips busy jobs, so the map grew for as long as the
analysis container ran.
Deploying an application no longer panics when a file check fails for
any reason other than the file being absent — a permission error, a
symlink loop, or an over-long name left a nil result that was then
dereferenced.
The fallback path for the plugin scripts folder contained a stray
character, so a layout that keeps the scripts under the plugin directory
never matched the candidate meant to find it.
The endpoint filter on the Applications, Marketplace and Services
toolbars lists endpoints by name. It was built by walking the endpoint
list in arrival order, which no query orders, so with more than one
endpoint of a kind the dropdown showed whatever order the rows came
back in. "All" stays at the top. The comparator is the one the sibling
dropdowns on those toolbars already use, so cf10 sorts after cf2.
The side navigation no longer offers Sign Out when there is no session
to end. Running with AUTH_ENDPOINT_TYPE=none grants the stratos.noauth scope, which the page header has always honoured; the
side navigation ignored it and showed the button anyway.
Pull requests targeting a release/* branch now run the full test suite.
The workflow triggers listed main, develop and angular** only, so a
release line got no checks at all — pushes to it are gated too.
Maintainability
Jetstream now runs on Echo v5. Echo v4 is in security-and-bugfix-only
maintenance until the end of 2026, and v5 reworked enough of the API —
a concrete request context, log/slog for logging, a rearranged error
handler — that the move had to happen in one step across the backend
and every plugin.
Retired four unmaintained or superseded dependencies: SermoDigital/jose (no upstream release since 2019) is gone from the
Kubernetes auth plugin, which used it only to read one claim from a
token the platform had already issued; satori/go.uuid (abandoned) is
replaced by google/uuid, which the backend already depended on for
the same purpose; golang/mock (archived) moves to its successor go.uber.org/mock; and gorilla/context, obsolete since Go 1.7, is
gone along with the middleware that existed only to call it.
Dropped the archived AWS SDK v1. It was reachable only through
aws-iam-authenticator, which has since moved to SDK v2; the Kubernetes
IAM auth path moves with it.
Upgraded Helm to v3.21.4 and the Kubernetes client libraries to v0.36.
Kubernetes minor releases remove APIs, so these move as a set. This
also repairs dependency maintenance in the Kubernetes plugin, where go mod tidy could not run at all: the previous Helm pulled a kubectl
that imports an API removed in k8s v0.36.
Jetstream now logs entirely through log/slog. Echo v5 had already
moved to slog, which left the backend running two loggers with two
formats and two level settings; a bridge kept them on one stream
during the transition and is now gone. All nine Go modules are
converted, and no first-party code imports logrus anywhere. Log
messages are structured records rather than formatted strings, so
identifiers that used to be interpolated into message text — user,
endpoint and token GUIDs, org and space, chart and release names —
are now attributes that can be filtered and correlated. LOG_LEVEL
and LOG_TO_JSON behave as before, and every level name logrus
accepted still works, including trace, fatal and panic.
Every filesystem operation in the analysis container now re-checks, at
the point of use, that the path still sits beneath the reports
directory, resolving any ".." before comparing. The paths were already
built safely, but the guarantee lived in the constructors: an analyzer
read the job folder and temporary file names directly, so a later change
setting either from somewhere else would have reached the disk
unchallenged. The monocular and Artifact Hub cache paths are built from
validated segments in one place for the same reason.
Chores
Jetstream now builds with Go 1.27. Go 1.27 rejects the invalid hash id
that SermoDigital/jose registers from an init function, which panics
before main and crash-loops the binary. The dependency is reached
through the CF CLI rather than our own code, so it is pinned to a fork
with that registration removed until the CF CLI moves to a maintained
JWT library.
make check lint runs the Go linters again. golangci-lint supports
only a Go version at or below the one that built it, so the Go 1.27
bump left the packaged binary failing before it reached any linter.
It is now pinned and built from source against the toolchain named in go.mod.
Frontend dependencies moved to their current releases: Angular and the
Angular CLI to 22.1.x, marked 16 to 18, js-yaml 4 to 5, sass-loader
13 to 17 and @playwright/test to 1.62. The Angular devkit packages have
to move as a set, and @angular-devkit/build-angular had to be carried
with them by hand: it is deprecated at every published version, and
Dependabot filters deprecated releases out of the candidate list, so it
cannot bump that one package while bumping its siblings. Leaving it behind
resolves two copies of @angular-devkit/architect and the devkit builders
stop type-checking.
Two build scripts imported js-yaml through a default export that
version 5 no longer provides, and failed at module load.
The frontend test matrix in CI listed seven of the eight vitest projects,
so the cf-autoscaler specs ran locally and never in CI.