Skip to main content
This page explains how bucket access policies work in CoreWeave AI Object Storage, how to apply one to a bucket, and how to structure the JSON document so you can write your own. Use this page when you need precise, S3-specific access control for an individual bucket, such as sharing a bucket with users from another organization or restricting access to a single prefix. Bucket access policies are JSON objects that define allowed or denied actions on a single bucket and its contents. Only the bucket owner can attach or update this policy. CoreWeave AI Object Storage enforces access in two layers:
  • Organization access policies apply to all principals and resources in your organization. You configure them in the Cloud Console or through the AI Object Storage API (for example, with curl). CoreWeave evaluates these policies first.
  • Bucket access policies apply only to one bucket and its objects. Use them to allow users from other organizations to access your bucket. CoreWeave evaluates these policies after organization access policies.
See the complete policy evaluation order for details about how CoreWeave evaluates policies.

Set a bucket access policy

To set a bucket access policy, use the S3-compatible API with standard S3 tools like aws s3api or s3cmd, or use the CoreWeave Terraform provider. The policy is a JSON object that defines the access rules for the bucket and its objects. For example, the following command applies a JSON policy file to a bucket. Replace [BUCKET-NAME] with the name of your bucket and [POLICY-FILE] with the path to the JSON file that contains the policy.
aws s3api put-bucket-policy --bucket [BUCKET-NAME] --policy file://[POLICY-FILE]
The policy file must be a valid JSON object that adheres to the structure and rules defined in this guide. After the command succeeds, the bucket enforces the new policy in addition to your organization access policies. The sections that follow describe the constraints to keep in mind and the JSON fields you use to author the policy.

Key considerations

Keep the following aspects of bucket access policies in mind:
Policy aspectDetails
Policy scopeBucket access policies can only grant S3-compatible API permissions. Actions under the cwobject: API (for example, managing access keys or audit logging) must be allowed through an organization access policy that uses "Resource": ["*"].
Lifecycle configurationBucket access policies uniquely govern bucket lifecycle configuration, including:

- Expiration actions (delete by date, age, or expired-marker)
- Noncurrent version expiration
- Abort incomplete multipart uploads
Access policies versus lifecycle policiesBucket access policies are not the same as lifecycle policies. Lifecycle policies manage object lifecycles, while bucket access policies control access to the bucket and its objects.

- Set access policies with s3:PutBucketPolicy.
- Set lifecycle policies with s3:PutBucketLifecycleConfiguration.
Global operationsCertain actions are global and only evaluate organization policies:

- s3:ListAllMyBuckets must specify "Resources": ["*"].
- s3:PutBucketPolicy is global and only checks organization access policies to avoid lock-out.
Principal specificationYou can’t use CoreWeave IAM groups in bucket access policies. Instead, specify principals by UID (from Cloud Console) or through SAML users and groups.
Explicit S3-compatible API accessThe Object Storage Admin IAM role (or membership in the legacy admin group) does not grant S3-compatible API access. You must explicitly allow it through organization or bucket access policies.
Make sure that your policy fits within the maximum policy size of 20 KB.

Structure of bucket access policies

Bucket access policies use JSON objects with two top-level fields: Version, Statement. The Statement field is an array of objects, each defining the access rules for a specific bucket or object. Each statement can include the following:
FieldDescription
SidOptional identifier for the policy statement.
EffectIndicates whether the policy allows or denies access.
PrincipalThe user, role, or group to which the policy applies.
ActionThe specific actions that the policy allows or denies.
ResourceThe resources to which the policy applies, specified in ARN format.
ConditionOptional element that specifies additional constraints for when the policy applies.

Version

Version is required. It defines the version of the policy language. Use 2012-10-17 for all policies. Some old policies use 2008-10-17. Any other value is invalid.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": { ... },
      "Action": [ ... ],
      "Resource": [ ... ],
      "Condition": { ... }
    }
  ]
}

Statement

Statement is required. It’s the main policy element that defines the access rules for buckets and objects. It can contain a single policy or an array. Enclose each policy in curly braces, and enclose arrays of policies in square brackets.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": { ... },
      "Action": [ ... ],
      "Resource": [ ... ],
      "Condition": { ... }
    },
    { ... },
    { ... }
  ]
}

Sid

Sid (Statement ID) is optional. It’s a short, human-readable identifier for the policy statement, which is useful for tracking and managing policies. Each Statement in an array of statements can have an assigned Sid. Each Sid must be unique within the JSON policy, and may only consist of ASCII uppercase letters, lowercase letters, or numbers.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": { ... },
      "Action": [ ... ],
      "Resource": [ ... ],
      "Condition": { ... }
    }
  ]
}

Effect

Effect is required. It specifies whether the statement allows or denies the action. The valid options are Allow or Deny, and these are case-sensitive. By default, CoreWeave denies access to resources. To allow access to a resource, set the Effect element to Allow. To override an allow that is otherwise in force, set the Effect element to Deny.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": { ... },
      "Action": [ ... ],
      "Resource": [ ... ],
      "Condition": { ... }
    }
  ]
}

Principal / NotPrincipal

This field defines who gets access to the resources specified in the policy. Either Principal or NotPrincipal is required. You can’t use them together.
  • Use Principal to specify the user, role, or group allowed for this policy.
  • Use NotPrincipal to deny access to all except the principal specified. NotPrincipal is only supported with "Effect": "Deny". You can’t use it with "Effect": "Allow".
Troubleshooting the side effects of NotPrincipal can be difficult. We recommend using options such as Condition instead. The key in the Principal object specifies the identity type:
  • Use CW for users from the CoreWeave Cloud Console.
  • Use AWS for identities from a federated SAML provider.
The value in the Principal object must be an ARN (Amazon Resource Name). In the path, indicate the source of the Principal:
  • For Console users: arn:aws:iam::[ORG-ID]:coreweave/[USER-ID]
  • For SAML users: arn:aws:iam::[ORG-ID]:saml/[USER-ID]
You can find your organization ID and user UID on the Settings page of your Cloud Console account. For OIDC users who set up Workload Identity Federation:
  • Use arn:aws:iam::[ORG-ID]:role/[JWT-ISSUER-URL]:[JWT-SUBJECT-USER-ID], where [JWT-ISSUER-URL] is the issuer of the JWT token and [JWT-SUBJECT-USER-ID] is the subject of the JWT token.
Do not use user/ in the ARN path. It isn’t a valid prefix for CoreWeave or SAML identities. To specify multiple principals in a single policy statement, include multiple entries in the Principal object:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": {
        "CW": [
          "arn:aws:iam::[ORG-ID]:coreweave/[USER-ID-1]",
          "arn:aws:iam::[ORG-ID]:coreweave/[USER-ID-2]"
        ],
      },
      "Action": [ ... ],
      "Resource": [ ... ],
      "Condition": { ... }
    }
  ]
}

Action / NotAction

Either Action or NotAction is required. You can’t use them together.
  • Use Action to describe the specific actions that are allowed or denied.
  • Use NotAction to match everything except the specified actions.
Wildcards such as s3:* are allowed to match multiple actions. Be careful when you combine NotAction and "Effect": "Allow" in the same policy because it could grant users more permissions than intended. See the list of API calls and required actions to determine what actions must be allowed for each API call.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": { ... },
      "Action": [
        "s3:ListBucket",
        "s3:GetObject"
      ],
      "Resource": [ ... ],
      "Condition": { ... }
    }
  ]
}

Resource / NotResource

Either Resource or NotResource is required. You can’t use them together.
  • Use Resource to apply the policy to the listed resources.
  • Use NotResource to apply the policy to all resources except the ones listed.
Use ARN format to specify resources. Wildcards * and ? are allowed within each colon-separated ARN segment. Wildcards don’t extend past colon boundaries. Don’t use NotResource in tandem with "Effect": "Allow" and "Action": "*" because this allows all actions on all resources except those listed.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": { ... },
      "Action": [ ... ],
      "Resource": [
        "arn:aws:s3:::[BUCKET-NAME]/[OBJECT-KEY]",
        "arn:aws:s3:::???-bucket/*/test"
      ],
      "Condition": { ... }
    }
  ]
}

Condition

Condition is optional. A Condition consists of an operator, and a key with a value. CoreWeave evaluates the condition to grant or deny access based on the request context.

Condition operators

The supported condition operators are:
FieldDescription
IpAddressThe specified IP address or range, such as 203.0.113.0/24
NotIpAddressAll IP addresses except the specified address
StringEqualsExact, case-sensitive match
StringNotEqualsMatch all except specified string, case-sensitive
StringLikeCase-sensitive match allowing wildcards
StringNotLikeNegated case-sensitive match allowing wildcards
StringEqualsIgnoreCaseExact match, ignores case
StringNotEqualsIgnoreCaseNegated exact match, ignores case
NullCheck for absent condition key

Condition keys

The supported condition keys are:
FieldDescription
cw:PrincipalArnThe principal, formatted as arn:partition:service:region:[ACCOUNT-ID]:[RESOURCE-TYPE/][RESOURCE-ID].
cw:ResourceArnThe resource ARN of the request.
cw:ResourceOrgIDThe organization ID from the owner of a resource.
cw:PrincipalOrgIDThe organization ID from the principal.
cw:SourceIPThe source IP address of the request.
cw:BucketThe bucket name of the request.
s3:prefixThe prefix of the request, used to list objects.
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UniquePolicyName",
      "Effect": "Allow",
      "Principal": { ... },
      "Action": [ ... ],
      "Resource": [ ... ],
      "Condition": {
        // Operator
        "IpAddress": {
          // Key with value
          "cw:SourceIP": "203.0.113.0/24"
        }
      }
    }
  ]
}

Example use cases

The following examples show bucket access policies for common scenarios. Use them as templates and adapt the principals, resources, and conditions to your own buckets.

Full access to a specific bucket for one user

This policy grants full access to a specific bucket for one user. It has two statements:
  • The first statement allows the specified user to perform all S3 actions on the bucket and its contents.
  • The second statement denies all other users access to the bucket and its contents.
Fill in the following parameters:
  • [ORG-ID] with your organization’s ID.
  • [USER-ID] with the ID of the user you want to grant full access to.
  • [BUCKET-NAME] with the name of the bucket you want to grant full access to.
Full access to a specific bucket for one user
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowOnlyOneUser",
      "Effect": "Allow",
      "Principal": {
        "CW": "arn:aws:iam::[ORG-ID]:coreweave/[USER-ID]"
      },
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::[BUCKET-NAME]",
        "arn:aws:s3:::[BUCKET-NAME]/*"
      ]
    },
    {
      "Sid": "DenyAllOthers",
      "Effect": "Deny",
      "NotPrincipal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::[BUCKET-NAME]",
        "arn:aws:s3:::[BUCKET-NAME]/*"
      ]
    }
  ]
}

Read-only for a specific bucket for all users in your organization

This policy grants read-only access to a specific bucket for all users in your organization. It has two statements:
  • The first statement allows all users in the organization to list the bucket and get its location.
  • The second statement allows all users in the organization to get objects from the bucket.
Replace [BUCKET-NAME] with the name of the bucket and [ORG-ID] with your organization’s ID.
Always include a Condition with cw:PrincipalOrgID when using "Principal": "*". Without it, the bucket is accessible to anyone on the internet, not just users in your organization.
Read-only for a specific bucket for all users in your organization
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowListBucket",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::[BUCKET-NAME]",
      "Condition": {
        "StringEquals": {
          "cw:PrincipalOrgID": ["[ORG-ID]"]
        }
      }
    },
    {
      "Sid": "AllowGetObjects",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::[BUCKET-NAME]/*",
      "Condition": {
        "StringEquals": {
          "cw:PrincipalOrgID": ["[ORG-ID]"]
        }
      }
    }
  ]
}

Read-only for a specific bucket for a specific user

This policy grants read-only access to a specific bucket for a specific user. It has two statements:
  • The first statement allows the specified user to list the bucket and get its location.
  • The second statement allows the specified user to get objects from the bucket.
Fill in the following parameters:
  • [ORG-ID] with your organization’s ID.
  • [USER-ID] with the ID of the user you want to grant read-only access to.
  • [BUCKET-NAME] with the name of the bucket you want to grant read-only access to.
Read-only for a specific bucket for a specific user
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "UserReadBucket",
      "Effect": "Allow",
      "Principal": {
        "CW": "arn:aws:iam::[ORG-ID]:coreweave/[USER-ID]"
      },
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::[BUCKET-NAME]"
    },
    {
      "Sid": "UserGetObjects",
      "Effect": "Allow",
      "Principal": {
        "CW": "arn:aws:iam::[ORG-ID]:coreweave/[USER-ID]"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::[BUCKET-NAME]/*"
    }
  ]
}

All buckets read-only for all users in your organization

This policy grants read-only access to all buckets for all users in your organization. It has three statements:
  • The first statement allows all users in the organization to list all buckets.
  • The second statement allows all users in the organization to list and describe all buckets.
  • The third statement allows all users in the organization to get objects from all buckets.
Replace [ORG-ID] with your organization’s ID.
Always include a Condition with cw:PrincipalOrgID when using "Principal": "*". Without it, the bucket is accessible to anyone on the internet, not just users in your organization.
All buckets read-only for all users in your organization
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListAllBuckets",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:ListAllMyBuckets",
      "Resource": "arn:aws:s3:::*",
      "Condition": {
        "StringEquals": {
          "cw:PrincipalOrgID": ["[ORG-ID]"]
        }
      }
    },
    {
      "Sid": "ListAndDescribeBuckets",
      "Effect": "Allow",
      "Principal": "*",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::*",
      "Condition": {
        "StringEquals": {
          "cw:PrincipalOrgID": ["[ORG-ID]"]
        }
      }
    },
    {
      "Sid": "GetAllObjects",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::*/*",
      "Condition": {
        "StringEquals": {
          "cw:PrincipalOrgID": ["[ORG-ID]"]
        }
      }
    }
  ]
}

Limit to a specific prefix

This policy restricts the ListBucket action to a specific prefix within a bucket. It has two statements:
  • The first statement allows the user to list objects in the bucket only if the prefix matches projects.
  • The second statement denies the user from listing objects in the bucket if the prefix doesn’t match projects.
The Condition statement allows the user to list only object keys that start with the projects prefix. An explicit Deny statement blocks the user from listing any other keys, even if other policies grant broader permissions. For instance, the user might later receive permissions to list all keys through an updated user policy or bucket policy. But because Deny takes precedence over Allow, CoreWeave denies any request to list keys outside the projects prefix. Replace [BUCKET-NAME] with the name of the bucket and [ORG-ID] with your organization’s ID.
Limit to a specific prefix
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowIfPrefixEquals",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::[BUCKET-NAME]",
      "Condition": {
        "StringEquals": {
          "s3:prefix": "projects",
          "cw:PrincipalOrgID": ["[ORG-ID]"]
        }
      }
    },
    {
      "Sid": "DenyIfPrefixNotEquals",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::[BUCKET-NAME]",
      "Condition": {
        "StringNotEquals": {
          "s3:prefix": "projects"
        }
      }
    }
  ]
}

Required policies and actions

Each API call requires permission to perform one or more related actions, and those action names don’t always match the API calls. Some API calls perform multiple actions that require permission to separate actions. For example, copying an object requires permission to perform both s3:PutObject and s3:GetObject actions. Use the following permission mapping when you plan bucket access policies. See Object Storage API features for a complementary list of API calls mapped to their associated actions.
Required action permissionAPI call
s3:AbortMultipartUploads3:AbortMultiPartUpLoad
s3:CreateBuckets3:CreateBucket
s3:DeleteBuckets3:DeleteBucket
s3:DeleteObjects3:DeleteObject
s3:DeleteObjects
s3:RenameObject
s3:DeleteObjectTaggings3:DeleteObjectTagging
s3:DeleteObjectVersions3:DeleteObject
s3:DeleteObjects
s3:DeleteLifecycleConfigurations3:DeleteBucketLifeCycle
s3:DeleteBucketPolicys3:DeleteBucketPolicy
s3:DeleteBucketTaggings3:DeleteBucketTagging
s3:GetLifecycleConfigurations3:GetBucketLifecycleConfiguration
s3:GetBucketLocations3:GetBucketLocation
s3:GetBucketPolicys3:GetBucketPolicy
s3:GetBucketTaggings3:GetBucketTagging
s3:GetBucketVersionings3:GetBucketVersioning
s3:GetObjects3:CopyObject
s3:GetObject
s3:GetObjectAcl
s3:GetObjectAttributes
s3:HeadObject
s3:UploadPartCopy
s3:GetObjectTaggings3:GetObjectTagging
s3:ListAllMyBucketss3:ListBuckets
s3:ListBuckets3:GetBucketACL
s3:HeadBucket
s3:ListObjectsV2
s3:ListObjectVersions
s3:ListMultipartUploadPartss3:ListParts
s3:ListBucketMultipartUploadss3:ListMultiPartUploads
s3:PutLifecycleConfigurations3:PutBucketLifecycleConfiguration
s3:PutBucketPolicys3:PutBucketPolicy
If no policy exists, CoreWeave grants access to create a new policy if the user’s organization ID matches the bucket’s organization.
s3:PutBucketTaggings3:PutBucketTagging
s3:PutBucketVersionings3:PutBucketVersioning
s3:PutObjects3:CompleteMultiPartUpLoad
s3:CopyObject
s3:CreateMultiPartUpLoad
s3:PutObject
s3:RenameObject
s3:UploadPart
s3:UploadPartCopy

PutObject, CompleteMultiPartUpLoad, CopyObject, and RenameObject support conditional writes.
s3:PutObjectTaggings3:PutObjectTagging

Bucket lifecycle policy

Bucket lifecycle policies automate object management in CoreWeave AI Object Storage. Each policy consists of rules that apply actions to objects or their versions. A lifecycle rule can perform the following actions:
  • Transition: Move objects to a different storage class. Not supported.
  • Expiration: Delete objects after a specified period. CoreWeave AI Object Storage handles deletion automatically. If multiple rules apply, the earliest expiration wins.
  • Noncurrent version expiration: For versioned buckets, remove older object versions after a defined count or time.
  • Abort incomplete multipart uploads: Delete multipart upload parts that remain incomplete after a set number of days.
The following example shows how to configure each action. The field reference describes each field.
{
  "Rules": [
    {
      "Expiration": {
        "Date": timestamp,
        "Days": integer,
        "ExpiredObjectDeleteMarker": true|false
      },
      "ID": "string",
      "Prefix": "string",
      "Filter": {
        "Prefix": "string",
        "Tag": {
          "Key": "string",
          "Value": "string"
        },
        "ObjectSizeGreaterThan": long,
        "ObjectSizeLessThan": long,
        "And": {
          "Prefix": "string",
          "Tags": [
            {
              "Key": "string",
              "Value": "string"
            }
            ...
          ],
          "ObjectSizeGreaterThan": long,
          "ObjectSizeLessThan": long
        }
      },
      "Status": "Enabled"|"Disabled",
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": integer,
        "NewerNoncurrentVersions": integer
      },
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": integer
      }
    }
    ...
  ]
}

RuleDefinition
ExpirationThis type of rule specifies that CoreWeave deletes an object when it reaches either a listed Date, a number of days old, or when an expired Delete marker is present. The date must be in ISO 8601 format and the time in UTC 0000.
ExpiredObjectDeleteMarkerIndicates whether CoreWeave removes a delete marker with no noncurrent versions. If set to true, CoreWeave expires the delete marker. If set to false, the policy takes no action. You can’t specify this with Days or Date.
IDIdentifier for the rule itself. Can be up to 255 characters.
FilterSpecifies objects for which a rule applies. Must contain only one of a Prefix, Tag, or And value. An empty Filter indiscriminately applies to all objects in a bucket.
PrefixA prefix to match on for an object. For instance, foo/ matches both foo/bar and foo/baz. Only one prefix per rule can match.
TagAn object that specifies a tag (key) and its value. Use multiple tags at once with And.
AndLets you match on multiple tags and up to one prefix.
ObjectSizeYou can specify a range of sizes in bytes with ObjectSizeGreaterThan and ObjectSizeLessThan.
StatusStatus shows whether this rule is enabled or not. If the rule is disabled, CoreWeave doesn’t apply it.
NoncurrentVersionExpirationSpecifies how long and how many noncurrent versions of a versioned (or versioning suspended) object to keep.
NoncurrentDaysHow many days after an object becomes noncurrent before deletion.
NewerNoncurrentVersionsDeletion only occurs after the specified number of noncurrent versions is reached. The process starts with the oldest version.
AbortIncompleteMultipartUploadSpecify a number of days after the start of a multipart upload with DaysAfterInitiation to delete all parts if the upload is aborted.
Last modified on May 29, 2026