OneFS S3 CORS Support

Modern web applications routinely load resources — images, videos, fonts, scripts — from origins other than the server hosting the page. Browsers enforce the ‘same-origin policy’ by default, which blocks these cross-origin requests unless the target server explicitly permits them. Cross-Origin Resource Sharing (CORS) is the W3C mechanism that provides those permissions, and as of OneFS 9.14, PowerScale S3 supports it natively on a per-bucket basis.

This capability matters for any organization running a web application that reads from or writes to a PowerScale S3 bucket directly from a browser. Without CORS configuration on the bucket, the browser silently blocks the request at the network layer — no error in the server logs, just a failed request on the client side. A CORS policy tells the browser which origins, HTTP methods, and headers are acceptable, enabling seamless integration between frontend applications and PowerScale object storage while preserving the bucket’s underlying access controls.

Web browsers enforce a same-origin policy that, by default, prevents a web application served from one origin (a combination of scheme, host, and port) from reading resources served from a different origin. CORS relaxes this policy in a controlled manner. By using a defined set of HTTP response headers, a resource declares which other origins, HTTP methods, and request headers are permitted to access it.

Before sending a cross-origin request that could have side effects — such as a PUT or DELETE — the browser sends an HTTP OPTIONS preflight request to the target server. The preflight carries:

  • Origin — the domain making the request
  • Access-Control-Request-Method — the HTTP method the browser intends to use
  • Access-Control-Request-Headers — any non-standard request headers

The S3 service evaluates these headers against the bucket’s CORS configuration and returns the appropriate Access-Control-* response headers. If all three are permitted by a matching rule, the browser proceeds with the actual request. If any one is rejected, the browser aborts. For simple read-only requests (GET, HEAD) the browser skips the preflight and reads the CORS response headers from the actual response directly.

CORS support extends OneFS S3 to browser-based workloads that would otherwise be blocked by the same-origin policy. Consider, for example, a website which needs to load images and other assets from a PowerScale S3 bucket. Without a CORS configuration the browser blocks these requests. Once CORS is configured to allow the application’s origin, the assets are retrieved and displayed successfully. Similarly, workflows where users upload files directly to a PowerScale S3 bucket from a front-end application, with no back-end proxy server in the request path. Once the bucket permits the application’s origin, uploads succeed and the browser receives a valid response with no CORS errors.

OneFS 9.14 introduces three new S3 API operations for managing per-bucket CORS configuration, and extends all existing bucket and object APIs with CORS response headers.

The CORS configuration is attached to an individual bucket and defines one or more rules. Each rule declares the allowed origins, HTTP methods, request headers, response headers to expose, and how long a browser may cache a preflight result.

1.       PutBucketCors

PutBucketCors sets a CORS configuration on a bucket. If a configuration already exists it is replaced in full — there is no partial update. The request body is an XML document:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <CORSRule>
    <ID>allow-webapp</ID>
    <AllowedOrigin>https://app.example.com</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
    <ExposeHeader>ETag</ExposeHeader>
    <MaxAgeSeconds>3600</MaxAgeSeconds>
  </CORSRule>
</CORSConfiguration>

A bucket can have multiple CORSRule blocks, each scoped to a different origin or method set. MaxAgeSeconds controls how long the browser may cache the preflight response, reducing round trips for repeat requests. Table 1 describes the CORS rule elements.

Element Description
AllowedOrigin One or more origins from which cross-origin requests
are allowed. A single wildcard (*) is permitted.
AllowedMethod An HTTP method the origin is allowed to use.
Valid values:GET,PUT,HEAD,POST,DELETE.
AllowedHeader A request header allowed in a preflight request viaAccess-Control-Request-Headers. A trailing wildcard (*)
is permitted.
ExposeHeader A response header that the browser is allowed to expose
to the client application.
ID An optional unique identifier for the rule.
MaxAgeSeconds The time in seconds that the browser may cache the
preflight response for the requested resource.

Required permission: Bucket owner or FULL_CONTROL ACL on the
bucket. Using the AWS CLI against a PowerScale endpoint:

aws s3api put-bucket-cors \
  --bucket mybucket \
  --cors-configuration file://cors.json \
  --endpoint-url https://powerscale.example.com:9020

2.       GetBucketCors

GetBucketCors returns the current CORS configuration for a bucket:

GET /<bucket>?cors

The response returns the same XML structure set by PutBucketCors. If no CORS configuration exists, the API returns 404 NoSuchCorsConfiguration.

Required permission: Bucket owner or READ ACL.

aws s3api get-bucket-cors \
  --bucket mybucket \
  --endpoint-url https://powerscale.example.com:9020

3.       DeleteBucketCors

DeleteBucketCors removes the CORS configuration from a bucket entirely:

DELETE /<bucket>?cors

After deletion the bucket returns no CORS headers and browser cross-origin requests will fail. There is no versioning, so the configuration is gone immediately.

Required permission: Bucket owner or FULL_CONTROL ACL.

The other new S3 operation introduced in OneFS 9.14 is the HTTP OPTIONS method, which browsers send as a preflight check before a cross-origin request that could have side effects. OneFS evaluates the preflight entirely outside the normal S3 authentication path, with no credentials required:

OPTIONS /<bucket>/<object> HTTP/1.1
Origin: https://app.example.com                  # origin url, including scheme and port
Access-Control-Request-Method: PUT               # intended http method
Access-Control-Request-Headers: Content-Type     # non-standard request headers

OneFS compares the origin, method, and headers against the bucket’s CORS rules and responds with the appropriate ‘Access-Control-*’ headers. Authentication is bypassed for ‘OPTIONS’ by design, consistent with the S3 specification, since the browser sends the preflight before it has any context for signing the subsequent request.

In addition to the three new CORS operations, all existing bucket-level and object-level S3 APIs now return CORS response headers on 200 OK responses where the request matches a configured rule. Three bucket-level APIs (HeadBucket, PutBucket/CreateBucket, and DeleteBucket) are intentionally excluded, consistent with Amazon S3 behavior.

Response Header Description
Access-Control-Allow-Origin The origin permitted to access the
resource, echoed from the matched rule, or a wildcard (*).
Access-Control-Allow-Methods The HTTP methods permitted for the
matched origin.
Access-Control-Allow-Headers The request headers permitted in the
actual cross-origin request.
Access-Control-Expose-Headers The response headers the browser is
allowed to expose to the client application (e.g.ETag).
Access-Control-Max-Age How long in seconds the browser may cache
the preflight response.
Access-Control-Allow-Credentials Whether the response may be exposed
when the request’s credentials mode is set.

CORS support requires no additional cluster-level configuration. The feature becomes active once the S3 service is enabled on the cluster:

# isi s3 settings global modify --service enabled

A CORS rule applies to a bucket only after a client sets a configuration with PutBucketCors. Until then, the bucket enforces the browser’s default same-origin behavior. On upgrade, the feature is applied after the upgrade is committed. After uninstallation the feature no longer functions.

When investigating and troubleshooting S3 CORS, the most common issues typically fall into three categories:

  • CORS configuration management errors
  • OPTIONS preflight errors
  • Rule matching failures.

1. CORS Configuration Management Errors

These occur when calling PutBucketCors, GetBucketCors, or DeleteBucketCors directly, typically because the supplied XML is malformed, the caller lacks the required ACL, or no configuration has been set yet:

Status Error Cause Resolution
400 Bad Request Incorrect CORS configuration XML Check the error message and fix the configuration issue
403 Forbidden Caller lacks required bucket ACL FULL_CONTROL for Put/Delete, READ for Get; must be bucket owner
404 NoSuchCorsConfiguration No CORS config set on the bucket CallPutBucketCorsfirst

2. OPTIONS Preflight Errors

These are returned when the browser’s preflight request is missing one of the two required headers that OneFS needs to evaluate the request against the bucket’s CORS rules:

Status Error Cause Resolution
400 InvalidRequest OPTIONS preflight missingOriginorAccess-Control-Request-Method Both headers are required in every preflight request

3. Rule Matching Failures

These are the most frequent issues in practice. The bucket has a CORS configuration but the incoming request does not satisfy any rule, either because no configuration exists at all, or because the origin, method, or headers are not listed as permitted. CorsNotAllowed is the most common: AllowedOrigin values are matched exactly, so https://app.example.com and https://app.example.com:443 are treated as different origins. Wildcards (*) are supported in AllowedOrigin and AllowedHeader but not in AllowedMethod:

Status Error Cause Resolution
403 CorsNotEnabled No CORS configuration on the bucket CallPutBucketCorsto define at least one rule
403 CorsNotAllowed Origin, method, or headers not matched by any configured rule Review the CORS rules; confirmAllowedOriginmatches exactly
(scheme + host + port)

In summary, PowerScale S3 CORS support in OneFS 9.14 adds three new S3 APIs, PutBucketCors, GetBucketCors, and DeleteBucketCors, plus the OPTIONS preflight handler. CORS response headers are also returned upon the successful responses of all existing bucket and object operations where a matching rule exists.

Configuration is per-bucket, requires no additional licensing, and takes effect immediately after PutBucketCors is called. The implementation is compatible with standard AWS S3 SDK clients using the ‘–endpoint-url’ override, making it straightforward to integrate into existing web application stacks that already target Amazon S3.

Leave a Reply

Your email address will not be published. Required fields are marked *