v1.24.0

Upgrade Notes

v1.24.0 is a security-hardening release. The admission webhooks (with controller-side guards as defence in depth) now reject several primitives that earlier versions silently accepted, and cross-origin browser requests are denied by default. Functions, packages, environments, and triggers that depend on the rejected primitives will fail admission after upgrade — audit your specs before rolling out.

For the general upgrade steps (CRDs, CLI, Helm chart), see the Upgrade Guide. The breaking changes specific to v1.24.0 and the action each requires are below.

Cross-namespace references are rejected

A Function, Package, or KubernetesWatchTrigger that points at a resource in a different namespace is now refused:

  • Function.spec.environment.namespace and Function.spec.package.packageref.namespace must equal the function’s own namespace (or be empty).
  • Package.spec.environment.namespace must equal the package’s own namespace (or be empty).
  • KubernetesWatchTrigger.spec.namespace must equal the trigger’s own namespace (or be empty).

Empty values are unchanged — controllers default them to the object’s own namespace. This closes a set of confused-deputy advisories where a low-privilege subject could make a cluster-wide controller act against another tenant’s namespace.

KubernetesWatchTrigger empty namespace now means “own namespace”

Previously an empty spec.namespace meant watch all namespaces (client-go’s "" semantics), which was itself a cross-tenant leak. It now coerces to the trigger’s own namespace. If you relied on cluster-wide watch, create one KubernetesWatchTrigger per target namespace with spec.namespace set explicitly (each must equal the trigger’s own namespace).

Dangerous PodSpec fields are rejected

Environment and Function reject a denylist of node-escape primitives in their PodSpec: hostNetwork, hostPID, hostIPC, hostPath volumes, container privileged / allowPrivilegeEscalation, dangerous Linux capabilities (SYS_ADMIN, NET_ADMIN, SYS_PTRACE, …), and serviceAccountName override. The Environment runtime/builder container securityContext is validated the same way. Benign customization — image, command, args, env, volumes, resources, nodeSelector, and capabilities like NET_BIND_SERVICE — flows through unchanged.

MessageQueueTrigger goes further: its spec.podspec is reduced to an allowlist of nodeSelector, tolerations, affinity, runtimeClassName, and per-container resources; all other fields are dropped or rejected. MQT-referenced Secret values are no longer copied into the connector pod template — they resolve via secretKeyRef at pod start using the connector’s own ServiceAccount instead.

If any of your specs set these fields, remove them (or move the privileged workload out of Fission’s tenant-facing CRDs) before upgrading.

Cross-origin browser requests are denied by default

All Fission HTTP listeners now emit X-Content-Type-Options: nosniff and deny cross-origin browser preflights on internal listeners. User HTTPTrigger traffic is unchanged by default. If a single-page app legitimately calls a trigger cross-origin, opt in per trigger with the new HTTPTrigger.spec.corsConfig allowlist rather than handling CORS inside the function.

fission-builder ServiceAccount token no longer mounted

Following the fission-fetcher change in v1.23.0, the fission-builder ServiceAccount token is no longer mounted into user builder containers. No action is required unless your build commands depended on that token being present.

Deprecations/Removals

  • We continue to support Kubernetes 1.28 and above (kubeVersion: ">=1.28.0-0" in the Helm chart). No change in supported Kubernetes versions from v1.23.0.
  • Cross-namespace Environment/Package references and dangerous PodSpec fields on Environment, Function, and MessageQueueTrigger are no longer accepted — see Upgrade Notes above.
  • The fission-builder ServiceAccount token is no longer mounted into user builder containers (mirrors the fission-fetcher change in v1.23.0).
  • License headers across the codebase were converted to SPDX identifiers; the one-time strip script has been removed.

Highlights

  • Confused-deputy hardening across the CRD surface. The admission webhooks (with controller-side guards as defence in depth) now reject cross-namespace Environment/Package references on Function, Package, and KubernetesWatchTrigger, closing several high/critical advisories where a low-privilege subject could target another namespace.
  • PodSpec injection is closed. Environment and Function reject a denylist of node-escape primitives (hostNetwork/hostPID/hostIPC, hostPath volumes, privileged, dangerous capabilities, SA override), MessageQueueTrigger PodSpec is reduced to a small allowlist, and Environment runtime/builder container securityContext is validated. Benign customization (image, command, env, resources, nodeSelector, …) is unaffected.
  • Cross-origin defense. A shared middleware adds X-Content-Type-Options: nosniff and Vary: Origin to every response and denies cross-origin browser preflights on internal listeners. A new opt-in HTTPTrigger.spec.corsConfig lets SPAs allowlist origins per trigger without baking CORS into the function body.
  • CRD status conditions. Every Fission CRD now carries a standard metav1.Condition array and observedGeneration, and the controllers write a Ready condition (plus resource-specific ones). Server-Side Apply list markers were added on the fields where atomic merging was wrong.
  • A much richer fission CLI built on those conditions — a READY column, kubectl-style -o json|yaml|wide output, wait --for=condition, and spec apply --dry-run. See Fission CLI below.

Fission CLI

v1.24.0 brings the largest CLI update in several releases, built on the new CRD status conditions. All additions are backward compatible — existing commands, flags, and default table output are unchanged.

Readiness in list and describe output

list commands for the condition-bearing resources — function, package, httptrigger, timetrigger, mqtrigger, watch (KubernetesWatchTrigger), and canaryconfig — now show a READY column by default (True / False / Unknown, or <none> before the controller has reported). package keeps its BUILD_STATUS column and canaryconfig keeps STATUS; READY is added alongside them. Describe-style commands (fn getmeta, pkg info, canary get, ht get) gained a CONDITIONS table (TYPE / STATUS / REASON / MESSAGE / LASTTRANSITION).

Environment is intentionally excluded — the builder manager writes no Environment status, so the column would always be empty.

$ fission httptrigger list
NAME METHOD URL FUNCTION_NAME ... READY
r1   GET    /hello hello      ... True

Output formats: -o json | yaml | wide

The read commands now accept a kubectl-style -o flag. list supports it for function, environment, httptrigger, timetrigger, mqtrigger, watch, canaryconfig, and package; the describe commands (fn getmeta, pkg info, canary get, ht get) support json/yaml.

  • -o json / -o yaml — emit the (already-filtered) objects for scripting with jq/yq.
  • -o wide — the normal table plus an AGE column.
  • no flag — byte-for-byte the previous table output.
$ fission fn list -o json | jq '.[].metadata.name'
$ fission fn list -o wide          # adds AGE

wait --for=condition

A kubectl wait-style subcommand lets scripts, CI, and GitOps flows block until a resource reaches a status condition. Available on the seven condition-bearing resources (Environment excluded).

$ fission fn wait --name hello --for=condition=Ready --timeout=2m
$ fission pkg wait --name p1 --for=condition=BuildSucceeded

The status defaults to True (--for=condition=Ready), or set it explicitly (--for=condition=Ready=False). It polls until the condition matches or --timeout (default 60s) elapses; a timeout exits non-zero so CI fails correctly.

spec apply --dry-run

Preview what a spec apply would create, update, or delete without touching the cluster:

$ fission spec apply --dry-run
1 environment would be created: nodejs
1 function would be created: hello
(dry run - no changes made)

The read-only list, diff, and validation (including HTTPTrigger duplicate-route detection) run exactly as a real apply would — only the cluster-mutating calls and archive uploads are skipped.

Fixes

  • MessageQueueTrigger no longer materializes referenced Secret values into the connector pod template — env vars now resolve via secretKeyRef at pod start using the connector’s own ServiceAccount.
  • Empty KubernetesWatchTrigger.spec.namespace is coerced to the trigger’s own namespace instead of watching cluster-wide.
  • fission httptrigger delete --ignore-not-found now works for multi/last deletes (it previously inspected the wrong error), and several copy-pasted CLI error messages now name the correct operation and resource.
  • Routine security sweeps refreshed Go dependencies (including go-git 5.19.1) and bumped workflow tool versions (skaffold v2.21.0, goreleaser-action v7.2.2).
  • Helm chart published as 1.24.0, versioned independently from the app version.

Changelog

What’s Changed

Full Changelog: https://github.com/fission/fission/compare/v1.23.0...v1.24.0

References

Last modified May 27, 2026: Doc changes v1.24.0 (#284) (07e7a1f)