cli

AWS CLI

The fastest way to prove an endpoint is real
verified in CIv2.13+AWS CLI documentation ↗

Install

shell
# macOS
brew install awscli

# Linux
curl -fsSL 'https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip' -o awscliv2.zip
unzip -q awscliv2.zip && sudo ./aws/install

Configure

Configure the endpoint, region, credential and bucket in this tool’s vocabulary. Path-style addressing is recommended for dotted bucket names and clients without nested wildcard TLS, but virtual-hosted addressing is also supported.

In AWS CLISet it to
endpoint_urlhttps://s3.canada.popcloud.ca
regioncanada
aws_access_key_idPCAK00EXAMPLEKEYID00
aws_secret_access_key<your secret access key>
s3.addressing_stylepath
Environment
example values
export AWS_ACCESS_KEY_ID=PCAK00EXAMPLEKEYID00
export AWS_SECRET_ACCESS_KEY=<your secret access key>
export AWS_ENDPOINT_URL=https://s3.canada.popcloud.ca
export AWS_REGION=canada
export POPCLOUD_BUCKET=pc-your-org-media

These are example values. Sign in and every snippet on this site fills in with your own endpoint, key and bucket.

shell
# One named profile, and every command below uses it.
aws configure set profile.popcloud.aws_access_key_id     "$AWS_ACCESS_KEY_ID"
aws configure set profile.popcloud.aws_secret_access_key "$AWS_SECRET_ACCESS_KEY"
aws configure set profile.popcloud.region                "$AWS_REGION"
aws configure set profile.popcloud.endpoint_url          "$AWS_ENDPOINT_URL"

# Recommended for predictable custom-endpoint behavior. PopCloud also accepts
# virtual-hosted requests for ordinary single-label bucket names.
aws configure set profile.popcloud.s3.addressing_style   path
# AWS CLI can otherwise fall back to the legacy S3 presigner for a custom
# endpoint. PopCloud accepts SigV4 only, matching modern AWS regions.
aws configure set profile.popcloud.s3.signature_version  s3v4

Use it

Upload an object

shell
aws s3 cp ./local-file.bin "s3://$BUCKET/${PREFIX}key.bin" --profile popcloud

# A whole directory, in parallel, skipping what is already there.
aws s3 sync ./public "s3://$BUCKET/${PREFIX}public/" --profile popcloud

Download an object

shell
aws s3 cp "s3://$BUCKET/${PREFIX}key.bin" ./restored.bin --profile popcloud

List a prefix

shell
aws s3 ls "s3://$BUCKET/${PREFIX}public/" --recursive --human-readable --profile popcloud

Presign a URL

shell
# Anyone holding this URL can read the object until it expires. Seconds; the
# hard maximum is 7 days.
url=$(aws s3 presign "s3://$BUCKET/${PREFIX}key.bin" --expires-in 3600 --profile popcloud)

Delete an object

shell
aws s3 rm "s3://$BUCKET/${PREFIX}key.bin" --profile popcloud

What to watch for

These apply to AWS CLI specifically. The full list covers the platform.

You’ll see
405 MethodNotAllowed from CreateBucket or DeleteBucket — `aws s3 mb`, `mc mb`, or a tool provisioning its own bucket on first run.
Why
Bucket lifecycle belongs to the control plane, which also allocates the storage account, the data-plane key and the CORS rules that come with it. Letting the edge create buckets would create half of one.
Instead
Create buckets in the dashboard, or with `POST /v1/buckets` on the control-plane API. Everything object-level then works normally against that bucket.
You’ll see
405 MethodNotAllowed on PutBucketPolicy, PutBucketLifecycleConfiguration, PutBucketWebsite, PutBucketReplication, PutBucketNotificationConfiguration, PutBucketTagging, PutPublicAccessBlock and their delete counterparts; the matching Get calls return 501 or are refused upstream.
Why
These configure infrastructure behaviour that PopCloud manages itself. Access control is expressed through credential scopes and the bucket's public flag rather than through bucket policies.
Instead
Use credential scopes for access control (permissions plus a bucket allowlist, optionally with an expiry), the bucket's public flag for anonymous reads, and the control plane for CORS. Tools that reconcile bucket configuration — Terraform's `aws_s3_bucket` in particular — must be limited to object-level resources.
You’ll see
501 NotImplemented when a request sets x-amz-storage-class to GLACIER, STANDARD_IA, INTELLIGENT_TIERING or similar.
Why
Storage economics are expressed as a bucket's tier (hot or cool), chosen when the bucket is created, rather than per object.
Instead
Leave the storage class unset. If your tool sets one by default, point it at STANDARD. To store colder data, create a cool-tier bucket and write there. RestoreObject does not exist either, because nothing is ever archived.

How this page is kept true

Every snippet above was extracted from examples/cli/aws-cli, a program that uploads, downloads, compares bytes, lists, presigns and cleans up after itself. It runs in CI against a live sandbox organisation via make docs-verify-cli. If it stops passing, this page is wrong and we treat that as a bug in the product.

A few snippets on this page are marked not run in CI — they need a browser, a second provider, or a configuration change the sandbox cannot make. Those are reviewed by hand.

Not yet run against the live sandbox — the runner is wired, the first verified run stamps this line.