pub struct ClientSideCredentialAccessBoundaryGranter { /* private fields */ }Expand description
Exchanges source credentials for intermediary material and generates Google Credential Access Boundary tokens locally.
The granter exchanges the source OAuth access token for an access-boundary
intermediary token and session key when the cached intermediary no longer
covers the requested lifetime, then creates every downscoped credential
locally. It does not spawn background work; the first caller that needs a
refresh performs the exchange. Refreshes for the same source authority,
expiration, and endpoint are serialized, while unrelated partitions can
proceed independently. After a failed refresh, the next waiting caller
retries instead of receiving cached failure state. Clones and values produced
with ClientSideCredentialAccessBoundaryGranter::with_grant share a bounded
intermediary cache partitioned by the source token authority, its declared
expiration, and the Google STS endpoint. Cancellation never installs a
partially fetched intermediary, and refresh-lock registry entries live only
while callers for that partition are active.
Each call performs fresh authenticated encryption and returns a distinct,
token-only Credential. The output expiration exactly matches the
intermediary expiration. The optional lifetime passed to
reqsign_core::Granter::grant is treated as the minimum remaining output
lifetime; it does not shorten the token. None uses the 30-minute default,
which can be changed with
ClientSideCredentialAccessBoundaryGranter::with_minimum_token_lifetime.
The source must be a token-only Google OAuth access token for a service
account, with a known absolute expiration and the Cloud Platform scope.
Client-issued CAB tokens do not support user principals. STS rejects tokens
that already carry security attributes; the opaque source token does not
expose enough information to detect its principal, scope, or existing
attributes locally. An intermediary response without expires_in, which STS
uses for user access-token sources, is rejected.
Google currently returns a serialized Tink AEAD keyset as the session key. This implementation accepts enabled primary AES-GCM keys and fails closed for other key types.
§Example
use std::time::Duration;
use reqsign_core::{Context, Granter, time::Timestamp};
use reqsign_google::{
ClientSideCredentialAccessBoundaryGranter, CredentialAccessBoundaryGrant,
CredentialAccessBoundaryPermissions, TokenCredentialProvider,
};
let source = TokenCredentialProvider::new("source-oauth-token")
.with_expires_at(Timestamp::now() + Duration::from_secs(3600));
let grant = CredentialAccessBoundaryGrant::for_object_prefix(
"example-bucket",
"customer-a/",
CredentialAccessBoundaryPermissions::OBJECT_VIEWER,
);
// Supply a Context configured with an HttpSend implementation.
let context = Context::new();
let credential = Granter::new(
context,
source,
ClientSideCredentialAccessBoundaryGranter::new(grant),
)
.grant(None)
.await?;Implementations§
Source§impl ClientSideCredentialAccessBoundaryGranter
impl ClientSideCredentialAccessBoundaryGranter
Sourcepub fn new(grant: CredentialAccessBoundaryGrant) -> Self
pub fn new(grant: CredentialAccessBoundaryGrant) -> Self
Create a granter for a bound Credential Access Boundary.
Sourcepub fn with_grant(self, grant: CredentialAccessBoundaryGrant) -> Self
pub fn with_grant(self, grant: CredentialAccessBoundaryGrant) -> Self
Replace the bound grant while retaining the shared intermediary cache.
Sourcepub fn with_minimum_token_lifetime(self, lifetime: Duration) -> Self
pub fn with_minimum_token_lifetime(self, lifetime: Duration) -> Self
Set the minimum remaining lifetime for outputs granted without an explicit per-call lifetime.
The value is rounded up to a whole second and must then be greater than zero and strictly less than twelve hours. The largest accepted value is 11 hours, 59 minutes, and 59 seconds. Validation occurs before STS I/O.
Trait Implementations§
Source§impl Clone for ClientSideCredentialAccessBoundaryGranter
impl Clone for ClientSideCredentialAccessBoundaryGranter
Source§fn clone(&self) -> ClientSideCredentialAccessBoundaryGranter
fn clone(&self) -> ClientSideCredentialAccessBoundaryGranter
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl GrantCredential for ClientSideCredentialAccessBoundaryGranter
impl GrantCredential for ClientSideCredentialAccessBoundaryGranter
Source§type Credential = Credential
type Credential = Credential
Source§fn required_valid_until(
&self,
_credential: &Self::Credential,
expires_in: Option<Duration>,
) -> Timestamp
fn required_valid_until( &self, _credential: &Self::Credential, expires_in: Option<Duration>, ) -> Timestamp
Source§async fn grant_credential(
&self,
ctx: &Context,
credential: &Self::Credential,
expires_in: Option<Duration>,
) -> Result<Self::Credential>
async fn grant_credential( &self, ctx: &Context, credential: &Self::Credential, expires_in: Option<Duration>, ) -> Result<Self::Credential>
Auto Trait Implementations§
impl !RefUnwindSafe for ClientSideCredentialAccessBoundaryGranter
impl !UnwindSafe for ClientSideCredentialAccessBoundaryGranter
impl Freeze for ClientSideCredentialAccessBoundaryGranter
impl Send for ClientSideCredentialAccessBoundaryGranter
impl Sync for ClientSideCredentialAccessBoundaryGranter
impl Unpin for ClientSideCredentialAccessBoundaryGranter
impl UnsafeUnpin for ClientSideCredentialAccessBoundaryGranter
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> GrantCredentialDyn for Twhere
T: GrantCredential + ?Sized,
impl<T> GrantCredentialDyn for Twhere
T: GrantCredential + ?Sized,
Source§type Credential = <T as GrantCredential>::Credential
type Credential = <T as GrantCredential>::Credential
Source§fn required_valid_until_dyn(
&self,
credential: &<T as GrantCredentialDyn>::Credential,
expires_in: Option<Duration>,
) -> Timestamp
fn required_valid_until_dyn( &self, credential: &<T as GrantCredentialDyn>::Credential, expires_in: Option<Duration>, ) -> Timestamp
GrantCredential::required_valid_until.Source§fn grant_credential_dyn<'a>(
&'a self,
ctx: &'a Context,
credential: &'a <T as GrantCredentialDyn>::Credential,
expires_in: Option<Duration>,
) -> Pin<Box<dyn Future<Output = Result<<T as GrantCredentialDyn>::Credential, Error>> + Send + 'a>>
fn grant_credential_dyn<'a>( &'a self, ctx: &'a Context, credential: &'a <T as GrantCredentialDyn>::Credential, expires_in: Option<Duration>, ) -> Pin<Box<dyn Future<Output = Result<<T as GrantCredentialDyn>::Credential, Error>> + Send + 'a>>
GrantCredential::grant_credential.