Releases: cirrus-code/cirrus
v0.4.0
v0.3.0
cirrus-auth-v0.2.4
Security
WebServerFlow'sDebugimplementation now redactsconsumer_keyandconsumer_secret. Previously the derived impl printed both verbatim, so any code logging the flow with{:?}(e.g.tracing::debug!(?flow)) wrote the connected app's client secret to its logs. If your application may have logged aWebServerFlowvalue, consider rotating that connected app's consumer secret.
All other secret-bearing types (PendingExchange, CompletedSession, the builders) already redacted correctly; this closes the one gap.
v0.3.0 (cirrus)
Breaking
BulkIngestJob::api_versionandBulkQueryJob::api_versionare nowf64(previouslyf32). The wire shape is unchanged — Salesforce sends a JSON number — so this only affects code that names the field's type.
Fixed
- After a 401-triggered token refresh, the retried request now gets a fresh transient-retry budget. Previously, retries spent on 429/503 responses before the 401 carried over, so the post-refresh request could run with no retries at all — exactly when the server had just proven flaky.
- Path segments you supply (sObject name and record ID in
create_with_blob/update_with_blob, deploy IDs in the Metadata REST handler) are now percent-encoded instead of interpolated raw.
Changed
- Connect-phase network failures (DNS errors, connection refused, TLS handshake failures) are now retried for all HTTP methods, including POST and PATCH. The request never reached the server in these cases, so a retry cannot duplicate an effect. Mid-request failures still retry only on idempotent methods. This matches
cirrus-metadata's existing policy. - A 2xx response with an empty body deserialized into a non-nullable type now produces a clear error suggesting
()orOption<T>, instead of serde's opaque "invalid type: null".
cirrus-metadata-v0.1.1
Fixed
list_metadatanow rejects an empty query list client-side withMetadataError::InvalidArgument, instead of sending a zero-query envelope that surfaces as an opaque server-side SOAP fault.wait_for_deploy/wait_for_deploy_with: if the deploy completes but the finalinclude_details: truefetch fails, the helpers now return the terminal result (withdetails: None) and log a warning, instead of discarding a finished deploy's outcome behind an error.
Documentation
MetadataClient::callandrequest_buildernow carry a security note: the session token travels inside the SOAP envelope (the request body), so redacting theAuthorizationheader is not sufficient — body-logging middleware or proxies will capture the token in plaintext.
v0.2.2
cirrus-auth 0.2.3
Security and reliability fixes for the OAuth flow layer. No public API changes;
upgrade is recommended for all users.
Security
-
Stop leaking OAuth
error_descriptionthroughAuthError. The
OAuthErrorResponsetype already redactederror_descriptionin itsDebug
impl (the field has historically echoed partial token material in some
Salesforce error paths), but the value was reconstituted in cleartext the
moment it became anAuthError::OAuth— both the derivedDebugand the
Displayimpl printed it verbatim, andAuthErroris the type that actually
escapes the crate and reaches logs.AuthErrornow has a hand-writtenDebug
that redactserror_description, and itsDisplaysurfaces only the
machine-readableerrorcode. The description remains available
programmatically by matching on theAuthError::OAuth { error_description, .. }
field. -
Stop echoing raw token-endpoint error bodies. When a non-2xx response from
/services/oauth2/tokendid not parse as the standard OAuth error shape, the
entire response body was folded intoAuthError::Otherand printed by
Display/Debug. Non-standard bodies (proxy HTML, reflected request
parameters) can carry token material. The error now reports only the HTTP
status; the body is logged solely atTRACE(off by default, an explicit
per-target opt-in for debugging).
Reliability
-
Proactive token refresh margin. Cached access tokens are now treated as
expired once they fall within a 60-second margin of their real expiry, across
the JWT bearer, refresh-token, and client-credentials flows. Previously a token
expiring milliseconds after the validity check would be handed to an in-flight
request and 401 at Salesforce, relying on the client's 401 auto-refresh to
recover. This removes a class of avoidable round-trips at every TTL boundary. -
Honor server-advertised token lifetime. Token responses that include
expires_in(RFC 6749 §5.1) now drive the cache lifetime, taking precedence
over the configured static TTL. The field is modeled as optional with a
default, so its absence (Salesforce omits it on most flows) leaves existing
behavior unchanged.
Behavior change to note
AuthError'sDisplayoutput for theOAuthvariant changed from
OAuth error: {error} — {error_description}toOAuth error: {error}. Code
that pattern-matches on theAuthError::OAuthvariant is unaffected; only code
that scraped the formatted string for the description needs to read the field
directly instead.
cirrus 0.2.2
Bug fixes and an internal refactor. No public API changes.
Fixes
- Percent-encode path segments in the Tooling sObject and Event Monitoring
handlers.ToolingSObjectHandler(describe,retrieve,
retrieve_with_fields,create,update,delete) and
EventMonitoringHandler::downloadbuilt their request paths by string
interpolation and routed through the unencoded path resolver, diverging from
the regularSObjectHandler, which percent-encodes each segment via
versioned_segments. They now use the same encoded-segment path, so a reserved
character in a record ID or object name can no longer alter the request path.
Low real-world exposure given Salesforce's ID/name character set, but it makes
the path-safety contract uniform across all sObject-style handlers.
cirrus-metadata
No changes in this release.
v0.2.1
Adds the cirrus-metadata crate, a client for interacting with Salesforce metadata via the SOAP API. Salesforce's Metadata API is SOAP-only for anything besides deployments, and the cirrus-metadata crate implements a means of interacting with it.
This also adds the deploy-only REST API to the main cirrus crate.
Full Changelog: v0.2.0...v0.2.1
v0.2.0
Refactors out the cirrus-auth crate into a separate crate. This has no end-user impact, as cirrus::auth is still re-exported in the same manner.
v0.1.0
The initial release of cirrus!