Configuration
Configuring the Shelby S3 Gateway
The S3 Gateway supports two configuration formats:
- YAML — Simple, supports reads and writes (add
aptosPrivateKeyto enable writes) - TypeScript — For advanced or dynamic configuration (custom providers, programmatic setup)
YAML Configuration
Create a shelby.config.yaml file and run with --config:
npx @shelby-protocol/s3-gateway --config shelby.config.yamlFull Example
# Network configuration (required)
network:
name: shelbynet # "shelbynet" or "local"
rpcEndpoint: https://api.shelbynet.shelby.xyz/shelby
aptosFullnode: https://api.shelbynet.shelby.xyz/v1
aptosIndexer: https://api.shelbynet.shelby.xyz/v1/graphql
apiKey: <YOUR_API_KEY> # Optional
# Server settings
server:
host: localhost # Bind address (default: localhost)
port: 9000 # Listen port (default: 9000)
region: shelbyland # S3 region for signing (default: shelbyland)
verbose: false # Enable request logging (default: false)
# S3 credentials for request signing (optional — defaults to dev credentials)
credentials:
- accessKeyId: AKIAIOSFODNN7EXAMPLE
secretAccessKey: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
aptosPrivateKey: <YOUR_APTOS_PRIVATE_KEY> # Enables uploads & deletes
# Shelby accounts to expose as S3 buckets (required)
# The public alias must follow the Amazon S3 bucket naming rules.
buckets:
- name: clickhouse-data
accountAddress: "<YOUR_SHELBY_ACCOUNT_ADDRESS>"To enable write operations (uploads, deletes), add aptosPrivateKey to a credential entry.
Without it, the credential only permits read operations.
Minimal Example
network:
name: shelbynet
rpcEndpoint: https://api.shelbynet.shelby.xyz/shelby
aptosFullnode: https://api.shelbynet.shelby.xyz/v1
aptosIndexer: https://api.shelbynet.shelby.xyz/v1/graphql
apiKey: <YOUR_API_KEY>
buckets:
- name: clickhouse-data
accountAddress: "<YOUR_SHELBY_ACCOUNT_ADDRESS>"With the minimal config, the gateway uses default development credentials
and supports read-only access. Add a credentials section with aptosPrivateKey
to enable writes.
Configuration Reference
Network Options (Required)
| Option | Type | Default | Description |
|---|---|---|---|
name | "shelbynet" | "local" | "shelbynet" | Network name |
rpcEndpoint | string | Network default | Shelby RPC endpoint URL |
aptosFullnode | string | - | Aptos fullnode URL |
aptosIndexer | string | - | Aptos indexer URL |
apiKey | string | - | API key for authentication |
Server Options
| Option | Type | Default | Description |
|---|---|---|---|
host | string | "localhost" | Bind address for the server |
port | number | 9000 | Port to listen on |
region | string | "shelbyland" | S3 region for SigV4 signing |
verbose | boolean | false | Enable detailed request logging |
The region setting must match what your S3 clients use for signing requests.
Some tools require a standard AWS region like "us-east-1".
Credentials
Array of S3 credential objects. If not specified, default dev credentials are used.
These are not AWS credentials. They are shared secrets used for S3 SigV4 request signing between your S3 client and the gateway. The same values must be configured in both the gateway config and your S3 client (rclone, boto3, etc.). You can use any values you want — the defaults work for local development.
| Field | Type | Description |
|---|---|---|
accessKeyId | string | Public identifier for the credential (used in the Authorization header) |
secretAccessKey | string | Shared secret used for HMAC request signing (never sent over the network) |
aptosPrivateKey | string (optional) | Your Aptos Ed25519 private key. If you've set up the Shelby CLI, copy your private_key from ~/.shelby/config.yaml. Accepts the ed25519-priv-0x... format or raw hex (0x...). Enables write operations (uploads, deletes) for this credential |
Buckets (Required)
Array of Shelby accounts to expose as S3 buckets. Use an alias when connecting an S3 client:
buckets:
- name: clickhouse-data
accountAddress: "<YOUR_SHELBY_ACCOUNT_ADDRESS>"The name is the public bucket name sent by the client. It must follow the
Amazon S3 general-purpose bucket naming rules,
including the 3–63 character limit. The accountAddress is the Shelby account
that owns the bucket's objects and must match the Aptos signer for writes and deletes.
Each configured public name and account address must be unique.
If server-side encrypted objects were previously written through an address-style
bucket, accountAddress must use the exact same address spelling as the historical
bucket path. The encryption identity is byte-sensitive, including zero-padding and case.
Legacy address-style buckets remain supported:
buckets:
- "<YOUR_SHELBY_ACCOUNT_ADDRESS>"Account addresses must be quoted because YAML interprets unquoted 0x… values as numbers.
Environment Variables
| Variable | Default | Description |
|---|---|---|
PORT | 9000 | Server port (overrides config file) |
HTTPS | - | Set to true to enable HTTPS |
CLI Options
| Option | Description |
|---|---|
-c, --config <path> | Path to config file |
-p, --port <port> | Port to listen on (overrides config) |
-h, --help | Show help message |
Advanced: TypeScript Configuration
For dynamic configuration or custom credential/bucket providers, use a TypeScript config.
A ready-to-use example that reads your existing ~/.shelby/config.yaml is included in the
package at example.shelby.config.ts. To use it:
npx @shelby-protocol/s3-gateway --config example.shelby.config.tsOr create your own:
import { Account, Ed25519PrivateKey, Network } from "@aptos-labs/ts-sdk";
import {
defineConfig,
StaticCredentialProvider,
StaticBucketResolver,
} from "@shelby-protocol/s3-gateway";
const privateKey = new Ed25519PrivateKey(process.env.APTOS_PRIVATE_KEY!);
const aptosSigner = Account.fromPrivateKey({ privateKey });
const signerAddress = aptosSigner.accountAddress.toString();
const bucketResolver = new StaticBucketResolver({
buckets: [
{
name: "clickhouse-data",
accountAddress: signerAddress,
},
],
});
export default defineConfig({
shelby: {
network: Network.SHELBYNET,
rpc: {
baseUrl: "https://api.shelbynet.shelby.xyz/shelby",
},
},
server: {
port: 9000,
region: "shelbyland",
},
credentialProvider: new StaticCredentialProvider({
credentials: {
AKIAIOSFODNN7EXAMPLE: {
secretKey: "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
aptosSigner, // Enables write operations (uploads, deletes)
},
},
}),
bucketProvider: bucketResolver,
bucketResolver,
});The aptosSigner field is what enables write operations. Without it, the credential
only permits reads. In YAML configs, set aptosPrivateKey to achieve the same result.
Custom Providers
Implement custom providers for dynamic credential or bucket lookup. A custom
BucketResolver translates public bucket names to Shelby account addresses;
the BucketProvider supplies the names returned by ListBuckets.
import {
defineConfig,
StaticBucketResolver,
} from "@shelby-protocol/s3-gateway";
import type { CredentialProvider } from "@shelby-protocol/s3-gateway";
// Custom credential provider (e.g., from database)
class DatabaseCredentialProvider implements CredentialProvider {
async getCredential(accessKeyId: string) {
const result = await db.query(
"SELECT secret_key FROM credentials WHERE access_key_id = ?",
[accessKeyId]
);
return result ? { accessKeyId, secretAccessKey: result.secret_key } : undefined;
}
async listAccessKeyIds() {
const results = await db.query("SELECT access_key_id FROM credentials");
return results.map((r) => r.access_key_id);
}
async refresh() {
// Refresh cache if needed
}
}
const bucketResolver = new StaticBucketResolver({
buckets: [
{
name: "clickhouse-data",
accountAddress: "0x...",
},
],
});
export default defineConfig({
shelby: { /* ... */ },
credentialProvider: new DatabaseCredentialProvider(),
bucketProvider: bucketResolver,
bucketResolver,
});For dynamic aliases, replace StaticBucketResolver with an implementation of
both BucketResolver and BucketProvider backed by your bucket directory.
In a replicated deployment, both providers must use a shared, authoritative data store. A gateway-local alias database is sufficient only for a single self-hosted instance; otherwise aliases can resolve differently across replicas or disappear after a restart.