Skip to content

Object storage (S3)

Sunet Cloud exposes an S3-compatible object store backed by Ceph RADOS Gateway. Any tool or SDK that speaks the AWS S3 API works against it. Use it for backups, datasets, build artifacts, static website content, and application data that you read and write over the network.

Endpoint

Endpoint URL https://s3.orion.sunetvdc.se
Addressing style Path-style (https://s3.orion.sunetvdc.se/<bucket>/<key>)
Region Leave empty, or use us-east-1 if a tool insists on a value

The shorter name https://s3.sunetvdc.se redirects to the endpoint above. Configure your client with the full s3.orion.sunetvdc.se host.

Getting access keys

S3 access keys come from your OpenStack project as EC2 credentials, so you need access to a project first. Follow S3 authentication to create an unrestricted application credential for that project and load it into the OpenStack client. Restricted application credentials cannot issue S3 keys.

With that application credential loaded, create a new S3 key pair:

openstack ec2 credentials create

This prints an access and a secret value. They are scoped to the project and user you created them under. Use these values in your S3 client, not the application credential ID and secret. Since Horizon 2025.2, API Access → View Credentials no longer displays S3 keys.

To reuse an existing pair, follow Manage S3 credentials. Keep the secret safe. To revoke a key, replace ACCESS_KEY with its access key and delete the matching EC2 credential:

openstack ec2 credentials delete ACCESS_KEY

Configuring common tools

aws configure        # paste the access key and secret
aws --endpoint-url https://s3.orion.sunetvdc.se s3 ls
aws --endpoint-url https://s3.orion.sunetvdc.se \
    s3 mb s3://my-bucket
aws --endpoint-url https://s3.orion.sunetvdc.se \
    s3 cp file.tar s3://my-bucket/

~/.s3cfg:

[default]
access_key = YOUR_ACCESS_KEY
secret_key = YOUR_SECRET_KEY
host_base = s3.orion.sunetvdc.se
host_bucket = s3.orion.sunetvdc.se
use_https = True

The host_bucket without a %(bucket)s placeholder keeps s3cmd in path-style mode, which is what the gateway expects.

rclone config section:

[sunet-s3]
type = s3
provider = Ceph
access_key_id = YOUR_ACCESS_KEY
secret_access_key = YOUR_SECRET_KEY
endpoint = https://s3.orion.sunetvdc.se

Then rclone ls sunet-s3:my-bucket.

Buckets, prefixes, and lifecycle

  • Create as many buckets as you need. Bucket names are shared across the whole gateway, so pick names that are unlikely to collide (prefix them with your project or organisation).
  • There are no real "folders". Keys with / in them are shown as a hierarchy by most tools, but the store is flat.
  • Versioning, object lifecycle (expiry) rules, and presigned URLs work as they do in AWS S3, through the same API calls your tooling already uses.

Restricting access to a bucket

All S3 credentials in one OpenStack project represent the same project to the object store. Creating another EC2 credential, application credential, or user in the same project therefore does not create an S3 identity that can be restricted independently.

To give an application access to only selected buckets, create a separate OpenStack project for its users and credentials, then grant that project access with an S3 bucket policy. A project used only to manage identities and credentials does not itself incur a cost. Normal charges still apply to resources and stored data.

The following example grants project B read-only access to BUCKET_A:

  1. Authenticate the OpenStack CLI with an unrestricted application credential created for project B (see S3 authentication), then create its S3 credentials:

    openstack ec2 credentials create
    
  2. Configure the credentials as the AWS CLI profile project-b, then make one S3 request to initialize the project's object-store identity:

    aws --profile project-b \
      --endpoint-url https://s3.orion.sunetvdc.se \
      s3 ls
    
  3. Get project B's UUID from a project-B-scoped OpenStack session:

    openstack token issue \
      -f value \
      -c project_id
    
  4. Create bucket-policy.json, replacing PROJECT_B_UUID and BUCKET_A:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Sid": "AllowProjectBToListBucket",
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam:::user/PROJECT_B_UUID"
          },
          "Action": "s3:ListBucket",
          "Resource": "arn:aws:s3:::BUCKET_A"
        },
        {
          "Sid": "AllowProjectBToReadObjects",
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam:::user/PROJECT_B_UUID"
          },
          "Action": "s3:GetObject",
          "Resource": "arn:aws:s3:::BUCKET_A/*"
        }
      ]
    }
    
  5. Apply the policy using an AWS CLI profile containing the bucket owner's project-A credentials:

    aws --profile project-a \
      --endpoint-url https://s3.orion.sunetvdc.se \
      s3api put-bucket-policy \
      --bucket BUCKET_A \
      --policy file://bucket-policy.json
    

Project B can now list bucket A and read its objects. Add s3:PutObject to the object statement to permit uploads, and add s3:DeleteObject only if the application must delete objects. Everyone with valid project B S3 credentials receives the granted access. Review keys when project membership changes and explicitly delete credentials that are no longer needed, replacing ACCESS_KEY with the access key to revoke:

openstack ec2 credentials delete ACCESS_KEY

Billing

Object storage is billed per gigabyte stored per month. Committing to a longer term lowers the rate. See Durability, quotas and billing for current figures.