Bucket CORS
CORS (Cross-Origin Resource Sharing) is a mechanism that allows web browsers to make requests to a different domain than the current page's domain. When your web application (running on app.example.com) needs to load files directly from a LANIT Cloud bucket, you must configure CORS so the browser is not blocked by the Same-Origin policy.
When Do You Need to Configure CORS?
- Uploading files directly from the browser to a bucket (browser-side upload)
- Web pages displaying images, videos, or fonts from a bucket
- SPA applications (React, Vue, Angular) calling the S3 API directly from the client side
- Static website hosting that needs to load cross-domain resources
Access the CORS Configuration
Step 1: Go to Simple Storage → Buckets, then click the name of the bucket you want to configure.
Step 2: Open the CORS tab in the bucket management section.

Step 3: Click Update to add a new CORS rule. Fill in the fields: Allowed Origins, Allowed Headers, Allowed Methods, Expose Headers, Max Age Seconds.

CORS Configuration Structure
The CORS configuration is a JSON array of rules:
[
{
"AllowedOrigins": ["https://app.example.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag", "Content-Length"],
"MaxAgeSeconds": 3000
}
]
Field descriptions:
| Field | Required | Description |
|---|---|---|
AllowedOrigins | ✅ | List of allowed domains. Use "*" to allow all domains |
AllowedMethods | ✅ | HTTP methods allowed: GET, PUT, POST, DELETE, HEAD |
AllowedHeaders | ❌ | Headers allowed in requests. "*" = all headers |
ExposeHeaders | ❌ | Headers the browser is allowed to read from responses |
MaxAgeSeconds | ❌ | Duration (seconds) the browser caches preflight request results |
Common Configuration Examples
1. Allow all origins read access (CDN, public assets)
Suitable for buckets containing public images, fonts, CSS:
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET", "HEAD"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 86400
}
]
2. Direct browser upload (Presigned URL Upload)
Allow a web application to upload files to the bucket using a presigned URL:
[
{
"AllowedOrigins": [
"https://app.example.com",
"https://staging.example.com"
],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": [
"Content-Type",
"Content-MD5",
"Authorization",
"x-amz-date",
"x-amz-content-sha256",
"x-amz-security-token"
],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]
3. Development environment (localhost)
Add localhost for development and local testing:
[
{
"AllowedOrigins": [
"http://localhost:3000",
"http://localhost:8080",
"https://app.example.com"
],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE", "HEAD"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag", "Content-Length", "Content-Type"],
"MaxAgeSeconds": 3000
}
]
4. Multiple rules for different use cases
[
{
"AllowedOrigins": ["*"],
"AllowedMethods": ["GET"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 86400
},
{
"AllowedOrigins": ["https://admin.example.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedHeaders": ["*"],
"ExposeHeaders": ["ETag"],
"MaxAgeSeconds": 3000
}
]
Apply the CORS Configuration
Step 1: Paste the JSON configuration into the editor on the portal.
Step 2: Click Save or Apply CORS.
Step 3: The configuration takes effect immediately (it may take a few seconds to propagate).
Remove the CORS Configuration
Clear all content in the editor and save with an empty array [], or use the Remove CORS button if available.
Test CORS
To test that CORS is working, use curl to send a preflight request:
curl -X OPTIONS \
-H "Origin: https://app.example.com" \
-H "Access-Control-Request-Method: GET" \
-H "Access-Control-Request-Headers: Content-Type" \
-v \
https://your-bucket.s3.lanit.com.vn/test-object.jpg
A correct response contains headers:
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Methods: GET, HEAD
CORS only applies to web browsers. Requests from servers, AWS CLI, or Rclone are not affected by the CORS configuration.
Avoid using "AllowedOrigins": ["*"] combined with AllowedMethods that include PUT/DELETE on buckets containing sensitive data — this allows any website to perform write/delete operations on your bucket.