pub trait ResourcePolicyProvider: Send + Sync {
// Required method
fn resource_policy(
&self,
service: &str,
resource_arn: &str,
) -> Option<String>;
// Provided method
fn resource_owner_account(
&self,
_service: &str,
_resource_arn: &str,
) -> Option<String> { ... }
}Expand description
Abstraction over “given a service + a fully-qualified resource ARN, return the resource-based policy attached to that resource, if any.”
Implemented by resource-owning services (S3 for bucket policies in
the initial rollout; SNS topic policies, KMS key policies, and
Lambda resource policies are separate future wirings) and plumbed
through crate::dispatch::DispatchConfig alongside
IamPolicyEvaluator. Dispatch fetches the policy for the target
resource and hands it to the evaluator so cross-account Allow/Deny
semantics can be computed.
Implementations must be cheap to clone-share via Arc and must be
thread-safe — dispatch calls them on every enforced request.
Returning None means “no resource policy attached / resource
doesn’t exist / this provider doesn’t handle that service.” Returning
Some(json) yields the raw JSON document as stored by the
resource’s CRUD handlers; parsing happens inside the evaluator so a
malformed document logs a debug audit event and falls through to
“no resource policy” rather than silently allowing.
Required Methods§
Sourcefn resource_policy(&self, service: &str, resource_arn: &str) -> Option<String>
fn resource_policy(&self, service: &str, resource_arn: &str) -> Option<String>
Fetch the resource-based policy document attached to
resource_arn on service. Both arguments are lowercase-ish
("s3", "arn:aws:s3:::my-bucket"); implementations should
match the service prefix they own and return None for
anything else so providers can be composed safely.
Provided Methods§
Sourcefn resource_owner_account(
&self,
_service: &str,
_resource_arn: &str,
) -> Option<String>
fn resource_owner_account( &self, _service: &str, _resource_arn: &str, ) -> Option<String>
Resolve the 12-digit account that owns resource_arn on service,
when the ARN itself does not carry it. S3 ARNs have an empty account
field (arn:aws:s3:::bucket), so without this the dispatcher would
fall back to the caller’s account and treat every S3 request as
same-account — letting account A reach account B’s bucket without B’s
bucket policy granting it (bug-audit 2026-05-28, 5.3). Providers whose
ARNs already carry the account (SQS/SNS/Lambda/…) return None and let
the dispatcher parse it from the ARN. Default None.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".