Releases: getaxonflow/axonflow-sdk-rust
Release v0.7.0
AxonFlow Rust SDK v0.7.0
Installation
[dependencies]
axonflow-sdk-rust = "0.7.0"Documentation
Adds the SDK analog of platform/shared/pep (ADR-056, epic
getaxonflow/axonflow-enterprise#2563, tracking #2571): a decide → fulfill →
forward Policy Enforcement Point. decide() surfaces engine-fulfillable
redact_pii obligations; fulfill_request() discharges them by round-tripping
content through the engine endpoint each obligation names — never by redacting
locally. The SDK carries no redaction logic of its own: there is no regex, no
pattern table, no masking branch. An obligation the engine cannot discharge
fails closed (AxonFlowError::ObligationNotFulfillable) rather than
forwarding unredacted content.
Added
AxonFlowClient::decide(DecideRequest) -> DecideResponse—POST /api/v1/decideusing the client's existing HTTP Basic (org:license) auth.
401 (bad / demo credentials) surfaces asAxonFlowError::ApiError { status: 401, .. }; adenyverdict is returned in the body (HTTP 200), not as an
error.AxonFlowClient::fulfill_request(&DecideResponse, &str) -> (String, bool)
— for each request-phaseredact_piiobligation, POSTs the statement to the
obligation's check-input endpoint and returns the engine-redacted content plus
whether the engine changed it. Fails closed (returns
AxonFlowError::ObligationNotFulfillable, never the original statement) when:
no request-phase fulfillment;content_typesis non-empty and omits
text/plain; the endpoint is not the request-redaction path (foreign URLs
rejected); the engine call fails / returns non-200; orredaction_evaluated
is false/absent.AxonFlowClient::decide_and_fulfill(DecideRequest) -> (verdict, content, DecideResponse)— one-call PEP path. On a non-allow verdict returns the
original query (caller blocks anyway); on allow returns engine-redacted
content. On an unfulfillable obligation it surfaces the fail-closed error so a
caller cannot accidentally forward the unredacted query.has_request_redaction(&[Obligation]) -> boolfree function — branch on
whether a verdict carries request-phase redaction work.- PEP types in
axonflow_sdk_rust::types::pep, re-exported from the crate
root:DecideRequest,DecideResponse,Obligation,
ObligationFulfillment,DecisionCallerIdentity,DecisionTarget,
MCPCheckInputRequest,MCPCheckInputResponse,MCPCheckOutputRequest,
MCPCheckOutputResponse. Wire field names are byte-identical with the Go /
Python / TypeScript / Java SDKs. content_typefield onMCPCheckInputRequest;redacted/
redacted_statement/redaction_evaluatedonMCPCheckInputResponse;
redaction_evaluatedonMCPCheckOutputResponse. All#[serde(default)]
so older platforms deserialize cleanly (the fail-closed default for
redaction_evaluatedisfalse).AxonFlowError::ObligationNotFulfillable(String)— the fail-closed signal
of the PEP contract. Non-retryable and not fail-open-eligible.- PEP contract constants (
OBLIGATION_REDACT_PII,PHASE_REQUEST/
PHASE_RESPONSE,CONTENT_TYPE_TEXT,VERDICT_ALLOW/VERDICT_DENY/
VERDICT_NEEDS_APPROVAL,DECIDE_PATH,REQUEST_REDACTION_PATH/
RESPONSE_REDACTION_PATH,GATEWAY_CONNECTOR_TAG). - 22 unit tests in
src/pep.rs::testscovering decide parse (allow +
obligation / deny-in-body / 401), every fail-closed branch (missing
request-phase fulfillment, response-phase obligation, unadvertised
content-type, foreign endpoint, engine error,redaction_evaluatedfalse,
redaction_evaluatedabsent), passthrough (no obligation, engine found
nothing, non-redact obligation type),endpoint_path_matchesexact/absolute/
foreign,has_request_redaction, anddecide_and_fulfill
allow/deny/unfulfillable. runtime-e2e/decide_fulfill_obligation/— bash runner + Rust helper crate
exercising the real SDK against a live enterprise agent (NO mocks): proves
decide → allow + obligation; fulfill → engine-masked content where neither
john.doe@example.comnor4111111111111111survives;decide_and_fulfill
parity; demo creds refused with 401. Mirrors the Python SDK's runner.
Compatibility
Additive. No existing public API is changed; no removed fields; no changed
defaults. The new request/response fields are an acknowledged SDK superset of
the wire contract — older platforms ignore the extra request field and the
SDK's #[serde(default)] keeps response parsing fail-closed when the platform
predates the redaction fields. Minor version bump 0.6.0 → 0.7.0 (SDK semver is
decoupled from the platform version).
Requires an AxonFlow platform exposing POST /api/v1/decide with Decision Mode
for the decide / decide_and_fulfill path; fulfill_request requires the
request-redaction redact_pii capability on /api/v1/mcp/check-input.
Cross-SDK parity: getaxonflow/axonflow-enterprise#2571.
Release v0.6.0
AxonFlow Rust SDK v0.6.0
Installation
[dependencies]
axonflow-sdk-rust = "0.6.0"Documentation
Targets AxonFlow platform v8.5.0.
Added
contextfield onDecisionSummaryandDecisionExplanation—
Option<HashMap<String, String>>with#[serde(default, skip_serializing_if = "Option::is_none")]. Surfaces the sanitized request context a PEP attaches to a
Decision Mode call (canonicallower_snake_casekeys such asx_ai_agent,
x_session_id,x_leader_identity, andx-bukuwarung-*), persisted by the
platform at the audit row'spolicy_details->'context'.list_decisions
returns the platform-truncated summary (5 keys);explain_decisionreturns the
full map.Nonefor pre-v0.6.0 audit rows.context_truncatedfield onDecisionExplanation—bool. True when the
agent dropped surplus context keys at write time.transfer_basismodule constants (transfer_basis::ADEQUACY,
transfer_basis::SAFEGUARDS,transfer_basis::PASAL_56B_DPA="pasal_56b_dpa",
transfer_basis::CONSENT), re-exported at the crate root. Name the Indonesia
UU PDP Pasal 56 legal bases.
Changed
AuditLogEntry::transfer_basisdocumentation now recordspasal_56b_dpa
(Pasal 56(b) explicit DPA tag) alongsideadequacy,safeguards, and
consent. The field stays anOption<String>(surfaced verbatim), so existing
code matching on"safeguards"is unaffected and the SDK never rejects a value
a newer platform may add.
Release v0.5.0
AxonFlow Rust SDK v0.5.0
Installation
[dependencies]
axonflow-sdk-rust = "0.5.0"Documentation
Added
PolicyCategoryenum with all policy categories includingPiiIndonesia
("pii-indonesia"). First policies module in the Rust SDK, establishing
cross-SDK parity for policy category constants.AuditLogEntrystruct with full audit log fields including
data_residencyandtransfer_basisfor cross-border data transfer
logging. Both areOption<String>for backward compatibility.
Release v0.4.0
AxonFlow Rust SDK v0.4.0
Installation
[dependencies]
axonflow-sdk-rust = "0.4.0"Documentation
Cross-SDK parity bring-up for HITL (Human-in-the-Loop) approval
workflows. Prior to this release the Rust SDK exposed no HITL
methods at all — the four stable SDKs (Python / TS / Go / Java) all
ship the read + review surface (list_hitl_queue, get_hitl_request,
approve_hitl_request, reject_hitl_request, get_hitl_stats),
plus the new create_hitl_request method introduced in v8.2.0 of
each. This release ports the full surface in one shot so Rust callers
can implement the full 4-step HITL flow against AxonFlow:
- Gate evaluates
require_approval(viapre_check/check_tool_input) - Caller invokes
client.create_hitl_request(...)to enqueue the row - Caller polls
client.get_hitl_request(approval_id)until terminal state - Caller resumes the agent or denies the call based on the decision
Added
AxonFlowClient::list_hitl_queue(opts: HITLQueueListOptions) -> HITLQueueListResponse
with pagination + status/severity filters.AxonFlowClient::get_hitl_request(request_id: &str) -> HITLApprovalRequest.AxonFlowClient::create_hitl_request(input: HITLCreateInput) -> HITLApprovalRequest.
Required fields:client_id,original_query,request_type.
Optional fields cover policy attribution, severity, compliance
framework, an expiry override, and the newnotify_urlcallback.
Server-sideX-Org-ID/X-Tenant-IDheaders are derived by the
platform's auth middleware from the SDK client's configured
credentials — callers do not pass them through this method.AxonFlowClient::approve_hitl_request(request_id: &str, review: HITLReviewInput) -> ()
and the symmetricreject_hitl_request.AxonFlowClient::get_hitl_stats() -> HITLStats.HITLApprovalRequest/HITLCreateInput/HITLReviewInput/
HITLQueueListOptions/HITLQueueListResponse/HITLStatsin
axonflow_sdk_rust::types::hitl, re-exported from the crate root.notify_urlfield onHITLCreateInputandHITLApprovalRequest.
Opt-in webhook URL fired after the request reaches a terminal state
(approved / rejected / expired / overridden). Pairs with the
HMAC-SHA256X-AxonFlow-Signatureheader on the receiver side.
Scheme allowlist (https://, plushttp://for self-hosted
local-dev) is enforced server-side; bad schemes surface as
AxonFlowError::ApiError { status: 400, .. }. Companion platform
work in getaxonflow/axonflow-enterprise#2419.- 18 contract tests in
src/hitl.rs::testscovering: list happy path +
filter serialization, get happy path + empty-id guard + 404
propagation, create happy path + minimal required-fields +
bad-notify_url-scheme 400 propagation + 401 propagation +
connect-failure propagation + the three required-field validation
guards, approve + reject path/body shape + empty-id guard, and
stats envelope parsing, plus a unit test for the
build_list_queryfield-omission contract.
Compatibility
This is the first Rust SDK release to expose HITL methods, so there
is no behavior to preserve. The new types and methods are additive;
no existing public API is changed. Minor version bump 0.3.1 → 0.4.0
for the new module-level addition.
Requires AxonFlow platform >= 8.1.0 for notify_url webhook delivery
and Idempotency-Key request deduplication.
Cross-SDK parity sweep: getaxonflow/axonflow-enterprise#2421.
Release v0.3.1
AxonFlow Rust SDK v0.3.1
Installation
[dependencies]
axonflow-sdk-rust = "0.3.1"Documentation
Patch release. No SDK behavior changes for the X-Client-ID + retry
path; one additive wire field (org_id) on the telemetry heartbeat.
Added
runtime-e2e/x-client-id/runner — bash entry point plus a Rust
helper crate. Mirrors the Go / Python / TypeScript / Java SDKs'
runtime-e2e/x-client-id/directories. Brings up the public community
docker-compose stack, then runs an in-process forwarding-proxy helper
that captures the SDK's outbound HTTP headers off the wire and asserts:
X-Client-ID == AXONFLOW_TENANT_ID,X-Axonflow-Clientstarts with
sdk-rust/,Authorizationstarts withBasic, andX-Tenant-ID
is absent. This is the wire-level companion to the unit test
(tests/x_client_id_header_test.rs), which useswiremockand is
necessary but not sufficient — it can't catch contract drift between
the SDK and the live community-stack agent in the same PR that causes
it.org_idfield in the telemetry heartbeat body. Brings the Rust
SDK telemetry up to parity with the other four SDKs and the platform —
every heartbeat now identifies which deployment-organization emitted
it. Two sources in precedence order:
- The
ORG_IDenv var when set (the operator's explicit configuration
on self-hosted deployments, or thecs_<uuid>tenant identifier on
Community SaaS). - Otherwise the
local-dev-orgsentinel.
Exposed as axonflow_sdk_rust::heartbeat::telemetry_org_id() and
axonflow_sdk_rust::heartbeat::ORG_ID_LOCAL_DEV_SENTINEL. Always
emitted; older receivers ignore the field cleanly for backward compat.
Honors AXONFLOW_TELEMETRY=off like every other heartbeat field. See
getaxonflow.com/privacy/ for the
customer-facing commitment that covers this field.
- Regression tests around the retry-allowlist contract. Two new
integration tests bracket the retry boundary so a future refactor
can't silently change either side: HTTP 401 is terminal (no retries
on bad/expired credentials, preventing the storm pattern customers
had observed against the audit endpoint); HTTP 429 keeps triggering
retries up tomax_attemptsso rate-limit handling remains intact.
Changed
- Telemetry-enabled log line softened from "Anonymous telemetry
enabled" to "Telemetry enabled" to stay coherent with theorg_id
addition — the operator-suppliedORG_IDon self-hosted is not
anonymized; only theinstance_idandcs_<uuid>Community SaaS
identifier remain anonymous-by-design.
Documentation
- Rustdoc on the retry executor documents which status codes retry
(5xx + 429) and which are terminal (401 and everything else 4xx
outside the allowlist), so customers who wrap the SDK in their own
retry middleware know which classes to exclude. - Clarifying comment above the retry-allowlist explains that 402 /
403 are handled as success responses in the request executor and
never propagate to the retry path as errors, so the*status != 402
/*status != 403clauses in the allowlist are intentional defense
against any future refactor that converts 402/403 back to errors.
Release v0.2.0
AxonFlow Rust SDK v0.2.0
Installation
[dependencies]
axonflow-sdk-rust = "0.2.0"Documentation
Preview release. The headline feature is the new decision-history client API
(list_decisions) plus the explain_decision example, both bringing Rust to
parity with the four stable SDKs. The other half is a telemetry rework that
brings Rust onto AxonFlow's central anonymous-heartbeat pipeline so adoption is
measurable consistently across all five SDKs.
Added
list_decisions(opts)client method paging through recorded decision history from the orchestrator. MirrorsGET /api/v1/decisions. Companion toexplain_decision— list and drill in. Seeexamples/list_decisions/.AxonFlowConfig::sandbox(client_id, client_secret)convenience constructor for local testing. Defaults tohttp://localhost:8080, setsmode = Mode::Sandbox, enables debug logging. Parity with Go'sSandbox(), Python's.sandbox(), TypeScript'sAxonFlow.sandbox(), Java'sAxonFlow.sandbox(url).WrappedAnthropicClientinvisible-governance interceptor for Anthropic models. Wrap any client implementingAnthropicMessageCreatorand AxonFlow pre-checks policy on everycreate_messagecall, blocks denied calls, and asynchronously audits successful responses. Mirrors the existingWrappedOpenAIClientpattern; supports the Anthropic Messages-API request shape (requiredmax_tokens, optionalsystem). Newexamples/anthropic_interceptor/shows the end-to-end flow.
Decision explainability
client.explain_decision(decision_id)carried forward — fetches the structuredDecisionExplanationfor a previously-made policy decision (matched policies, risk level, override availability, historical hit count, tool signature). Newexamples/explain_decision/shows the end-to-end pattern.
Fixed
- URL-encoding parity with the other SDKs. Path parameters (
connector_id,plan_id,decision_id) were percent-encoded withNON_ALPHANUMERIC, which over-escapes the RFC-3986 unreserved characters_,-,.,~. Connector IDs likeamadeus-travelwere going on the wire asamadeus%2Dtravel— wrong wire form that stricter routers would 404. Replaced with a path-segment encode set matching Go'surl.PathEscapesemantics.
Telemetry
- Heartbeat endpoint moves to central checkpoint (
https://checkpoint.getaxonflow.com/v1/ping). Pre-v0.2 the Rust SDK pinged the local agent — useful for proxy debugging but invisible to the central pipeline. Now in parity with the other four SDKs. AXONFLOW_TELEMETRY=offis the sole opt-out (no programmatic disable;DO_NOT_TRACKintentionally NOT honored). Heartbeat payload expanded to the cross-SDK v1 shape (telemetry_type,deployment_mode,endpoint_type,instance_id,stream); sandbox clients tagstream="sandbox". 7-day per-machine cadence + stamp-on-delivery unchanged.
Maintenance
- Test-suite mocking library swapped from
httpmocktowiremock. Test-onlydev-dependencieschange with no public API or wire-contract impact; downstream consumers usingaxonflow-sdk-rustas a runtime dependency are unaffected. The previous library's transitive dependency onasync-stdis unmaintained.
Release v0.1.0
AxonFlow Rust SDK v0.1.0
Installation
[dependencies]
axonflow-sdk-rust = "0.1.0"Documentation
Initial release of the AxonFlow Rust SDK. The foundation was contributed voluntarily by @fpierfed — see CONTRIBUTORS.md.
Added
Core client (AxonFlowClient):
proxy_llm_call— send governed queries through the AxonFlow agent.audit_llm_call— gateway-mode logging for direct LLM calls.- HTTP Basic auth with a
community:default tenant when no credentials are configured. With credentials:Authorization: Basic base64(client_id:client_secret). X-License-Keyheader support for enterprise mode (AxonFlowConfig::with_license_key); marked sensitive and redacted inDebug.- Production fail-open + Sandbox propagate-error modes.
- Cache (moka, configurable TTL, mutation-aware), retry with exponential backoff.
MCP connectors:
list_connectors,get_connector,get_connector_health,query_connector.install_connector→POST /api/v1/connectors/{id}/install.
Multi-Agent Planning (MAP):
generate_plan,execute_plan.get_plan_status→GET /api/v1/plan/{id}.cancel_plan→POST /api/v1/plan/{id}/cancel.
LLM interceptor:
WrappedOpenAIClientfor invisible-governance over any OpenAI-compatible client. Pre-checks policy via AxonFlow, blocks on policy violations, and audits asynchronously after the response.
Resilience + ergonomics:
AxonFlowConfigbuilder (with_auth,with_license_key,with_mode,with_timeout,with_map_timeout,with_retry,with_cache).- Custom
Debugredactsclient_secretandlicense_key. - URL-encodes user-supplied path parameters (connector_id, plan_id).
- Tokio-runtime guard on the heartbeat — safe to construct without an active runtime.
AXONFLOW_INSECURE_TLS=1env to skip TLS verification (debug only).AXONFLOW_TRY=1short-circuit for the hosted try endpoint.
Telemetry:
- 7-day machine-global anonymous heartbeat for licensing compliance.
- Honors
AXONFLOW_TELEMETRY=offas the documented opt-out.DO_NOT_TRACKis intentionally NOT honored — it is commonly inherited from a parent shell.
Examples (runnable):
cargo run --example basic— proxy mode with PII redaction demo.cargo run --example connectors— list / install / query MCP connectors.cargo run --example planning— generate + execute a multi-agent plan.cargo run --example interceptors— invisible governance viaWrappedOpenAIClient.
Tests:
- 17 integration tests via
httpmockcovering proxy / blocked / fail-open / cache / mutation-bypass / retry / list-connectors / generate-plan / install-connector / get-plan-status / cancel-plan, plus the auth-header contract (community default, OAuth2 with creds, clientID-only-no-secret) andX-License-Keypresence/absence.
Documentation + ergonomics:
- README,
docs/ARCHITECTURE.md,docs/ERROR_HANDLING.md. Cargo.tomlis crates.io-ready: explicitrust-version = "1.78"MSRV, repository / homepage / documentation / readme metadata, MIT license.
CI / governance:
test.yml(fmt, clippy-D warnings, build, test, build all examples),audit.yml(cargo auditweekly + on Cargo.lock change),integration.yml(runs all examples against a fresh community docker-compose stack on every PR + weekly cron),release.yml(preflights CHANGELOG + Cargo.toml version match, creates GH release on tag, and publishes to crates.io)..github/dependabot.yml(cargo + github-actions, weekly),pull_request_template.md,CODEOWNERS.- DCO sign-off required on every commit (see
CONTRIBUTING.md).
Notes
This is a preview release. The Rust SDK currently covers a subset of the surface available in the established Go / Python / TypeScript / Java SDKs (which are at v7.6.x and ship the full governance / workflow / cost / compliance surface). Subsequent releases will expand parity in well-scoped phases — track upcoming work in the Issues.