Storage

Preview — pending review

This reference is generated from the platform API contract and is still under review. Operations, fields, and descriptions can change before publication.

Add a CORS rule to the bucket (lifecycle and replication are refused)

POST
/scopes/{scopeId}/storage/buckets/{bucketId}/configuration-rules

Adds one configuration rule to the bucket: a CORS rule (origins, methods, headers, max age). The request carries a type discriminator and exactly the matching payload object; the created rule then appears in the bucket detail's corsRules. type: lifecycle and type: replication remain in the discriminator but are always refused (see below). CORS on OpenStack Swift. Swift holds ONE CORS policy per container, in container metadata, so every CORS rule of the bucket is merged into it: the union of origins (X-Container-Meta-Access-Control-Allow-Origin), the union of headers (X-Container-Meta-Access-Control-Expose-Headers — the response headers a browser script may read) and the longest maxAgeSeconds (X-Container-Meta-Access-Control-Max-Age). Swift answers a preflight from an allowed origin with every method the container supports and echoes back any requested header, so methods is recorded and returned but NOT enforced per rule, and there is no allowed-request-headers restriction. Lifecycle is not supported. Swift has no lifecycle engine, so type: lifecycle is refused with 422 VALIDATION_FAILED, field: lifecycle, details.reason: lifecycle_not_supported; nothing is stored. Replication is not supported. Nothing configures Swift container-sync from a rule, so type: replication is refused with 422 VALIDATION_FAILED, field: replication, details.reason: replication_not_supported (also for a malformed replication payload); nothing is stored. Validation: bucketId must reference an existing, non-deleted bucket in the scope (unknown → 404 NOT_FOUND); type must be one of cors|lifecycle|replication and the matching payload object must be present while the other two are absent (mismatch → 422 VALIDATION_FAILED); type: lifecycle → 422 VALIDATION_FAILED (details.reason: lifecycle_not_supported); CORS rules need ≥1 origin and ≥1 method with maxAgeSeconds ≥ 0, every origin * or an ASCII scheme://host[:port] (no path, wildcard, credentials or whitespace; IDN hosts in punycode — Swift matches origins exactly; else 422 with field: cors.origins), stored lowercased (browsers send Origin lowercased), and every header a single HTTP header name or * (else 422 with field: cors.headers); the bucket's MERGED origin list and merged header list must each fit the object store's metadata value limit (256 bytes by default, space-separated) — else 422 with details.reason: cors_policy_too_large; type: replication → 422 VALIDATION_FAILED (details.reason: replication_not_supported); the per-bucket rule-count limit must not be exhausted (→ 409 QUOTA_EXCEEDED); caller must hold owner|admin|contributor on the scope, otherwise 403 FORBIDDEN. Async & state: Synchronous — returns 201 with the created BucketConfigurationRule once it is stored on the bucket. A CORS rule is applied to the Swift container asynchronously, within seconds, by a tracked objectstore.bucket.cors.apply Operation that rewrites the container's merged CORS metadata from the bucket's current rules. A transient object-store failure is retried; a refusal or exhausted retries end the Operation FAILED (the rule stays stored, the container keeps its previous policy, and a resource.updated frame carries corsApply.status: failed; the next CORS change re-applies the whole policy). The state is readable as BucketDetail.corsApply. A resource.updated SSE frame is emitted (kind storage.bucket, patch {corsRuleCount}). Errors: 401 unauthenticated; 403 caller lacks write permission on the scope; 404 unknown scopeId or bucketId; 409 CONFLICT bucket state does not permit the change; 409 QUOTA_EXCEEDED per-bucket rule limit reached; 422 discriminator or payload validation failure, unsupported lifecycle or replication rule; 500 unexpected backend failure. Idempotency/Concurrency: Idempotency-Key is optional (recommended); replaying the same key returns the originally created rule (same id) instead of appending a duplicate — retries where duplicate creation would be harmful are therefore safe.

Authorization

bearerToken
headerAuthorizationBearer <token>

An API token (pc_live_…) or a service-account key (sak_live_…), created in Identity & Access Management and sent as Authorization: Bearer <token>. Requests are rate limited per credential and per tenant: every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, and a refused request gets 429 RATE_LIMITED with Retry-After.

Path Parameters

scopeId*string

Opaque ownership+authorization scope resolving to tenant + subscription + project.

bucketId*string

Identifier of the bucket.

Header Parameters

Idempotency-Key?string

Optional; recommended for safe retries. When sent, the same key+body within 24h replays the original result and the same key with a different body is 409 CONFLICT; keys are unique per tenant. When an API token or service-account (bearer) caller omits it, the request is applied once with no replay protection (a retry may apply it again). A console session gets one from the edge.

Formatuuid

Request Body

application/json
  1. body

Type-discriminated payload for adding a CORS, lifecycle or replication rule; exactly the payload matching type must be present.

type*BucketConfigurationRuleType

Kind of bucket configuration rule (CORS, lifecycle or replication).

Value in"cors""lifecycle""replication"
cors?

Payload for creating a CORS configuration rule.

lifecycle?

Payload for a lifecycle rule. Not supported — a create with it is refused 422 lifecycle_not_supported.

replication?

Payload for a cross-region replication rule. Not supported — a type: replication rule create is refused with 422 details.reason: replication_not_supported.

Response Body

Configuration rule created and now active on the bucket.

application/json
  1. response

Created configuration rule; exactly one of cors, lifecycle or replication is non-null, matching type.

id*string
bucketId*string
type*BucketConfigurationRuleType

Kind of bucket configuration rule (CORS, lifecycle or replication).

Value in"cors""lifecycle""replication"
cors*|null
lifecycle*|null
replication*|null
curl -X POST "https://example.com/scopes/string/storage/buckets/string/configuration-rules" \  -H "Content-Type: application/json" \  -d '{    "type": "cors"  }'
{  "id": "string",  "bucketId": "string",  "type": "cors",  "cors": {    "id": "string",    "origins": [      "string"    ],    "methods": [      "string"    ],    "headers": [      "string"    ],    "maxAgeSeconds": 0  },  "lifecycle": {    "id": "string",    "name": "string",    "prefix": "string",    "enabled": true,    "action": "string",    "days": 0  },  "replication": {    "id": "string",    "name": "string",    "prefix": "string",    "destination": "string",    "destinationRegion": "string",    "storageClass": "string",    "status": "Enabled",    "rtoMinutes": 0  }}