gcs-s3-compat-acl-rejection

Par divinevideo · divine-mobile

Corrige les erreurs S3 "InvalidArgument" lors de l'utilisation de l'API compatible S3 de Google Cloud Storage avec `ObjectCannedAcl::PublicRead` ou les en-têtes `x-amz-acl`. À utiliser quand : (1) `put_object` ou `upload_blob` échoue avec `InvalidArgument` sur GCS, (2) utilisation du crate Rust `aws-sdk-s3` avec l'endpoint GCS (`storage.googleapis.com`), (3) le bucket a l'accès uniforme au niveau du bucket activé (comportement par défaut de GCS depuis 2023), (4) les opérations S3 fonctionnent sur MinIO/AWS mais échouent sur GCS. GCS rejette les ACL par objet lorsque l'accès uniforme au niveau du bucket est activé.

npx skills add https://github.com/divinevideo/divine-mobile --skill gcs-s3-compat-acl-rejection

Rejet ACL de l'API S3-Compatible de GCS

Problème

Les appels S3 put_object échouent avec InvalidArgument lors du ciblage de Google Cloud Storage via son API S3-compatible, bien qu'ils fonctionnent correctement avec MinIO ou AWS S3.

Contexte / Conditions de déclenchement

  • Utilisation de aws-sdk-s3 (Rust) ou tout SDK S3 avec endpoint GCS
  • AWS_ENDPOINT=https://storage.googleapis.com
  • Erreur : Error { code: "InvalidArgument", message: "Invalid argument." }
  • La trace de pile affiche S3BlobStore::put_temp ou une opération put S3 similaire
  • Le bucket GCS a l'accès uniforme au niveau du bucket activé (par défaut GCS)

Solution

Supprimez ObjectCannedAcl::PublicRead des appels put_object lors de l'utilisation de GCS :

// AVANT (échoue sur GCS avec accès uniforme au niveau du bucket)
self.client
    .put_object()
    .body(body)
    .bucket(&self.s3_bucket)
    .key(key)
    .acl(ObjectCannedAcl::PublicRead)  // Ceci provoque InvalidArgument
    .send()
    .await?;

// APRÈS (fonctionne avec GCS)
self.client
    .put_object()
    .body(body)
    .bucket(&self.s3_bucket)
    .key(key)
    // Supprimez .acl() — utilisez plutôt la politique IAM au niveau du bucket
    .send()
    .await?;

Pour l'accès en lecture publique, configurez plutôt la politique IAM du bucket :

gsutil iam ch allUsers:objectViewer gs://YOUR_BUCKET

Ou désactivez l'accès uniforme au niveau du bucket (non recommandé) :

gsutil ubla set off gs://YOUR_BUCKET

Vérification

Après suppression de l'appel .acl(), l'upload devrait réussir :

curl -X POST "$PDS_URL/xrpc/com.atproto.repo.uploadBlob" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: video/mp4" \
  --data-binary @test.mp4

Notes

  • L'accès uniforme au niveau du bucket de GCS est le par défaut depuis 2023
  • L'appel copy_object dans move_object() utilise aussi .acl(PublicRead) et échouera
  • Cela affecte le stockage blob rsky-pds : rsky-pds/src/actor_store/aws/s3.rs lignes 69, 97, 212
  • MinIO n'applique pas cette restriction, donc le dev local fonctionne mais la GCS de production échoue
  • Le même problème s'applique aux méthodes put_permanent() et move_object()

Skills similaires