1. Docs
  2. SaaS Shield
  3. Suite
  4. Amazon S3
  5. Changelog

Changelog

See our buildlog for relationships between specific docker hashes and version tags. The most recent releases are at the bottom of the file. There will only ever be multiple hashes for a single version tag if the underlying image was rebuilt to fix a security vulnerability.

v3.0.0

Breaking Changes

To fix the key loss described below, the proxy now sends a versionId on the reads and tag writes it makes on a client’s behalf. S3 counts a request carrying a versionId as a different action from one without, so every user in the proxy’s credentials map needs s3:GetObjectVersion, s3:GetObjectVersionTagging and s3:PutObjectVersionTagging on every bucket behind the proxy, alongside the unversioned actions you already grant. Granting the unversioned form doesn’t allow the versioned one.

Grant all three no matter what state versioning is in. Required Permissions lists every action the proxy needs.

REJECT_UNKNOWN_TENANT_ID now defaults to true. A write whose tenant ID the Tenant Security Proxy doesn’t recognize, or whose tenant has no active KMS configuration, is refused with InvalidRequest. Before this it was stored unencrypted and answered 200, with only a warning in the proxy’s log to say so. Set it to false for the old behavior. This doesn’t change a request that resolves no tenant ID at all, from a missing tenant header or a folder mapping that matches nothing, which is still stored unencrypted; the setting has never covered that case.

Other Changes

  • Added an option to report an object’s KMS config ID as an ICL-M@kms-config-id tag, for tools that show you an object’s tags but give you no way to read the x-icl-kms-config-id response header. KMS_CONFIG_ID_TAG takes disabled, response or stored, and defaults to disabled. response adds the tag to GetObjectTagging responses without storing it; stored also writes it to S3, so it reaches the S3 Metadata inventory tables. ICL-M@ is a new reserved tag prefix, and the proxy strips client tags that use it just as it does for ICL@. See KMS Config ID Tag.
  • Fixed CopyObject writing a destination object that nothing could decrypt. This could happen if the request had an x-amz-tagging header.
  • Fixed the proxy passing a tagging request that carries SSE-C headers straight through to S3. S3 replaced or cleared the object’s tag set, the ICL@ EDEK tags went with it, and the object’s key was gone for good.
  • Fixed a PutObjectTagging body with no TagSet element.
  • Fixed defects for GetObject, HeadObject, CopyObject, UploadPartCopy, PutObjectTagging or DeleteObjectTagging with a versionId.
  • Fixed CopyObject and UploadPartCopy of an encrypted source failing for AWS SDK v1 client.
  • The proxy now rejects a versionId with no value after it which allowed a degenerate case to pass through.
  • On a versioned bucket, the proxy now sends a tag write that arrived with no versionId using the versionId its tag read returned. Before this, a new version created while the write was in flight ended up holding the older version’s EDEK, which could result in EDEK corruption.
  • We recommend turning on versioning for any bucket behind the proxy. Versioning lets the proxy address a tag write at the exact version it just read, so an object’s EDEK stays with the object it belongs to. On a bucket that was never versioned, or one where versioning is suspended, S3 has no immutable version to include with the request. A write to the same key (a PutObject, a CopyObject, or a multipart upload completing) that lands between the tag read and the tag write of a client’s PutObjectTagging or DeleteObjectTagging leaves the new object holding the old one’s EDEK, and its data can no longer be decrypted. S3 gives us no way to prevent that or to detect it afterwards. Nothing else is at risk: every other write carries its EDEK on the request that creates the object. See Unversioned and Versioning-Suspended Buckets.
  • The proxy now logs a warning when a tenant’s EDEK needs more than four tags, which leaves clients fewer than the usual six of S3’s ten tag slots.

v2.0.2

  • The proxy now passes Snowflake’s S3 compatibility test suite, apart from two assertions that identical objects yields identical ETags. This is not possible when encrypting.
  • Fixed SigV4 canonicalization of the query string.
  • Fixed SigV4 canonicalization of a header sent as several field lines, which must be joined with commas in wire order.
  • Host must now be signed.
  • Requests are now bounded to ±15 minutes of the proxy’s clock.
  • The region in the credential scope is no longer required to match the proxy’s deployed region, and InvalidRequestRegion is gone. The region is still authenticated, since it feeds signing key derivation, and the deployed region is still what selects the upstream endpoint and signs outbound requests.
  • Authentication error responses now match what S3 returns.
  • Fixed bucket names not being URI-encoded into the upstream request. A name holding a character a URI cannot carry produced a plain-text Invalid URI response that no S3 client can parse.
  • Authentication failures now close the connection. The proxy replies before reading the request body, so leftover bytes were parsed as the client’s next request.
  • Fixed a spurious Request body publisher already consumed error.

v2.0.1

  • Moved all classes into the com.ironcorelabs.s3 namespace, from forwarder. Logs are structured JSON and include a logger_name field, so any log queries, dashboards, or alerts that match on the old forwarder.* prefix must be updated or they will silently stop matching. The container’s entry point class changed to com.ironcorelabs.s3.Main for anyone overriding it.
  • Fixed virtual-host style addressing when the request’s Host header differs from the configured PROXY_DNS_NAME in letter case, by a trailing dot, or by the presence or absence of a port. Such a request was previously treated as path style without warning, which made the proxy read the object key as the bucket name. See URL Addressing Styles.
  • A PROXY_DNS_NAME that is not a valid host name is now rejected at startup instead of being accepted and silently routing every request as path style.
  • The proxy now logs at startup whether virtual-host style addressing is enabled, and for which suffix.
  • Upgraded the runtime from Java 21 to Java 25.

This release rolls up the changes intended for 2.0.0, which was never published.

v1.13.1

  • Fix issue with multipart copy returning 400.

v1.13.0

  • Added Prometheus metrics, exposed on a new /metrics endpoint. Includes server-side request counters and latencies (s3proxy_server_*), client-side counters classified as s3, tsp, or healthz (s3proxy_client_*), and folder-mapping refresh counters plus a last-success timestamp gauge (s3proxy_folder_mapping_*). See Metrics for the full list. Note that this endpoint is not authenticated so depending on your deployment configuration you might need to exclude it from being reachable externally.

v1.12.1

  • Fixed an issue where PUT tagging requests failed due to the request body being consumed twice.
  • Added an explicit x-amz-content-sha256 check on PUT ?tagging.

v1.12.0

  • Updated http4s-netty, which natively releases connections when the response body isn’t fully consumed. This removes the need for the rotating HTTP client workaround introduced in 1.11.2.
  • Removed the rotating HTTP client and related connection-cleanup workarounds. Connection lifecycle is now handled entirely by the underlying client.

v1.11.4

  • Signed requests no longer buffer the full request body in memory before forwarding. Large uploads now stream through the proxy, reducing memory usage and improving throughput for signed payloads.

v1.11.3

  • Changed TSP errors to return 4xx responses instead of 5xx.
  • When reject-unknown-tenant-id is enabled and a request has no matching tenant, the proxy now returns a proper XML error response with code InvalidRequest instead of a generic internal error.
  • Dependency updates.

v1.11.2

  • Added a rotating HTTP client that periodically allocates a fresh HTTP client and force-releases leaked connections from the old one after a grace period. Works around an http4s-netty resource leak where onFinalize isn’t called if the caller doesn’t consume the response body. This resource leak was introduced in 1.10.0.
  • Small responses (512KB or less) and bodyless responses (HEAD, 204, 304) are now fully buffered in memory so the underlying connection is released immediately rather than waiting for the caller to drain the stream.
  • Per-request timeouts with S3-style errors: S3 client calls and TSP calls now enforce clientRequestTimeout and return a RequestTimeoutError XML response instead of a generic 500.
  • Default timeout reduced from 2 minutes to 1 minute.
  • Fixed issue that could cause x-icl-kms-config-id to be incorrect.
  • Dependency updates.

v1.11.1

  • Updated HTTP client configuration to always use HTTP 1.x to talk to S3. This is to avoid a potential leak in connection reuse.
  • Fixed an issue where client request resources might not get cleaned up if the response wasn’t fully consumed.

v1.11.0

  • Added x-icl-kms-config-id to all responses where a key was used. In the case of something like COPY where 2 keys are used, the encrypting KMS config ID is used.
  • Updated dependencies.
  • Updated default logging to use an async stdout appender.

v1.10.3

  • Fix issue where HEAD requests would return an invalid Transfer-Encoding on the response. This issue was introduced in 1.10.0.

v1.10.2

  • Fix issue where hardened machines didn’t allow usage of /tmp. This issue was introduced in 1.10.0.

v1.10.1

  • Fix issue where proxy’s healthz endpoint would always error regardless of the health of the proxy. This issue was introduced in 1.10.0.

v1.10.0

  • Fix issue where proxy could hang with the Expect: 100-continue header.
  • Dramatically improve performance. As much as 10x in some cases.
  • Add new configuration option server.max-connections. By default, this will be read from the environment variable SERVER_MAX_CONNECTIONS. This defaults to 1024.
  • Add new configuration option server.client-request-timeout. By default, this will be read from the environment variable SERVER_CLIENT_REQUEST_TIMEOUT. This defaults to 2 minutes.

v1.9.0

  • Update to support STREAMING-UNSIGNED-PAYLOAD-TRAILER, STREAMING-AWS4-HMAC-SHA256-PAYLOAD and STREAMING-AWS4-HMAC-SHA256-PAYLOAD-TRAILER for authentication.

v1.8.1

  • Fix issue with concurrent multipart uploads to the same bucket/key.
  • Fix issue preventing multipart uploads with checksums from completing.

v1.8.0

  • Change PutObjectTagging to allow CRC32 checksums on requests. Other checksum algorithms are unsupported at this time and will cause the request to fail.

v1.7.0

  • Add support for customer-provided SSE-C keys. Whenever SSE-C headers are provided on a request, the S3 Proxy will detect them and pass through the request.

v1.6.0

  • Add new configuration option read-only-aws-creds. By default, this will be read from the environment variables READ_ONLY_S3_ACCESS_KEY_ID and READ_ONLY_S3_SECRET_ACCESS_KEY.
    • If present, this AWS Access Key ID/Secret Key will be used for fetching the folder mapping. If these credentials are not present, the S3 proxy will continue to use one of the credentials from the regular AWS credentials map.
  • Add new error response when attempting to transfer a payload in multiple chunks (not supported by the S3 proxy).
  • Change container to output structured JSON logging.

v1.5.2

  • Added a retry if we get a 403 due to the EDEK being out of sync with the object.

v1.5.1

  • Fixed an issue where some clients caused a signature calculation error. This was due to a defect in the server and will not require changes to the client configuration.

v1.5.0

  • Add support for CORS_ALLOWED_ORIGIN environment variable. See Advanced Install for details.

v1.4.0

v1.3.1

  • Dependency updates

v1.3.0

  • Images are no longer based on alpine and are instead built from scratch.

v1.2.5

  • added multi arch builds. amd64 and arm64 docker containers are both published to gcr.

v1.2.0

  • Added support for capture groups in the folder mapping with the capture-tenant-regex key.
    • In the folder mapping, the object-regex key has been renamed to explicit-tenant-regex. To maintain compatibility, we will still support the object-regex key until the next major release.

v1.1.1

  • Fixed bug that prevented configuring new features added in v1.1.0 in a deployment.

v1.1.0

  • Added ability to specify encryption tenant ID in request headers.
  • Added configuration option to deny encryption requests with invalid tenant ID.

v1.0.0

Initial release


Versioning Policy

See our container versioning policy documentation.

Was this page helpful?

One sec... bot checking