Skip to content

SILO 20261112: Security Hardening, Service-Account Policy Inheritance and Multi-Pool Repairs

SILO Server 20261112 release notes: SN-2026-020 through SN-2026-025 security fixes, strict policy JSON decoding, Object Lock null-version and replica hardening, compressed encrypted Range reads, Console 2.7.2, mcli 20261112, and silo-pkg 3.16.1.

SILO Server 20261112 is now released. Tag: RELEASE.2026-11-12T00-00-00Z; package version: 20261112000000.0.0; source: 44e848fedf8c. It delivers the SN-2026-020 through SN-2026-025 security repairs, strict policy JSON decoding, Object Lock null-version and replica hardening, and multi-pool storage fixes after Server 20261109, built with Go 1.27.4 alongside embedded Console 2.7.2, mcli 20261112, and silo-pkg 3.16.1.

GitHub Release · Full Changelog · Security Advisories · Upgrade Guide · Downloads

Components

Component Released version Fixed source
SILO Server RELEASE.2026-11-12T00-00-00Z, package 20261112000000.0.0 44e848fedf8cec3d8c0da4b1aa8422390a2b7a8b
Embedded / standalone Console v2.7.2 0e7953ff59c4a1eb77c7d203b265e6783ff18d01
MC module / image-bundled mcli 20261112 a37a9f054fba828a0bbbceb4e9ff247ccf09c28d
Shared package silo-pkg v3.16.1 433f7eefa714a30b72ca70c4dffcd5faca25804f
Optional external KES 20261026 e9b4f1acebc11d61b42f876da8df48f548750cc9
Go / upstream S3 SDK Go 1.27.4 / pinned upstream minio-go/v7 v7.4.2-0.20261025165926-320af050c445

The component matrix records exact module versions. Updating standalone Console, mcli, or silo-pkg does not replace components inside an older Server binary. KES remains a separate, optional external key service with its own release cycle. The maintained PGSTY stack is the supported target; upstream MinIO/MC compatibility remains best effort.

S3, replication and Object Lock security

  • Single-pool DeleteObjects containment (SN-2026-020): stops single-pool DeleteObjects entries that fail object-name validation (.. segments) before drive dispatch, returning XMinioInvalidObjectName instead of traversing into sibling buckets or .minio.sys or bypassing COMPLIANCE Object Lock (a18293d0c).
  • Active-active tagging and read proxies (SN-2026-022, #337): authenticates DeleteObjectTagging before replication proxying, evaluates stored remote replica tags across GetObjectTagging, PutObjectTagging, DeleteObjectTagging, and proxied GET/HEAD (14ecb222e, 67a90dfef, 293ab78b4, c39605d4f), fails closed on unreadable targets while skipping missing replicas caused by replication lag, and strips both x-amz-tagging-count / X-Amz-Tagging and canonical-case X-Amz-Object-Lock-* headers across local and proxied GET/HEAD responses unless the corresponding tagging or retention/legal-hold read permission is granted without explicit Deny (ea37a7e8b).
  • SigV4 and streaming-trailer authentication (SN-2026-023, #338): enforces the 15-minute clock-skew window and checkUnsignedHeaders coverage on authenticated STREAMING-UNSIGNED-PAYLOAD-TRAILER uploads while keeping bucket-policy-authorized anonymous uploads intact (14ecb222e, 296c9710b), and rejects SigV4 credential-scope date mismatches, negative X-Amz-Decoded-Content-Length headers, and truncated or oversized (> 64 KiB) streaming trailers.
  • Stored-tag and version authorization (SN-2026-024, #293, #342): evaluates s3:ExistingObjectTag/<key> on GetObjectAttributes, CopyObject, UploadPartCopy, SelectObjectContent, and side-effect-free in-memory ZIP member reads/listings (s3:ListBucket + s3:GetObject), preserves 5xx storage read-quorum errors on tag-conditioned GET/HEAD, evaluates CopyObject COPY-directive destination tag conditions against the tags actually copied, and enforces explicit version-action denies on version-addressed reads and tagging calls while retaining legacy base-action grants when no explicit version deny applies.
  • Replica and null-version Object Lock (#336): reconciles destination lock/tag state under the mutation lock, verifies staged replica content hashes, SSE-C status, and compressed ActualSize before committing, prevents peer timestamps from weakening unexpired COMPLIANCE retention, requires header-based SigV4 signing on X-Minio-Replication-* headers, fails closed when x-minio-force-delete cannot read bucket lock metadata (cf486df66), and protects locked null versions in versioning-suspended or prefix-excluded buckets against overwrites, delete markers, and shadowed unversioned DELETE calls across single-pool and multi-pool deployments.

IAM, service accounts and strict policy validation

  • Service-account inline policy tri-state (SN-2026-021, SN-2026-025, #331, #339, #345): UpdateServiceAccount preserves existing inline session policies when newPolicy is omitted or null (including historical pre-20261111 empty embedded-policy deny-all accounts), removes the inline restriction and restores parent inheritance only when an explicit empty policy document ({} or {"Statement":[]}) is sent, and fills default Version: "2012-10-17" on nonempty versionless inline policies. IAM imports preserve disabled service-account and group states and report group failures accurately (1d714834c).
  • Strict policy JSON decoding: IAM named policies, service-account session policies, STS Policy parameters, IAM imports/replication, and bucket policies reject unknown JSON fields, trailing tokens, non-object inputs, empty Principal: {}, and unsupported NotPrincipal blocks via silo-pkg v3.16.1 (34ba7cc1f), validating whole policy archives before applying entries while keeping stored on-disk IAM policy reads and explicit null bucket-policy replication tombstones compatible.
  • Site-replication concurrency and credential hygiene: IAM healing, bucket/metadata healing, status collection, and replication hooks snapshot site topology and release the cluster state lock before storage I/O and peer RPCs (design note), and exported/replicated credentials strip derived policy claims.

Storage pools, compressed encrypted ranges, lifecycle and batch

  • Multi-pool copy and moving-pool authority (#343): historical-version self-copy (PUT ?versionId=... to the same key) creates a readable new version across multi-pool clusters for plaintext, SSE-S3, SSE-KMS, SSE-C, and multi-block S2 compressed objects (Parts[0].Index preserved), and in-place replica metadata updates preserve authoritative content on draining/rebalancing pools (design note).
  • Compressed + encrypted Range reads: indexed byte-range reads on objects using both compression and server-side encryption (SSE-S3, SSE-KMS, SSE-C) advance DARE decryption frames accurately when the target compressed block starts inside the first 64 KiB encrypted frame (decryptSkip > 0), without rewriting existing objects, while still failing closed on corrupted DARE authentication tags (939cb2600).
  • Lifecycle/restore revision quorum and metadata cache (#332, #344): normalizes pre-2024-04-28 partially healed xl.meta headers (design note) and clears the time-dependent xlFlagUsesDataDir bit from revisionKey comparisons so partial heals and expired restored copies do not split cross-drive quorum; guards BucketMetadataSys.GetConfig against stale cache overwrites.
  • Pool decommission (#334): stops stalled passes that make zero physical progress, returns cancellation errors promptly, rescans child keys previously hidden beneath an exact object key, and tolerates offline drives within the erasure set’s read quorum when verifying source cleanup.
  • SSE-KMS encryption context and batch keyrotate: S3 write endpoints (PutObject, CopyObject, CreateMultipartUpload, browser POST) reject empty, malformed Base64/UTF-8/JSON, trailing-token, or non-string/non-null X-Amz-Server-Side-Encryption-Context headers with 400 InvalidArgument instead of 500 InternalError. Batch keyrotate preserves configured KMS context across execution, retry, and manifest reload (design note), stream-rewrites legacy XLV1 objects onto XLV2 with sealed plaintext MD5 ETags and preserved tags/expiry, and keeps internal multipart/tier headers during SSE-S3 -> SSE-KMS rotation.

Console, client and dependencies

Embedded and standalone Console 2.7.2 carries forward 2.7.1’s tri-state service-account policy editor, in-modal error reporting, strict policy JSON validation, and --host 0.0.0.0 / CONSOLE_SECURE_TLS_HOST HTTP-to-HTTPS redirect host preservation (unrolled/secure v1.18.0), with synchronized 2.7.2 release metadata and optimized web assets. mcli 20261112 aligns explicit empty-policy ({}) resets across access-key edit commands (#78) and enforces client-side strict policy JSON validation. silo-pkg 3.16.1 provides ParseConfigStrict / ParseBucketPolicyConfig hardening and base dependency updates on Go 1.27.4, while retaining go-systemd v22.6.0 for NetBSD cross-compilation (72a6047bf). Release gates now verify the coordinated silo-pkg, embedded Console v2.7.2, mcli tag/commit, DCO sign-off on main, and Helm chart 7.0.5 appVersion/image.tag alignment (c83dbe0ea).

Upgrade and rollback

  1. Verify .minio.sys quorum and retain 20261109 rollout prerequisites. Confirm healthy read quorum across erasure sets before restarting. When upgrading directly from 20261026 or earlier, also follow the 20261109 upgrade checklist (drain or cancel unfinished batch jobs; stop all nodes simultaneously on single-pool layouts whose erasure sets do not share identical hosts, such as 18+ auto-layout hosts; pause POST ?restore during mixed-version windows).
  2. Drain or pause concurrent S3 writes during mixed-version multi-pool rolling restarts. Old and new nodes can otherwise interleave multi-pool write lock ordering or skip suspended/excluded null-version Object Lock checks on un-upgraded peers until every node runs 20261112.
  3. Freeze service-account edits on un-upgraded 20261109 sites during multi-site rollout. On 20261109 and earlier, status toggles or metadata edits without --policy still strip inline session policies and replicate that weakened state. After every site runs 20261112, audit accounts where mcli admin user svcacct info reports Policy: implied against reviewed intended policies rather than running a blind site-replication resync.
  4. Audit policy automation for strict JSON compliance before rollout. Automated tooling that submits misspelled IAM or bucket policy keys (for example Conditions instead of Condition), trailing JSON, empty Principal: {}, NotPrincipal, or non-string KMS encryption-context values now receives 400 instead of silent field dropping or 500.
  5. Verify per-node S3 data paths and set Helm image.tag explicitly. Run bounded signed S3 write/read checks against every restarted node, and pass --set image.tag=RELEASE.2026-11-12T00-00-00Z when running helm upgrade --reuse-values with chart 7.0.5.

Costs and limits

Every explicit version removal (VersionId specified) in S3 DeleteObjects now executes sequentially through the single-object path across all buckets — including buckets without Object Lock — as do unaddressed deletes that could replace a locked null version, so large explicit version-purge batches take longer than unversioned bulk deletes. Ordinary delete-marker creation and unversioned deletes that do not touch locked null versions retain concurrent bulk execution.

Storage timeouts still do not prove that a disk write did not commit, and this release does not add distributed fencing or recover previously deleted data or stripped policies. Known open limitations remain in ListMultipartUploads prefix/pagination (#79), multi-site delete-marker purges (#217), replayed bucket creation under site replication (PR #241), and upstream SDK multipart-completion retry headers (mcli put --if-not-exists; see multipart completion retries).

Delivery and verification

Release commit 44e848fedf8c passed Go CI, VulnCheck, DCO, Test Release Pipeline, the tagged release build, package finalization, and multi-arch Docker publication, along with eight-node two-pool runtime verification across compressed encrypted range reads, replication proxy header authorization, service-account tri-state policy updates, and upgrade checks.

The GitHub release publishes 36 Server assets (Linux/macOS tar.gz and Windows ZIP archives, GPG-signed x86_64 and aarch64 RPMs, DEB and APK packages, SHA-256 checksums, SPDX SBOMs, Sigstore bundles, and provenance attestations), alongside 44 Console 2.7.2 assets, 19 mcli 20261112 assets, 19 KES 20261026 assets, and the source-only silo-pkg 3.16.1 module. Multi-architecture container images (linux/amd64 and linux/arm64) are published on Docker Hub:

  • docker.io/pgsty/silo:RELEASE.2026-11-12T00-00-00Z (latest): sha256:c20d112390b9a9ce8c11b8af95ad35bcaa62f4759663c09c936cd8d2b511f329
  • docker.io/pgsty/silo:RELEASE.2026-11-12T00-00-00Z-distroless (distroless): sha256:a72e17773bdeb151999f9bf9d3bd842fb03850a577b730ab8c63343bb1f468fd

Thanks to @botdeniska for the tag-conditioned read-error and pool-decommission nested-key fixes (#294, #335) and the bulk-delete Object Lock report behind SN-2026-020, and @seumasdunlop for the Helm chart default image tag report (#296). Component and community credits are recorded in the contributor record.

Source Changelog · Changes Since 20261109