Skip to main content

AwsService

Trait AwsService 

Source
pub trait AwsService: Send + Sync {
    // Required methods
    fn service_name(&self) -> &str;
    fn handle<'life0, 'async_trait>(
        &'life0 self,
        request: AwsRequest,
    ) -> Pin<Box<dyn Future<Output = Result<AwsResponse, AwsServiceError>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn supported_actions(&self) -> &[&str];

    // Provided methods
    fn iam_enforceable(&self) -> bool { ... }
    fn iam_action_for(&self, _request: &AwsRequest) -> Option<IamAction> { ... }
    fn iam_actions_for(&self, request: &AwsRequest) -> Vec<IamAction> { ... }
    fn iam_resource_in_caller_account(&self, _request: &AwsRequest) -> bool { ... }
    fn iam_condition_keys_for(
        &self,
        _request: &AwsRequest,
        _action: &IamAction,
    ) -> BTreeMap<String, Vec<String>> { ... }
    fn resource_tags_for(
        &self,
        _resource_arn: &str,
    ) -> Option<HashMap<String, String>> { ... }
    fn request_tags_from(
        &self,
        _request: &AwsRequest,
        _action: &str,
    ) -> Option<HashMap<String, String>> { ... }
}
Expand description

Trait that every AWS service implements.

Required Methods§

Source

fn service_name(&self) -> &str

The AWS service identifier (e.g., “sqs”, “sns”, “sts”, “events”, “ssm”).

Source

fn handle<'life0, 'async_trait>( &'life0 self, request: AwsRequest, ) -> Pin<Box<dyn Future<Output = Result<AwsResponse, AwsServiceError>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Handle an incoming request.

Source

fn supported_actions(&self) -> &[&str]

List of actions this service supports (for introspection).

Provided Methods§

Source

fn iam_enforceable(&self) -> bool

Whether this service participates in opt-in IAM enforcement (FAKECLOUD_IAM=soft|strict).

Defaults to false: unless a service has a full iam_action_for implementation covering every operation it supports plus resource-ARN extractors, it’s silently skipped when IAM enforcement is on. The startup log enumerates which services are enforced and which are not so users always know the current enforcement surface.

Phase 1 contract: a service that returns true here MUST also provide a fully populated AwsService::iam_action_for implementation covering every action it advertises. Returning true without the action mapping is a programming bug.

Source

fn iam_action_for(&self, _request: &AwsRequest) -> Option<IamAction>

Derive the IAM action + resource ARN for an incoming request.

Only called when AwsService::iam_enforceable returns true and IAM enforcement is enabled. Services must map every action they implement; returning None for a covered action causes the evaluator to skip the request and flag it via the fakecloud::iam::audit tracing target so gaps are visible in soft mode.

The IamAction.resource is built from request.principal’s account id (not global config) so multi-account isolation (#381) works once per-account state partitioning lands.

Source

fn iam_actions_for(&self, request: &AwsRequest) -> Vec<IamAction>

Every IAM authorization an incoming request needs.

Most operations act on one resource and need one action, which is what the default returns (AwsService::iam_action_for). Some need several: a batch or transaction naming several resources needs the action on each, and an operation can require more than one action (DynamoDB’s CreateTable with Tags also needs TagResource). Dispatch evaluates every action returned and denies the request if any of them is denied. An empty list means the operation has no mapping, which strict enforcement denies.

Source

fn iam_resource_in_caller_account(&self, _request: &AwsRequest) -> bool

Whether the request creates its resource in the CALLER’s account, so that whatever currently holds the resource’s name elsewhere has no say in authorizing it. S3’s CreateBucket is the case: bucket names are global, and creating a name another account owns is authorized against the caller’s own policies (then answered BucketAlreadyExists), never against the other account’s bucket policy. Dispatch then evaluates the request as same-account with no resource policy. Default false.

Source

fn iam_condition_keys_for( &self, _request: &AwsRequest, _action: &IamAction, ) -> BTreeMap<String, Vec<String>>

Derive service-specific IAM condition keys for an incoming request.

Called right after AwsService::iam_action_for when IAM enforcement is enabled. The returned map is merged into the crate::auth::ConditionContext::service_keys before the evaluator runs, so policies can reference keys like s3:prefix or sns:Protocol the same way they reference global keys.

Keys MUST be in the full "service:key" form, lowercased (e.g. "s3:prefix"), matching the case-insensitive lookup in crate::auth::ConditionContext::lookup. Extractors should only emit keys they can populate with confidence; anything ambiguous or unimplemented should be skipped with a tracing::debug!(target: "fakecloud::iam::audit", ...) so condition evaluation safe-fails to “doesn’t apply” rather than “matches”.

Default impl returns an empty map: services that haven’t been plumbed yet behave exactly as before.

Source

fn resource_tags_for( &self, _resource_arn: &str, ) -> Option<HashMap<String, String>>

Return the tags on the resource identified by resource_arn.

Called at dispatch time when IAM enforcement is enabled, right after AwsService::iam_action_for. The returned map populates aws:ResourceTag/<key> condition keys so policies can gate access based on the target resource’s tags.

Return None to signal that this service does not (yet) support resource-tag ABAC — dispatch will emit a debug audit log and skip aws:ResourceTag/* evaluation. Return Some(empty map) when the resource exists but has no tags.

Source

fn request_tags_from( &self, _request: &AwsRequest, _action: &str, ) -> Option<HashMap<String, String>>

Extract tags being sent in the request (e.g. on CreateQueue, PutObject with x-amz-tagging, TagResource).

The returned map populates aws:RequestTag/<key> and aws:TagKeys condition keys. Return None when the service does not (yet) support request-tag extraction — dispatch skips aws:RequestTag/* / aws:TagKeys evaluation with a debug log. Return Some(empty map) when the request legitimately carries no tags.

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§