mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-09 18:15:50 +00:00
Prepare v6.4.2 security patch
This commit is contained in:
@@ -2,9 +2,9 @@ apiVersion: v2
|
||||
name: pulse
|
||||
description: Helm chart for deploying the Pulse hub and optional Docker, Kubernetes, or OpenShift monitoring agent.
|
||||
type: application
|
||||
version: 6.4.1
|
||||
appVersion: "6.4.1"
|
||||
icon: https://raw.githubusercontent.com/rcourtman/Pulse/v6.4.1/docs/images/pulse-logo.svg
|
||||
version: 6.4.2
|
||||
appVersion: "6.4.2"
|
||||
icon: https://raw.githubusercontent.com/rcourtman/Pulse/v6.4.2/docs/images/pulse-logo.svg
|
||||
keywords:
|
||||
- monitoring
|
||||
- proxmox
|
||||
@@ -32,7 +32,7 @@ annotations:
|
||||
description: Smoke tests with kind cluster deployment
|
||||
artifacthub.io/links: |
|
||||
- name: Documentation
|
||||
url: https://github.com/rcourtman/Pulse/blob/v6.4.1/docs/KUBERNETES.md
|
||||
url: https://github.com/rcourtman/Pulse/blob/v6.4.2/docs/KUBERNETES.md
|
||||
- name: Support
|
||||
url: https://github.com/rcourtman/Pulse/discussions
|
||||
artifacthub.io/maintainers: |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# pulse
|
||||
|
||||
  
|
||||
  
|
||||
|
||||
Helm chart for deploying the Pulse hub and optional Docker, Kubernetes, or OpenShift monitoring agent.
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ version: '3.8'
|
||||
|
||||
services:
|
||||
pulse:
|
||||
image: ${PULSE_IMAGE:-rcourtman/pulse:6.4.1}
|
||||
image: ${PULSE_IMAGE:-rcourtman/pulse:6.4.2}
|
||||
container_name: pulse
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
|
||||
@@ -7,10 +7,14 @@ For historical v4 notes that previously lived in this repo, see:
|
||||
`docs/releases/RELEASE_NOTES_v4.md`
|
||||
|
||||
For the current stable v6 packet, see:
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.2.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.2.md`
|
||||
|
||||
For the preceding stable v6 packet, see:
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.1.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.1.md`
|
||||
|
||||
For the preceding stable v6 packet, see:
|
||||
For the earlier stable v6 packet, see:
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.0.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.0.md`
|
||||
|
||||
|
||||
+6
-1
@@ -4,10 +4,15 @@ This guide covers practical upgrade steps for existing Pulse installs moving to
|
||||
|
||||
For the current stable v6 packet, see:
|
||||
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.2.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.2.md`
|
||||
|
||||
For the preceding stable v6 packet, see:
|
||||
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.1.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.1.md`
|
||||
|
||||
For the preceding stable v6 packet, see:
|
||||
For the earlier stable v6 packet, see:
|
||||
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.0.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.0.md`
|
||||
|
||||
@@ -2302,7 +2302,22 @@ version. It opened the `v6.4.0` candidate line from `main` with
|
||||
`rollback_version=v6.3.1` and did not move stable/latest install pointers or
|
||||
stable semver aliases.
|
||||
|
||||
The active stable `v6.4.1` cut sets the repo-root `VERSION`, repo-root
|
||||
The active stable `v6.4.2` cut sets the repo-root `VERSION`, repo-root
|
||||
`docker-compose.yml` image default, `scripts/install-docker.sh` fallback, and
|
||||
Helm chart release metadata to the same `6.4.2` release version. This patch
|
||||
release uses the stable hotfix path with `rollback_version=v6.4.1`,
|
||||
`hotfix_exception=true`, a release-owner reason, and no fabricated same-version
|
||||
RC tag. The governed branch is `main`. The active customer harm is two stable
|
||||
authorization failures: authenticated non-administrator organization members
|
||||
can reach infrastructure action control, and SSO-only deployments can treat
|
||||
every authenticated IdP user as an instance administrator without an explicit
|
||||
grant. The exact pushed `main` SHA must pass the integrated candidate checks
|
||||
before publication. No governed mobile-facing path changed from `v6.4.1`, so
|
||||
the release decision is `no-mobile-impact`. The standing
|
||||
SignPath-unavailable policy from `v6.3.2` onward still applies, with public
|
||||
Unknown Publisher disclosure and the existing signed integrity controls.
|
||||
|
||||
The preceding stable `v6.4.1` cut sets the repo-root `VERSION`, repo-root
|
||||
`docker-compose.yml` image default, `scripts/install-docker.sh` fallback, and
|
||||
Helm chart release metadata to the same `6.4.1` release version. This patch
|
||||
release uses the stable hotfix path with `rollback_version=v6.4.0`,
|
||||
@@ -2740,13 +2755,15 @@ For the active stable `v6.1.2` cut, the repo-root compose default and
|
||||
`scripts/install-docker.sh` fallback must both pin `6.1.2` whenever the
|
||||
governed `VERSION` is that stable cut. The stable promotion guard remains in
|
||||
force and rejects leftover `-rc.` defaults.
|
||||
For the active stable `v6.4.1` cut, the repo-root compose default and
|
||||
`scripts/install-docker.sh` fallback must both pin `6.4.1` until the next
|
||||
For the active stable `v6.4.2` cut, the repo-root compose default and
|
||||
`scripts/install-docker.sh` fallback must both pin `6.4.2` until the next
|
||||
governed release moves them forward. The stable promotion guard remains in
|
||||
force and rejects leftover `-rc.` defaults. Each new release moves
|
||||
these two pins together with the repo-root `VERSION` and the Helm chart metadata
|
||||
in the same commit; a cut that leaves any of the four on a superseded value is a
|
||||
release-packet blocker.
|
||||
For the preceding stable `v6.4.1` cut, the repo-root compose default and
|
||||
`scripts/install-docker.sh` fallback both pinned `6.4.1`.
|
||||
For the preceding stable `v6.4.0` cut, the repo-root compose default and
|
||||
`scripts/install-docker.sh` fallback both pinned `6.4.0`.
|
||||
For the preceding stable `v6.3.2` cut, the repo-root compose default and
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
# Pulse v6.4.2 Release Notes
|
||||
|
||||
`v6.4.2` is a stable patch release for the Pulse v6 line. It follows stable
|
||||
`v6.4.1` and restores explicit administrator boundaries for infrastructure
|
||||
actions and SSO-only deployments.
|
||||
|
||||
## What's improved
|
||||
|
||||
- **Infrastructure actions honor role boundaries** - Browser and proxy users must now be administrators or hold an explicit action permission before they can plan, approve, view, or execute infrastructure actions.
|
||||
- **SSO access no longer implies administrator access** - An authenticated SSO user now needs an effective RBAC `admin` grant for administrator routes. Unassigned, `operator`, and `viewer` users remain non-administrative even when no local administrator exists.
|
||||
- **SAML allowlists fail closed** - A configured domain or email allowlist now rejects a SAML assertion that omits the email claim instead of bypassing the allowlist.
|
||||
|
||||
## Before you upgrade
|
||||
|
||||
- Upgrade promptly when Pulse has organization members, proxy-authenticated users, or SSO users who should not administer the instance or control infrastructure.
|
||||
- On an SSO-only deployment, map at least one trusted IdP group to the built-in `admin` role before upgrading so an intended administrator retains access.
|
||||
- Existing configured local administrators, explicitly authorized RBAC roles, and action-scoped API tokens remain supported.
|
||||
- Pulse Mobile remains compatible. This patch does not require a companion mobile release.
|
||||
- Windows Unified Agent binaries are not Authenticode-signed while SignPath remains unavailable and may show an Unknown Publisher warning. Verify downloads with the published checksums and detached signatures.
|
||||
- The rollback target is stable `v6.4.1`. On systemd and Proxmox LXC installs, use `sudo /bin/update --version v6.4.1` to return to the previous stable release. For Docker Compose, pin `rcourtman/pulse:6.4.1` and recreate the container.
|
||||
@@ -0,0 +1,50 @@
|
||||
# Pulse v6.4.2
|
||||
|
||||
_This changelog describes stable `v6.4.2` compared with stable `v6.4.1`._
|
||||
|
||||
## Fixed
|
||||
|
||||
- The OSS default authorizer no longer treats ordinary authenticated
|
||||
organization membership as permission to use the infrastructure action
|
||||
control plane. Browser and proxy sessions must satisfy the canonical
|
||||
administrator boundary, while explicitly scoped API tokens and real RBAC
|
||||
action grants retain their governed paths.
|
||||
- Route and lifecycle guardrails cover planning, review, approval, execution,
|
||||
refresh, and recovery action surfaces so the permission check cannot be
|
||||
bypassed through a sibling action endpoint.
|
||||
- SSO authentication no longer becomes instance-administrator authority when
|
||||
no local administrator is configured. SSO browser sessions must carry an
|
||||
effective RBAC `admin` grant on `*` before they can use administrator-only
|
||||
settings, discovery, configuration transfer, platform, or infrastructure
|
||||
action routes.
|
||||
- SAML domain and email allowlists now reject assertions without an email
|
||||
claim when either allowlist is configured.
|
||||
|
||||
## Upgrade requirement
|
||||
|
||||
- An SSO-only installation must map at least one trusted IdP group to the
|
||||
built-in `admin` role before upgrading. Sessions mapped only to `operator`,
|
||||
`viewer`, or no role intentionally lose the administrator access that older
|
||||
versions granted implicitly.
|
||||
|
||||
## Release Metadata
|
||||
|
||||
- Version: `v6.4.2`
|
||||
- Previous stable: `v6.4.1`
|
||||
- Rollback target: `v6.4.1`
|
||||
- Rollback command: `sudo /bin/update --version v6.4.1`
|
||||
- Promotion path: emergency stable patch from `main`, using the single-build
|
||||
release workflow after exact-SHA qualification
|
||||
- Emergency reason: current stable releases contain two authorization
|
||||
boundary failures. A non-administrator organization member may reach the
|
||||
infrastructure action control plane, and every authenticated IdP user on an
|
||||
SSO-only instance may inherit instance-administrator authority without an
|
||||
explicit grant
|
||||
- Windows signing decision: the standing SignPath-unavailable policy publishes
|
||||
unsigned Windows Unified Agent binaries. They may display an Unknown
|
||||
Publisher warning while exact-SHA candidate binding, checksums, detached
|
||||
signatures, immutable-manifest verification, and published-digest
|
||||
verification remain mandatory
|
||||
- Mobile decision: `no-mobile-impact`. The patch changes no governed mobile
|
||||
route, payload, Relay, pairing, approval, push, or onboarding contract, so no
|
||||
companion mobile build or store rollout is required.
|
||||
@@ -4,10 +4,15 @@ This guide covers practical upgrade steps for existing Pulse installs moving to
|
||||
|
||||
For the current stable v6 packet, see:
|
||||
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.2.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.2.md`
|
||||
|
||||
For the preceding stable v6 packet, see:
|
||||
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.1.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.1.md`
|
||||
|
||||
For the preceding stable v6 packet, see:
|
||||
For the earlier stable v6 packet, see:
|
||||
|
||||
- `docs/releases/RELEASE_NOTES_v6.4.0.md`
|
||||
- `docs/releases/V6_CHANGELOG_v6.4.0.md`
|
||||
|
||||
@@ -6,7 +6,7 @@ set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
||||
DOCKER_IMAGE_REPO="${DOCKER_IMAGE_REPO:-rcourtman/pulse}"
|
||||
CANONICAL_DEFAULT_PULSE_VERSION="6.4.1"
|
||||
CANONICAL_DEFAULT_PULSE_VERSION="6.4.2"
|
||||
|
||||
resolve_default_pulse_version() {
|
||||
if [ -n "${PULSE_IMAGE_VERSION:-}" ]; then
|
||||
|
||||
@@ -2045,6 +2045,39 @@ func TestDeploymentDefaultsPinVersionedImagesAndHelmDocsChecksum(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestV642SecurityPacketCoversBothAdministratorBoundaryFixes(t *testing.T) {
|
||||
notesBytes, err := os.ReadFile(repoFile("docs", "releases", "RELEASE_NOTES_v6.4.2.md"))
|
||||
if err != nil {
|
||||
t.Fatalf("read v6.4.2 release notes: %v", err)
|
||||
}
|
||||
changelogBytes, err := os.ReadFile(repoFile("docs", "releases", "V6_CHANGELOG_v6.4.2.md"))
|
||||
if err != nil {
|
||||
t.Fatalf("read v6.4.2 changelog: %v", err)
|
||||
}
|
||||
notes := string(notesBytes)
|
||||
changelog := string(changelogBytes)
|
||||
for _, required := range []string{
|
||||
"Infrastructure actions honor role boundaries",
|
||||
"SSO access no longer implies administrator access",
|
||||
"map at least one trusted IdP group to the built-in `admin` role before upgrading",
|
||||
"The rollback target is stable `v6.4.1`",
|
||||
} {
|
||||
if !strings.Contains(notes, required) {
|
||||
t.Fatalf("v6.4.2 release notes missing %q", required)
|
||||
}
|
||||
}
|
||||
for _, required := range []string{
|
||||
"effective RBAC `admin` grant on `*`",
|
||||
"SSO-only installation must map at least one trusted IdP group",
|
||||
"Promotion path: emergency stable patch from `main`",
|
||||
"Mobile decision: `no-mobile-impact`",
|
||||
} {
|
||||
if !strings.Contains(changelog, required) {
|
||||
t.Fatalf("v6.4.2 changelog missing %q", required)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestHelmChartDoesNotPublishRetiredExplorePrepassMonitoring(t *testing.T) {
|
||||
chartDir := repoFile("deploy", "helm", "pulse")
|
||||
err := filepath.WalkDir(chartDir, func(path string, d os.DirEntry, walkErr error) error {
|
||||
|
||||
@@ -329,6 +329,13 @@ func TestInstallDockerProofTracksStablePatchReleaseContract(t *testing.T) {
|
||||
"Public Unknown Publisher disclosure",
|
||||
)
|
||||
}
|
||||
if version == "6.4.2" {
|
||||
assertFileContainsAllNormalized(t, repoFile("docs", "release-control", "v6", "internal", "subsystems", "deployment-installability.md"),
|
||||
"The governed branch is `main`",
|
||||
"authenticated non-administrator organization members can reach infrastructure action control",
|
||||
"SSO-only deployments can treat every authenticated IdP user as an instance administrator without an explicit grant",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInstallDockerProofTracksStableMinorContract(t *testing.T) {
|
||||
|
||||
@@ -29,6 +29,21 @@ def _discover_rc_draft_packet_paths() -> tuple[str, ...]:
|
||||
|
||||
|
||||
class RenderReleaseBodyTest(unittest.TestCase):
|
||||
def test_v642_security_packet_keeps_both_admin_boundaries_visible(self) -> None:
|
||||
notes = (
|
||||
_REPO_ROOT / "docs" / "releases" / "RELEASE_NOTES_v6.4.2.md"
|
||||
).read_text(encoding="utf-8")
|
||||
|
||||
for expected in (
|
||||
"Infrastructure actions honor role boundaries",
|
||||
"SSO access no longer implies administrator access",
|
||||
"map at least one trusted IdP group to the built-in `admin` role before upgrading",
|
||||
"The rollback target is stable `v6.4.1`",
|
||||
):
|
||||
self.assertIn(expected, notes)
|
||||
self.assertNotIn("## Fixes", notes)
|
||||
render_release_body.validate_release_notes_shape(notes, "6.4.2")
|
||||
|
||||
def test_v640_stable_packet_keeps_release_boundaries_visible(self) -> None:
|
||||
notes = (
|
||||
_REPO_ROOT / "docs" / "releases" / "RELEASE_NOTES_v6.4.0.md"
|
||||
|
||||
Reference in New Issue
Block a user