<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Connecting storage on back(d)</title><link>https://fernandezvara.github.io/backd/docs/operate/providers/storage/</link><description>Recent content in Connecting storage on back(d)</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://fernandezvara.github.io/backd/docs/operate/providers/storage/index.xml" rel="self" type="application/rss+xml"/><item><title>AWS S3</title><link>https://fernandezvara.github.io/backd/docs/operate/providers/storage/aws-s3/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/providers/storage/aws-s3/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;aws&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;eu-west-1 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# the bucket&amp;#39;s region; the endpoint is derived&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;acme-files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_ACCESS_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_SECRET_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Endpoint&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;https://s3.&amp;lt;region&amp;gt;.amazonaws.com&lt;/code&gt; (derived from &lt;code&gt;region&lt;/code&gt;; if you write it, &lt;code&gt;region&lt;/code&gt; must agree)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Addressing&lt;/td&gt;
 &lt;td&gt;virtual-hosted (&lt;code&gt;&amp;lt;bucket&amp;gt;.s3.&amp;lt;region&amp;gt;.amazonaws.com&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Signed SHA-256 (direct uploads)&lt;/td&gt;
 &lt;td&gt;supported&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Largest single PUT&lt;/td&gt;
 &lt;td&gt;5 GiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Multipart uploads (files above 5 GiB)&lt;/td&gt;
 &lt;td&gt;supported, with a SHA-256 per part&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;backd storage check&lt;/code&gt; reads&lt;/td&gt;
 &lt;td&gt;CORS and default encryption&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="setting-it-up"&gt;Setting it up&lt;a class="hd-anchor" href="#setting-it-up" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create the bucket&lt;/strong&gt; in the region you will name, with &lt;em&gt;Block all public access&lt;/em&gt; on. The bucket is always private.&lt;/p&gt;</description></item><item><title>MinIO</title><link>https://fernandezvara.github.io/backd/docs/operate/providers/storage/minio/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/providers/storage/minio/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;minio&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://minio.internal.example:9000 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# http://minio:9000 only with BACKD_DEV=true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# public_endpoint: http://localhost:9000 # when browsers reach MinIO at another address&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;acme-files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_ACCESS_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_SECRET_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Endpoint&lt;/td&gt;
 &lt;td&gt;any &lt;code&gt;https://&amp;lt;host&amp;gt;[:port]&lt;/code&gt; (plain &lt;code&gt;http&lt;/code&gt; only when &lt;code&gt;BACKD_DEV=true&lt;/code&gt;, for development)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Addressing&lt;/td&gt;
 &lt;td&gt;path style (&lt;code&gt;&amp;lt;endpoint&amp;gt;/&amp;lt;bucket&amp;gt;/…&lt;/code&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Region&lt;/td&gt;
 &lt;td&gt;any; default &lt;code&gt;us-east-1&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Signed SHA-256 (direct uploads)&lt;/td&gt;
 &lt;td&gt;supported&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Multipart uploads (files above 5 GiB)&lt;/td&gt;
 &lt;td&gt;supported, with a SHA-256 per part&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Oldest version tested&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;RELEASE.2025-09-07T16-13-09Z&lt;/code&gt; (the repository&amp;rsquo;s tests run against Chainguard&amp;rsquo;s current build as well)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;backd storage check&lt;/code&gt; reads&lt;/td&gt;
 &lt;td&gt;neither CORS nor encryption (MinIO doesn&amp;rsquo;t expose them to an S3 client): it says so&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="development"&gt;Development&lt;a class="hd-anchor" href="#development" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Images:&lt;/strong&gt; the MinIO project no longer publishes container images (the old &lt;code&gt;minio/minio&lt;/code&gt; and &lt;code&gt;quay.io/minio/minio&lt;/code&gt; repositories stopped being pullable). The repository&amp;rsquo;s stacks use &lt;a href="https://images.chainguard.dev/directory/image/minio/overview"&gt;Chainguard&amp;rsquo;s build&lt;/a&gt; (&lt;code&gt;cgr.dev/chainguard/minio&lt;/code&gt; and &lt;code&gt;cgr.dev/chainguard/minio-client&lt;/code&gt;); both have no shell, so the server can&amp;rsquo;t run a health check and one-shot jobs call &lt;code&gt;mc&lt;/code&gt; directly. You can also build MinIO from its source. &lt;code&gt;backd storage check&lt;/code&gt; tells whether whatever you run behaves.&lt;/p&gt;</description></item><item><title>Cloudflare R2</title><link>https://fernandezvara.github.io/backd/docs/operate/providers/storage/cloudflare-r2/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/providers/storage/cloudflare-r2/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;r2&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;https://&amp;lt;account id&amp;gt;.r2.cloudflarestorage.com &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# no bucket in it&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;acme-files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_ACCESS_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_SECRET_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Endpoint&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;https://&amp;lt;account id&amp;gt;.r2.cloudflarestorage.com&lt;/code&gt; (also &lt;code&gt;.eu.&lt;/code&gt; and &lt;code&gt;.fedramp.&lt;/code&gt; for those jurisdictions). R2&amp;rsquo;s console shows it with the bucket&amp;rsquo;s name after it: write only the host, and the name in &lt;code&gt;bucket&lt;/code&gt;.&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Addressing&lt;/td&gt;
 &lt;td&gt;virtual-hosted&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Region&lt;/td&gt;
 &lt;td&gt;always &lt;code&gt;auto&lt;/code&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Signed SHA-256 (direct uploads)&lt;/td&gt;
 &lt;td&gt;supported: R2 rejects an upload whose digest differs (confirmed by the provider smoke test)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Largest single PUT&lt;/td&gt;
 &lt;td&gt;5 GiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Multipart uploads (files above 5 GiB)&lt;/td&gt;
 &lt;td&gt;supported, with a SHA-256 per part (confirmed by the provider smoke test)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;backd storage check&lt;/code&gt; reads&lt;/td&gt;
 &lt;td&gt;neither CORS nor encryption: it says so&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="setting-it-up"&gt;Setting it up&lt;a class="hd-anchor" href="#setting-it-up" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create the bucket&lt;/strong&gt; in the Cloudflare dashboard (R2 → Create bucket). Keep it private: don&amp;rsquo;t enable public access or a public domain.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create an API token&lt;/strong&gt; (R2 → Manage API tokens) with &lt;em&gt;Object Read &amp;amp; Write&lt;/em&gt; limited to that bucket. R2 shows an &lt;strong&gt;Access Key ID&lt;/strong&gt; and a &lt;strong&gt;Secret Access Key&lt;/strong&gt; once: those are the two secrets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encryption at rest:&lt;/strong&gt; R2 encrypts all objects at rest; there is nothing to set.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CORS&lt;/strong&gt;, needed for &lt;a href="../../../../build/files/transfers/#direct-uploads"&gt;direct uploads&lt;/a&gt; and cross-origin downloads: set it on the bucket (Settings → CORS policy) for your app&amp;rsquo;s origin, with &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;HEAD&lt;/code&gt; and the allowed headers &lt;code&gt;Content-Type&lt;/code&gt; and &lt;code&gt;x-amz-checksum-sha256&lt;/code&gt;. &lt;code&gt;backd storage check&lt;/code&gt; can&amp;rsquo;t read it: try an upload from the app.&lt;/li&gt;
&lt;li&gt;Set the secrets and run &lt;code&gt;backd storage check --realm &amp;lt;realm&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;R2&amp;rsquo;s tokens limit the bucket, not a prefix: the &lt;code&gt;prefix&lt;/code&gt; still keeps each &lt;code&gt;backd&lt;/code&gt; instance&amp;rsquo;s files apart, but a key can reach the whole bucket, so give each instance sharing a bucket a token of its own only if you must trust no instance with another&amp;rsquo;s files; otherwise use a bucket per instance.&lt;/p&gt;</description></item><item><title>DigitalOcean Spaces</title><link>https://fernandezvara.github.io/backd/docs/operate/providers/storage/digitalocean-spaces/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fernandezvara.github.io/backd/docs/operate/providers/storage/digitalocean-spaces/</guid><description>&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;digitalocean&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;nyc3 &lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c"&gt;# the Space&amp;#39;s region; the endpoint is derived&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;acme-files&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;prefix&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;prod&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;access_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_ACCESS_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;secret_key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;secret:STORAGE_SECRET_KEY&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;Endpoint&lt;/td&gt;
 &lt;td&gt;&lt;code&gt;https://&amp;lt;region&amp;gt;.digitaloceanspaces.com&lt;/code&gt; (derived from &lt;code&gt;region&lt;/code&gt;; if you write it, &lt;code&gt;region&lt;/code&gt; must agree)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Addressing&lt;/td&gt;
 &lt;td&gt;virtual-hosted&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Signed SHA-256 (direct uploads)&lt;/td&gt;
 &lt;td&gt;supported (documented in the &lt;a href="https://docs.digitalocean.com/reference/api/spaces/"&gt;Spaces API reference&lt;/a&gt;)&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Largest single PUT&lt;/td&gt;
 &lt;td&gt;5 GiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Multipart uploads (files above 5 GiB)&lt;/td&gt;
 &lt;td&gt;not enabled until the provider smoke test confirms a SHA-256 per part: &lt;code&gt;max_size&lt;/code&gt; stays at 5 GiB&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;backd storage check&lt;/code&gt; reads&lt;/td&gt;
 &lt;td&gt;neither CORS nor encryption: it says so&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="setting-it-up"&gt;Setting it up&lt;a class="hd-anchor" href="#setting-it-up" aria-hidden="true"&gt;#&lt;/a&gt;
&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create the Space&lt;/strong&gt; in the region you will name, with &lt;em&gt;File listing&lt;/em&gt; restricted (private).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create a Spaces access key&lt;/strong&gt; (API → Spaces Keys), scoped to that Space with &lt;em&gt;Read, Write and Delete&lt;/em&gt;. The key and its secret are the two realm secrets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Encryption at rest:&lt;/strong&gt; Spaces encrypts data at rest; there is nothing to set.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CORS&lt;/strong&gt;, needed for &lt;a href="../../../../build/files/transfers/#direct-uploads"&gt;direct uploads&lt;/a&gt; and cross-origin downloads: set it in the Space&amp;rsquo;s Settings for your app&amp;rsquo;s origin with &lt;code&gt;GET&lt;/code&gt;, &lt;code&gt;PUT&lt;/code&gt; and &lt;code&gt;HEAD&lt;/code&gt;, and allow the headers &lt;code&gt;Content-Type&lt;/code&gt; and &lt;code&gt;x-amz-checksum-sha256&lt;/code&gt;. &lt;code&gt;backd storage check&lt;/code&gt; can&amp;rsquo;t read it: try an upload from the app.&lt;/li&gt;
&lt;li&gt;Set the secrets and run &lt;code&gt;backd storage check --realm &amp;lt;realm&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A Spaces key is scoped to a Space, not to a prefix: use a Space per &lt;code&gt;backd&lt;/code&gt; instance, or keep &lt;code&gt;prefix&lt;/code&gt; distinct and accept that a key can reach every prefix of its Space.&lt;/p&gt;</description></item></channel></rss>