Application integration

Connect an S3 application to X2

Use standard AWS Signature Version 4 clients with the X2 HTTPS endpoint, an account access key, its secret, and the configured signing region.

01

Collect five connection values

Endpoint
https://x2.example.com
Access key
Created for the application identity
Secret key
Shown once when the key is created
Region
us-east-1, unless configured differently
TLS trust
Public CA or the cluster CA certificate

Use path-style addressing for IP endpoints and whenever wildcard bucket DNS is not configured. Never use an X2 Console password as an S3 secret key.

02

AWS CLI

export AWS_ACCESS_KEY_ID='your-access-key'
export AWS_SECRET_ACCESS_KEY='your-secret-key'
export AWS_DEFAULT_REGION='us-east-1'
export AWS_CA_BUNDLE='/path/to/x2-ca.crt'

aws --endpoint-url https://x2.example.com s3api list-buckets
aws --endpoint-url https://x2.example.com s3 mb s3://media
aws --endpoint-url https://x2.example.com s3 cp ./photo.jpg s3://media/photo.jpg
aws --endpoint-url https://x2.example.com s3 ls s3://media/

On PowerShell, assign the same names with $env:NAME = 'value'. Prefer a CA bundle over --no-verify-ssl.

03

Python with Boto3

import os
import boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    endpoint_url="https://x2.example.com",
    region_name="us-east-1",
    aws_access_key_id=os.environ["AWS_ACCESS_KEY_ID"],
    aws_secret_access_key=os.environ["AWS_SECRET_ACCESS_KEY"],
    verify="/path/to/x2-ca.crt",
    config=Config(signature_version="s3v4", s3={"addressing_style": "path"}),
)

s3.create_bucket(Bucket="media")
s3.upload_file("photo.jpg", "media", "photo.jpg")
print(s3.list_objects_v2(Bucket="media").get("Contents", []))
04

JavaScript with AWS SDK v3

import { S3Client, PutObjectCommand, ListObjectsV2Command } from "@aws-sdk/client-s3";
import { readFile } from "node:fs/promises";

const s3 = new S3Client({
  endpoint: "https://x2.example.com",
  region: "us-east-1",
  forcePathStyle: true,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  },
});

await s3.send(new PutObjectCommand({
  Bucket: "media", Key: "photo.jpg", Body: await readFile("photo.jpg"),
}));
console.log(await s3.send(new ListObjectsV2Command({ Bucket: "media" })));

For a private CA, configure the Node.js HTTPS trust store for the process instead of disabling TLS verification.

05

Go with AWS SDK v2

package main

import (
    "context"
    "os"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
)

func main() {
    ctx := context.Background()
    cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"))
    if err != nil { panic(err) }
    client := s3.NewFromConfig(cfg, func(o *s3.Options) {
        o.BaseEndpoint = aws.String("https://x2.example.com")
        o.UsePathStyle = true
    })
    file, err := os.Open("photo.jpg")
    if err != nil { panic(err) }
    defer file.Close()
    _, err = client.PutObject(ctx, &s3.PutObjectInput{
        Bucket: aws.String("media"), Key: aws.String("photo.jpg"), Body: file,
    })
    if err != nil { panic(err) }
}

The default credential chain reads AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.

06

Java with AWS SDK v2

S3Configuration s3Configuration = S3Configuration.builder()
    .pathStyleAccessEnabled(true)
    .build();

S3Client s3 = S3Client.builder()
    .endpointOverride(URI.create("https://x2.example.com"))
    .region(Region.US_EAST_1)
    .credentialsProvider(DefaultCredentialsProvider.create())
    .serviceConfiguration(s3Configuration)
    .build();

s3.putObject(
    PutObjectRequest.builder().bucket("media").key("photo.jpg").build(),
    RequestBody.fromFile(Paths.get("photo.jpg"))
);

Import the corresponding classes from software.amazon.awssdk. Configure the JVM trust store with the X2 endpoint CA when it is not publicly trusted.

07

Troubleshoot connection failures

SignatureDoesNotMatch

Verify access key and secret, endpoint, region, request path, proxy rewriting, and system clock. Do not sign one URL and send another.

AccessDenied

The signature was accepted, but the identity lacks the required bucket or object permission.

TLS verification failure

Trust the issuing CA and use a hostname or IP covered by the endpoint certificate.

Redirect or DNS failure

Enable path-style addressing unless wildcard bucket DNS and certificates are configured.

Zero-byte objects are valid

S3 clients should send a zero content length and the SHA-256 hash of an empty payload; do not omit signing merely because the body is empty.