rs_ali_sts/lib.rs
1//! Alibaba Cloud STS (Security Token Service) SDK for Rust.
2//!
3//! This crate provides both async and sync (blocking) clients for the
4//! Alibaba Cloud STS API, supporting all 4 API operations:
5//!
6//! - [`Client::assume_role`] — Assume a RAM role to get temporary credentials
7//! - [`Client::assume_role_with_saml`] — SAML-based SSO role assumption
8//! - [`Client::assume_role_with_oidc`] — OIDC-based SSO role assumption
9//! - [`Client::get_caller_identity`] — Query current caller identity
10//!
11//! # Features
12//!
13//! - **Async and Blocking clients** — Use `Client` for async or `blocking::Client` for sync
14//! - **Builder pattern** — Ergonomic request construction with `try_build()` for fallible builds
15//! - **Credential chain** — Automatic resolution from environment variables or profile files
16//! - **Clock skew correction** — Automatic adjustment for local clock drift
17//! - **Concurrent request limiting** — Built-in semaphore for async client
18//! - **Security first** — Credentials redacted in debug output
19//!
20//! # Quick Start
21//!
22//! ```no_run
23//! use rs_ali_sts::{Client, Credential, AssumeRoleRequest};
24//!
25//! # async fn example() -> rs_ali_sts::Result<()> {
26//! // Create client with explicit credential
27//! let client = Client::new(Credential::new("access-key-id", "access-key-secret"))?;
28//!
29//! // Or use the credential chain (env vars -> profile file)
30//! // let client = Client::from_env()?;
31//!
32//! // Build request using builder pattern
33//! let request = AssumeRoleRequest::builder()
34//! .role_arn("acs:ram::123456:role/example")
35//! .role_session_name("my-session")
36//! .duration_seconds(3600)
37//! .build();
38//!
39//! // Execute request
40//! let resp = client.assume_role(request).await?;
41//!
42//! println!("Temporary AK: {}", resp.credentials.access_key_id);
43//! println!("Expires: {}", resp.credentials.expiration);
44//! # Ok(())
45//! # }
46//! ```
47//!
48//! # Blocking Client
49//!
50//! Enable the `blocking` feature for synchronous usage:
51//!
52//! ```toml
53//! [dependencies]
54//! rs-ali-sts = { version = "0.1", features = ["blocking"] }
55//! ```
56//!
57//! ```ignore
58//! use rs_ali_sts::blocking::Client;
59//! use rs_ali_sts::{Credential, AssumeRoleRequest};
60//!
61//! fn main() -> rs_ali_sts::Result<()> {
62//! let client = Client::new(Credential::new("id", "secret"))?;
63//!
64//! let request = AssumeRoleRequest::builder()
65//! .role_arn("acs:ram::123456:role/example")
66//! .role_session_name("session")
67//! .build();
68//!
69//! let resp = client.assume_role(request)?;
70//! println!("AK: {}", resp.credentials.access_key_id);
71//! Ok(())
72//! }
73//! ```
74//!
75//! # Error Handling
76//!
77//! All operations return [`Result<T>`] which wraps [`StsError`]:
78//!
79//! ```no_run
80//! # use rs_ali_sts::{Client, Credential, AssumeRoleRequest, StsError};
81//! # async fn example(client: Client) {
82//! let request = AssumeRoleRequest::builder()
83//! .role_arn("acs:ram::123456:role/example")
84//! .role_session_name("session")
85//! .build();
86//!
87//! match client.assume_role(request).await {
88//! Ok(resp) => println!("Success: {}", resp.credentials.access_key_id),
89//! Err(StsError::Api { request_id, code, message, .. }) => {
90//! eprintln!("API error [{}]: {} (RequestId: {})", code, message, request_id);
91//! }
92//! Err(StsError::Validation(msg)) => eprintln!("Invalid request: {}", msg),
93//! Err(e) => eprintln!("Error: {}", e),
94//! }
95//! # }
96//! ```
97//!
98//! # Security
99//!
100//! - **Credential redaction**: `access_key_secret` and `security_token` are shown as `****` in debug output
101//! - **HTTPS POST**: Credentials never appear in URLs
102//! - **HMAC-SHA1**: Signature algorithm compatible with Alibaba Cloud STS
103//! - **UUID v4 nonce**: Prevents replay attacks
104//!
105//! # Feature Flags
106//!
107//! | Feature | Description |
108//! |---------|-------------|
109//! | `blocking` | Enables synchronous (`blocking::Client`) |
110//!
111pub mod client;
112pub mod config;
113pub mod credential;
114pub mod error;
115pub mod response;
116
117#[cfg(feature = "blocking")]
118pub mod blocking;
119
120mod exec;
121mod request;
122mod sign;
123
124pub use client::{
125 AssumeRoleRequest, AssumeRoleRequestBuilder, AssumeRoleWithOidcRequest,
126 AssumeRoleWithOidcRequestBuilder, AssumeRoleWithSamlRequest, AssumeRoleWithSamlRequestBuilder,
127 Client,
128};
129pub use config::ClientConfig;
130pub use credential::Credential;
131pub use error::{Result, StsError};
132pub use response::{
133 AssumeRoleResponse, AssumeRoleWithOidcResponse, AssumeRoleWithSamlResponse, AssumedRoleUser,
134 Credentials, GetCallerIdentityResponse, OidcTokenInfo, SamlAssertionInfo,
135};
136pub use sign::SignatureVersion;
137
138// Compile-time assertions: key types must be Send + Sync for use across threads.
139const _: () = {
140 const fn assert_send_sync<T: Send + Sync>() {}
141 let _ = assert_send_sync::<Client>;
142 let _ = assert_send_sync::<StsError>;
143 let _ = assert_send_sync::<Credential>;
144};