Provider Storage – Backend Differences
The Storage API defines the same buckets, credentials, access requests,
grants, and lifecycle rules for every backend. Each Composition maps that API
to its provider's bucket and access resources. The table below compares the
available implementations.
Where Access Rules Live
| Backend | Bucket | Identity and credential | Access rule |
|---|---|---|---|
| MinIO | Bucket |
User with generated credentials |
Named Policy resources; the User lists their names. |
| AWS | S3 Bucket |
IAM User and AccessKey |
IAM Policy resources linked to the user by UserPolicyAttachment. |
| OTC | OBS Bucket |
IAM UserV3 and CredentialV3 |
One OBS BucketPolicy per bucket, with user IDs in Principal. |
| OVHcloud | Regional S3 ProjectStorage |
Project User and S3Credentials |
One consolidated S3Policy document per user, linked by its observed numeric user ID. |
| CloudFerro | Project-scoped OpenStack ContainerV1 |
One shared Keystone controller user with one EC2CredentialV3 per Storage generation |
The project owns access. An AWS S3 BucketPolicy uses the CloudFerro endpoint to share with another project's root ARN. |
MinIO
- Bucket: The Composition creates a MinIO
Bucketfor each claimed bucket. - Identity and credential: It creates a
Userfor each retained credential generation. - Access rule: It creates named
Policyresources for owned buckets and grants. EachUserlists the policy names that apply to that generation.
AWS
- Bucket: The Composition creates an S3
Bucketfor each claimed bucket. - Identity and credential: It creates an IAM
UserandAccessKeyfor each retained credential generation. - Access rule: It creates IAM
Policyresources for owned buckets and grants. AUserPolicyAttachmentlinks each applicable policy to a user. The Composition does not create S3 bucket policies.
OTC
- Bucket: The Composition creates an OBS
Bucket. Consumers use its S3-compatible endpoint. - Identity and credential: It creates an IAM
UserV3andCredentialV3for each retained credential generation. - Access rule: It creates one OBS
BucketPolicyfor each bucket named in the claim's buckets or grants. The policy contains the observed IDs of allowed users inPrincipal. The Composition must observe those IDs before it can build the policy.
OVHcloud
- Bucket: The Composition creates a regional S3-compatible
ProjectStoragebucket. - Owner: It creates a separate, stable project
UserwithoutS3Credentialsor anS3Policy. This user owns the buckets and keeps their owner ID unchanged when consumer credentials rotate or a credential user is replaced. - Identity and credential: It creates a project
UserandS3Credentialsfor each retained credential generation. - Access rule: It creates a separate
S3Policyfor each credential user. The policy allows or denies access to owned and requested buckets based on the owner's grants. See the OVHcloud access guide.
CloudFerro
- Bucket: A slot-specific OpenStack ProviderConfig scopes each
ContainerV1to one project. The slot name is selected withspec.crossplane.compositionSelector.matchLabels.provider, such ascloudferro-0001. - Identity and credential: One controller user receives the configured member role in every managed project. The Composition creates retained EC2 credential generations for that user in the selected project.
- Access rule: Users in one project can access its containers. For an
active grant, the Composition resolves the grantee Storage's project slot
and creates an AWS S3
BucketPolicyagainst the CloudFerro endpoint. The policy grants the grantee project'srootARN. It cannot isolate users in the owner project. Usage resources keep the EC2 credential, AWS provider configuration, and AWS provider credential Secret until each bucket policy is deleted. See the bucket-sharing guide.
MinIO and OVHcloud both place consumer access on the user. MinIO users list multiple named policies. OVHcloud has one policy document per user, so the Composition combines all bucket rules into that document. AWS also uses user policies, but needs explicit attachment resources. OTC places the consumer grant rules on each bucket.
From Request to Access
The requester records a target bucket in bucketAccessRequests. The bucket
owner records its decision in bucketAccessGrants. These are fields on
Storage claims; no backend creates a separate cloud request resource. The
owner's grant selects ReadOnly, WriteOnly, ReadWrite, or None. The
permission guide shows the claim fields and an example.
| Backend | Request pending, with no owner grant | Owner grants access | Owner sets None or removes the grant |
|---|---|---|---|
| MinIO | The request adds no policy name to the requester's User. |
The owner creates a named grant Policy; the requester lists that policy on each retained User. |
The requester stops listing the policy. With None, the owner's named policy has no allow statements. |
| AWS | The request creates no UserPolicyAttachment for the target bucket. |
The owner creates an IAM grant Policy; the requester attaches it to each retained IAM User. |
The requester has no attachment. With None, the owner's grant policy has no allow statements. |
| OTC | The request field does not change the generated policy. | The owner's grant adds allow statements for the observed grantee ID to the bucket's BucketPolicy, even if the grantee did not record a request. |
The bucket policy has no allow statements for that grantee. None does not add an explicit deny. |
| OVHcloud | Each retained requester's S3Policy gets an explicit deny for the requested bucket. |
The policy replaces that deny with allow statements for the granted actions. | While the request remains, the policy contains an explicit deny for that bucket. |
| CloudFerro | The request has no cloud-side effect. | The owner adds allow statements for the grantee project's root ARN to the bucket policy. |
None or grant removal adds no cross-project allow. If no active grants remain, the bucket policy is removed. This does not restrict a user who is already in the owner's project. |
For the owner-label requirement and the distinction between bucket visibility and access, see Discoverable Buckets.
OTC builds policies from the bucket owner's grants and observed grantee user
IDs. It resolves each grantee principal through the matching discoverable peer
Storage, then observes the provider-native user for that peer's current
credential generation.
Removing a request also differs by backend. MinIO removes the grant policy name from the requester's users, and AWS removes the grant attachments. OTC does not use the request field, so removing it has no policy effect. OVHcloud removes the bucket-specific rule from the requester's user policy. OVHcloud then falls back to ACLs when no policy rule matches; removing a request alone does not prove that S3 access is denied. See the OVHcloud policy evaluation rules.
These descriptions are the resources the Compositions request. Cloud-side enforcement and revocation are asynchronous and need positive and negative S3 tests.
Verification Status
The common OVHcloud integration verification passes in DE. The primary
principal completes an S3 write, list, read, and delete round trip in its four
buckets. The secondary principal completes the same round trip in its own
bucket. It has no access to the ungranted, denied, and pending buckets. It can
read the bucket with a ReadOnly grant, but it cannot write to or delete from
that bucket. Credential rotation, lifecycle rules, and full teardown still
need separate live tests.
All bucket resources use the default Crossplane management policy. Removing a
bucket from spec.buckets, or removing its Storage claim, requests bucket
deletion. Deletion behavior is provider-specific. A provider can reject the
request when it cannot empty the bucket or when its cloud identity lacks the
required delete permission.