Storage
Configure cloud storage providers and perform file operations across AWS S3, Google Cloud Storage, and Azure Blob Storage through a unified interface.
Quick Example
Use the storage API on the Ductape instance. Initialize Ductape with your access key:
- TypeScript
- Java
- Go
- .NET
import Ductape from '@ductape/sdk';
const ductape = new Ductape({
accessKey: 'your-access-key',
});
// Upload a file
const result = await ductape.storage.upload({
storage: 'main-storage',
fileName: 'documents/report.pdf',
buffer: fileBuffer,
mimeType: 'application/pdf',
});
console.log('File URL:', result.url);
import app.ductape.sdk.Ductape;
import app.ductape.sdk.core.EnvType;
import app.ductape.sdk.core.RequestContext;
RequestContext auth = new RequestContext(null, null, null, null, 'your-access-key');
Ductape ductape = new Ductape(EnvType.PRODUCTION, auth);
// Upload a file
Map<String, Object> result = ductape.storage.upload(Map.of(
"storage", "main-storage",
"fileName", "documents/report.pdf",
buffer: fileBuffer,
"mimeType", "application/pdf"
));
System.out.println('File URL:', result.url);
import (
"context"
"github.com/ductape/ductape/sdk/go/core"
ductapesdk "github.com/ductape/ductape/sdk/go/ductape"
)
auth := core.NewRequestContext("", "", "", "", 'your-access-key')
client, err := ductapesdk.New(core.EnvProduction, auth)
if err != nil {
return err
}
// Upload a file
result := client.storage.upload({
"storage": "main-storage",
"fileName": "documents/report.pdf",
buffer: fileBuffer,
"mimeType": "application/pdf",
});
fmt.Println('File URL:', result.url);
using Ductape.Sdk;
using Ductape.Sdk.Core;
var auth = new RequestContext(null, null, null, null, 'your-access-key', null);
var ductape = new Ductape(EnvType.Production, auth);
// Upload a file
var result = await ductape.storage.upload({
["storage"] = "main-storage",
["fileName"] = "documents/report.pdf",
buffer: fileBuffer,
["mimeType"] = "application/pdf",
});
Console.WriteLine('File URL:', result.url);
Supported Providers
| Provider | Enum Value | Description |
|---|---|---|
| Amazon S3 | StorageProviders.AWS | AWS S3 buckets |
| Google Cloud | StorageProviders.GCP | Google Cloud Storage |
| Azure | StorageProviders.AZURE | Azure Blob Storage |
File Operations
Upload a File
- TypeScript
- Java
- Go
- .NET
const result = await ductape.storage.upload({
storage: 'main-storage',
fileName: 'images/photo.jpg',
buffer: imageBuffer, // Buffer or string
mimeType: 'image/jpeg', // Optional
});
// Returns { success: true, url: '...', fileName: '...', mimeType: '...' }
Map<String, Object> result = ductape.storage.upload(Map.of(
"storage", "main-storage",
"fileName", "images/photo.jpg",
buffer: imageBuffer, // Buffer or string
"mimeType", "image/jpeg", // Optional
));
// Returns Map.of( "success", true, "url", "...", "fileName", "...", "mimeType", "..." )
result := client.storage.upload({
"storage": "main-storage",
"fileName": "images/photo.jpg",
buffer: imageBuffer, // Buffer or string
"mimeType": "image/jpeg", // Optional
});
// Returns { "success": true, "url": "...", "fileName": "...", "mimeType": "..." }
var result = await ductape.storage.upload({
["storage"] = "main-storage",
["fileName"] = "images/photo.jpg",
buffer: imageBuffer, // Buffer or string
["mimeType"] = "image/jpeg", // Optional
});
// Returns { ["success"] = true, ["url"] = "...", ["fileName"] = "...", ["mimeType"] = "..." }
Download a File
- TypeScript
- Java
- Go
- .NET
const result = await ductape.storage.download({
storage: 'main-storage',
fileName: 'documents/report.pdf',
});
// Returns { success: true, data: Buffer, fileName?: string, size?: number, mimeType?: string }
Map<String, Object> result = ductape.storage.download(Map.of(
"storage", "main-storage",
"fileName", "documents/report.pdf"
));
// Returns Map.of( "success", true, data: Buffer, fileName?: string, size?: number, mimeType?: string )
result := client.storage.download({
"storage": "main-storage",
"fileName": "documents/report.pdf",
});
// Returns { "success": true, data: Buffer, fileName?: string, size?: number, mimeType?: string }
var result = await ductape.storage.download({
["storage"] = "main-storage",
["fileName"] = "documents/report.pdf",
});
// Returns { ["success"] = true, data: Buffer, fileName?: string, size?: number, mimeType?: string }
Remove a File
Use storage.remove() to delete a file:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.storage.remove({
storage: 'main-storage',
fileName: 'documents/old-report.pdf',
});
// Returns { success: true, fileName?: string }
Map<String, Object> result = ductape.storage.remove(Map.of(
"storage", "main-storage",
"fileName", "documents/old-report.pdf"
));
// Returns Map.of( "success", true, fileName?: string )
result := client.storage.remove({
"storage": "main-storage",
"fileName": "documents/old-report.pdf",
});
// Returns { "success": true, fileName?: string }
var result = await ductape.storage.remove({
["storage"] = "main-storage",
["fileName"] = "documents/old-report.pdf",
});
// Returns { ["success"] = true, fileName?: string }
List Files
Use storage.listFiles() for paginated listing:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.storage.listFiles({
storage: 'main-storage',
prefix: 'documents/', // Optional
limit: 100, // Optional (default: 100, max: 1000)
continuationToken: '...', // Optional: for next page
});
// Returns { success: true, files: [...], limit?, nextToken?, hasMore }
Map<String, Object> result = ductape.storage.listFiles(Map.of(
"storage", "main-storage",
"prefix", "documents/", // Optional
"limit", 100, // Optional ("default", 100, "max", 1000)
"continuationToken", "...", // Optional: for next page
));
// Returns Map.of( "success", true, files: [...], limit?, nextToken?, hasMore )
result := client.storage.listFiles({
"storage": "main-storage",
"prefix": "documents/", // Optional
"limit": 100, // Optional ("default": 100, "max": 1000)
"continuationToken": "...", // Optional: for next page
});
// Returns { "success": true, files: [...], limit?, nextToken?, hasMore }
var result = await ductape.storage.listFiles({
["storage"] = "main-storage",
["prefix"] = "documents/", // Optional
["limit"] = 100, // Optional (["default"] = 100, ["max"] = 1000)
["continuationToken"] = "...", // Optional: for next page
});
// Returns { ["success"] = true, files: [...], limit?, nextToken?, hasMore }
Pagination Example
Use continuationToken and nextToken for cursor-based pagination:
- TypeScript
- Java
- Go
- .NET
async function getAllFiles(product: string, env: string, storageTag: string) {
const allFiles = [];
let continuationToken: string | undefined;
do {
const result = await ductape.storage.listFiles({
product,
env,
storage: storageTag,
limit: 100,
continuationToken,
});
allFiles.push(...result.files);
continuationToken = result.nextToken;
} while (continuationToken);
return allFiles;
}
async function getAllFiles(product: string, env: string, storageTag: string) Map.of(
Map<String, Object> allFiles = [];
Map<String, Object> continuationToken: string | undefined;
do Map.of(
Map<String, Object> result = ductape.storage.listFiles(Map.of(
product,
env,
storage: storageTag,
"limit", 100,
continuationToken
));
allFiles.push(...result.files);
continuationToken = result.nextToken;
) while (continuationToken);
return allFiles;
)
async function getAllFiles(product: string, env: string, storageTag: string) {
allFiles := [];
let continuationToken: string | undefined;
do {
result := client.storage.listFiles({
product,
env,
storage: storageTag,
"limit": 100,
continuationToken,
});
allFiles.push(...result.files);
continuationToken = result.nextToken;
} while (continuationToken);
return allFiles;
}
async function getAllFiles(product: string, env: string, storageTag: string) {
var allFiles = [];
var continuationToken: string | undefined;
do {
var result = await ductape.storage.listFiles({
product,
env,
storage: storageTag,
["limit"] = 100,
continuationToken,
});
allFiles.push(...result.files);
continuationToken = result.nextToken;
} while (continuationToken);
return allFiles;
}
Get Storage Statistics
Get file counts and sizes without loading all files:
- TypeScript
- Java
- Go
- .NET
const stats = await ductape.storage.stats({
storage: 'main-storage',
prefix: 'documents/', // Optional
});
// Returns { success: true, totalFiles, totalSize, byType: { image, video, audio, document, archive, other } }
Map<String, Object> stats = ductape.storage.stats(Map.of(
"storage", "main-storage",
"prefix", "documents/", // Optional
));
// Returns Map.of( "success", true, totalFiles, totalSize, byType: Map.of( image, video, audio, document, archive, other ) )
stats := client.storage.stats({
"storage": "main-storage",
"prefix": "documents/", // Optional
});
// Returns { "success": true, totalFiles, totalSize, byType: { image, video, audio, document, archive, other } }
var stats = await ductape.storage.stats({
["storage"] = "main-storage",
["prefix"] = "documents/", // Optional
});
// Returns { ["success"] = true, totalFiles, totalSize, byType: { image, video, audio, document, archive, other } }
Generate Signed URL
Create temporary URLs for secure file access:
- TypeScript
- Java
- Go
- .NET
// Read access (download)
const result = await ductape.storage.getSignedUrl({
storage: 'main-storage',
fileName: 'documents/report.pdf',
expiresIn: 3600, // Seconds (default: 3600)
action: 'read', // 'read' or 'write'
});
// Write access (upload)
const uploadUrl = await ductape.storage.getSignedUrl({
storage: 'main-storage',
fileName: 'uploads/new-file.pdf',
expiresIn: 600,
action: 'write',
});
// Read access (download)
Map<String, Object> result = ductape.storage.getSignedUrl(Map.of(
"storage", "main-storage",
"fileName", "documents/report.pdf",
"expiresIn", 3600, // Seconds ("default", 3600)
"action", "read", // 'read' or 'write'
));
// Write access (upload)
Map<String, Object> uploadUrl = ductape.storage.getSignedUrl(Map.of(
"storage", "main-storage",
"fileName", "uploads/new-file.pdf",
"expiresIn", 600,
"action", "write"
));
// Read access (download)
result := client.storage.getSignedUrl({
"storage": "main-storage",
"fileName": "documents/report.pdf",
"expiresIn": 3600, // Seconds ("default": 3600)
"action": "read", // 'read' or 'write'
});
// Write access (upload)
uploadUrl := client.storage.getSignedUrl({
"storage": "main-storage",
"fileName": "uploads/new-file.pdf",
"expiresIn": 600,
"action": "write",
});
// Read access (download)
var result = await ductape.storage.getSignedUrl({
["storage"] = "main-storage",
["fileName"] = "documents/report.pdf",
["expiresIn"] = 3600, // Seconds (["default"] = 3600)
["action"] = "read", // 'read' or 'write'
});
// Write access (upload)
var uploadUrl = await ductape.storage.getSignedUrl({
["storage"] = "main-storage",
["fileName"] = "uploads/new-file.pdf",
["expiresIn"] = 600,
["action"] = "write",
});
Dispatch Storage Jobs
Queue storage operations as background jobs:
- TypeScript
- Java
- Go
- .NET
const result = await ductape.storage.dispatch({
storage: 'main-storage',
operation: 'upload',
input: {
fileName: 'reports/monthly.pdf',
buffer: reportBuffer,
mimeType: 'application/pdf',
},
schedule: { start_at: Date.now() + 60000 }, // Optional: delay 1 minute
});
// Returns { job_id, status, scheduled_at, recurring?, next_run_at? }
Map<String, Object> result = ductape.storage.dispatch(Map.of(
"storage", "main-storage",
"operation", "upload",
input: Map.of(
"fileName", "reports/monthly.pdf",
buffer: reportBuffer,
"mimeType", "application/pdf"
),
schedule: Map.of( start_at: Date.now() + 60000 ), // Optional: delay 1 minute
));
// Returns Map.of( job_id, status, scheduled_at, recurring?, next_run_at? )
result := client.storage.dispatch({
"storage": "main-storage",
"operation": "upload",
input: {
"fileName": "reports/monthly.pdf",
buffer: reportBuffer,
"mimeType": "application/pdf",
},
schedule: { start_at: Date.now() + 60000 }, // Optional: delay 1 minute
});
// Returns { job_id, status, scheduled_at, recurring?, next_run_at? }
var result = await ductape.storage.dispatch({
["storage"] = "main-storage",
["operation"] = "upload",
input: {
["fileName"] = "reports/monthly.pdf",
buffer: reportBuffer,
["mimeType"] = "application/pdf",
},
schedule: { start_at: Date.now() + 60000 }, // Optional: delay 1 minute
});
// Returns { job_id, status, scheduled_at, recurring?, next_run_at? }
Managing Storage Configurations
Create, list, fetch, update, and delete storage configs with the CRUD API. See Storage CRUD for full examples.
- TypeScript
- Java
- Go
- .NET
// Create (cloud-linked)
await ductape.storage.create({ product: 'my-product', name: 'App Storage', tag: 'app-storage', envs: [...] });
// List / fetch / update / delete
await ductape.storage.list('my-product');
await ductape.storage.fetch('my-product', 'app-storage');
await ductape.storage.update('my-product', 'app-storage', { envs: [...] });
await ductape.storage.delete('my-product', 'app-storage');
// Create (cloud-linked)
ductape.storage.create(Map.of( "product", "my-product", "name", "App Storage", "tag", "app-storage", envs: [...] ));
// List / fetch / update / delete
ductape.storage.list('my-product');
ductape.storage.fetch('my-product', 'app-storage');
ductape.storage.update('my-product', 'app-storage', Map.of( envs: [...] ));
ductape.storage.delete('my-product', 'app-storage');
// Create (cloud-linked)
client.storage.create({ "product": "my-product", "name": "App Storage", "tag": "app-storage", envs: [...] });
// List / fetch / update / delete
client.storage.list('my-product');
client.storage.fetch('my-product', 'app-storage');
client.storage.update('my-product', 'app-storage', { envs: [...] });
client.storage.delete('my-product', 'app-storage');
// Create (cloud-linked)
await ductape.storage.create({ ["product"] = "my-product", ["name"] = "App Storage", ["tag"] = "app-storage", envs: [...] });
// List / fetch / update / delete
await ductape.storage.list('my-product');
await ductape.storage.fetch('my-product', 'app-storage');
await ductape.storage.update('my-product', 'app-storage', { envs: [...] });
await ductape.storage.delete('my-product', 'app-storage');
Creating Storage Configurations
Create storage with manual credentials or link a workspace cloud account by tag.
For cloud-linked storage, check available storage classes first:
- TypeScript
- Java
- Go
- .NET
const tiers = await ductape.cloud.tiers.list({ provider: 'aws', resource_type: 'storage' });
// tiers[0].tiers → [{ name: 's3-standard', label: 'Standard', est_cost_per_month: 0.023 }, …]
Map<String, Object> tiers = ductape.cloud.tiers.list(Map.of( "provider", "aws", "resource_type", "storage" ));
// tiers[0].tiers → [Map.of( "name", "s3-standard", "label", "Standard", "est_cost_per_month", 0.023 ), …]
tiers := client.cloud.tiers.list({ "provider": "aws", "resource_type": "storage" });
// tiers[0].tiers → [{ "name": "s3-standard", "label": "Standard", "est_cost_per_month": 0.023 }, …]
var tiers = await ductape.cloud.tiers.list({ ["provider"] = "aws", ["resource_type"] = "storage" });
// tiers[0].tiers → [{ ["name"] = "s3-standard", ["label"] = "Standard", ["est_cost_per_month"] = 0.023 }, …]
- TypeScript
- Java
- Go
- .NET
import { StorageProviders } from '@ductape/sdk/types';
// Cloud-linked (recommended)
await ductape.storage.create({
product: 'my-product',
name: 'App Storage',
tag: 'app-storage',
envs: [{
slug: 'prd',
type: StorageProviders.AWS,
config: {
cloud: 'prod_aws',
bucketName: 'my-prod-bucket',
region: 'us-east-1',
tier: 's3-standard', // from cloud.tiers.list() — controls storage class
},
}],
});
// Manual credentials
await ductape.storage.create({
name: 'App Storage',
tag: 'app-storage',
envs: [
{
slug: 'prd',
type: StorageProviders.AWS,
config: {
bucketName: 'my-prod-bucket',
region: 'us-east-1',
accessKeyId: process.env.AWS_ACCESS_KEY,
secretAccessKey: process.env.AWS_SECRET_KEY,
},
},
],
});
// Cloud-linked (recommended)
ductape.storage.create(Map.of(
"product", "my-product",
"name", "App Storage",
"tag", "app-storage",
envs: [Map.of(
"slug", "prd",
type: StorageProviders.AWS,
config: Map.of(
"cloud", "prod_aws",
"bucketName", "my-prod-bucket",
"region", "us-east-1",
"tier", "s3-standard", // from cloud.tiers.list() — controls storage class
)
)]
));
// Manual credentials
ductape.storage.create(Map.of(
"name", "App Storage",
"tag", "app-storage",
envs: [
Map.of(
"slug", "prd",
type: StorageProviders.AWS,
config: Map.of(
"bucketName", "my-prod-bucket",
"region", "us-east-1",
accessKeyId: System.getenv("AWS_ACCESS_KEY"),
secretAccessKey: System.getenv("AWS_SECRET_KEY")
)
),
]
));
// Cloud-linked (recommended)
client.storage.create({
"product": "my-product",
"name": "App Storage",
"tag": "app-storage",
envs: [{
"slug": "prd",
type: StorageProviders.AWS,
config: {
"cloud": "prod_aws",
"bucketName": "my-prod-bucket",
"region": "us-east-1",
"tier": "s3-standard", // from cloud.tiers.list() — controls storage class
},
}],
});
// Manual credentials
client.storage.create({
"name": "App Storage",
"tag": "app-storage",
envs: [
{
"slug": "prd",
type: StorageProviders.AWS,
config: {
"bucketName": "my-prod-bucket",
"region": "us-east-1",
accessKeyId: os.Getenv("AWS_ACCESS_KEY"),
secretAccessKey: os.Getenv("AWS_SECRET_KEY"),
},
},
],
});
// Cloud-linked (recommended)
await ductape.storage.create({
["product"] = "my-product",
["name"] = "App Storage",
["tag"] = "app-storage",
envs: [{
["slug"] = "prd",
type: StorageProviders.AWS,
config: {
["cloud"] = "prod_aws",
["bucketName"] = "my-prod-bucket",
["region"] = "us-east-1",
["tier"] = "s3-standard", // from cloud.tiers.list() — controls storage class
},
}],
});
// Manual credentials
await ductape.storage.create({
["name"] = "App Storage",
["tag"] = "app-storage",
envs: [
{
["slug"] = "prd",
type: StorageProviders.AWS,
config: {
["bucketName"] = "my-prod-bucket",
["region"] = "us-east-1",
accessKeyId: Environment.GetEnvironmentVariable("AWS_ACCESS_KEY"),
secretAccessKey: Environment.GetEnvironmentVariable("AWS_SECRET_KEY"),
},
},
],
});
See Cloud-linked components for the full AWS / GCP / Azure provisioning matrix, tier reference, and update flows.
Updating Storage
- TypeScript
- Java
- Go
- .NET
await ductape.storage.update('my-product', 'app-storage', {
envs: [{
slug: 'prd',
type: StorageProviders.GCP,
config: {
cloud: 'gcp_prod',
bucketName: 'my-dev-bucket',
location: 'US',
},
}],
});
ductape.storage.update('my-product', 'app-storage', Map.of(
envs: [Map.of(
"slug", "prd",
type: StorageProviders.GCP,
config: Map.of(
"cloud", "gcp_prod",
"bucketName", "my-dev-bucket",
"location", "US"
)
)]
));
client.storage.update('my-product', 'app-storage', {
envs: [{
"slug": "prd",
type: StorageProviders.GCP,
config: {
"cloud": "gcp_prod",
"bucketName": "my-dev-bucket",
"location": "US",
},
}],
});
await ductape.storage.update('my-product', 'app-storage', {
envs: [{
["slug"] = "prd",
type: StorageProviders.GCP,
config: {
["cloud"] = "gcp_prod",
["bucketName"] = "my-dev-bucket",
["location"] = "US",
},
}],
});
Listing and Fetching Storage
- TypeScript
- Java
- Go
- .NET
// List all storage configs for a product
const providers = await ductape.storage.list('my-product');
// Fetch a single storage by tag
const provider = await ductape.storage.fetch('my-product', 'app-storage');
// List all storage configs for a product
Map<String, Object> providers = ductape.storage.list('my-product');
// Fetch a single storage by tag
Map<String, Object> provider = ductape.storage.fetch('my-product', 'app-storage');
// List all storage configs for a product
providers := client.storage.list('my-product');
// Fetch a single storage by tag
provider := client.storage.fetch('my-product', 'app-storage');
// List all storage configs for a product
var providers = await ductape.storage.list('my-product');
// Fetch a single storage by tag
var provider = await ductape.storage.fetch('my-product', 'app-storage');
API Reference
ductape.storage Methods
| Method | Description |
|---|---|
create(data) | Create a storage config (data includes product, name, tag, envs) |
list(product) | List all storage configs for a product |
fetch(product, tag) | Fetch a storage config by tag |
update(product, tag, data) | Update a storage config |
delete(product, tag) | Delete a storage config |
upload(options) | Upload a file |
download(options) | Download a file |
remove(options) | Remove (delete) a file |
listFiles(options) | List files with pagination |
getSignedUrl(options) | Generate a temporary signed URL |
stats(options) | Get file counts and sizes by type |
dispatch(options) | Queue a storage operation as a job |
testConnection(options) | Test storage provider connectivity |
For reading a file from local disk (e.g. before upload), use ductape.storage.files.read(path).
Error Handling
- TypeScript
- Java
- Go
- .NET
import { StorageError } from '@ductape/sdk';
try {
const result = await ductape.storage.upload({ ... });
} catch (error) {
if (error instanceof StorageError) {
console.log('Error code:', error.code);
console.log('Message:', error.message);
}
}
import Map.of( StorageError ) from '@ductape/sdk';
try Map.of(
Map<String, Object> result = ductape.storage.upload(Map.of( ... ));
) catch (error) Map.of(
if (error instanceof StorageError) Map.of(
System.out.println('Error "code", ", error.code);
System.out.println("Message:', error.message);
)
)
import { StorageError } from '@ductape/sdk';
try {
result := client.storage.upload({ ... });
} catch (error) {
if (error instanceof StorageError) {
fmt.Println('Error "code": ", error.code);
fmt.Println("Message:', error.message);
}
}
import { StorageError } from '@ductape/sdk';
try {
var result = await ductape.storage.upload({ ... });
} catch (error) {
if (error instanceof StorageError) {
Console.WriteLine('Error ["code"] = ", error.code);
Console.WriteLine("Message:', error.message);
}
}
Provider Configuration
AWS S3
- TypeScript
- Java
- Go
- .NET
{
slug: 'prd',
type: StorageProviders.AWS,
config: {
bucketName: 'your-bucket-name',
accessKeyId: 'your-access-key-id',
secretAccessKey: 'your-secret-access-key',
region: 'us-east-1'
}
}
Map.of(
"slug", "prd",
type: StorageProviders.AWS,
config: Map.of(
"bucketName", "your-bucket-name",
"accessKeyId", "your-access-key-id",
"secretAccessKey", "your-secret-access-key",
"region", "us-east-1"
)
)
{
"slug": "prd",
type: StorageProviders.AWS,
config: {
"bucketName": "your-bucket-name",
"accessKeyId": "your-access-key-id",
"secretAccessKey": "your-secret-access-key",
"region": "us-east-1"
}
}
{
["slug"] = "prd",
type: StorageProviders.AWS,
config: {
["bucketName"] = "your-bucket-name",
["accessKeyId"] = "your-access-key-id",
["secretAccessKey"] = "your-secret-access-key",
["region"] = "us-east-1"
}
}
| Field | Description |
|---|---|
bucketName | The name of the S3 bucket |
accessKeyId | AWS access key ID |
secretAccessKey | AWS secret access key |
region | AWS region where the bucket is hosted |
Google Cloud Storage
- TypeScript
- Java
- Go
- .NET
{
slug: 'prd',
type: StorageProviders.GCP,
config: {
bucketName: 'your-gcp-bucket',
config: {
type: 'service_account',
project_id: 'your-project-id',
private_key_id: 'key-id',
private_key: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n',
client_email: 'service-account@project.iam.gserviceaccount.com',
client_id: '123456789',
auth_uri: 'https://accounts.google.com/o/oauth2/auth',
token_uri: 'https://oauth2.googleapis.com/token',
auth_provider_x509_cert_url: 'https://www.googleapis.com/oauth2/v1/certs',
client_x509_cert_url: 'https://www.googleapis.com/robot/v1/metadata/x509/...',
universe_domain: 'googleapis.com',
},
},
}
Map.of(
"slug", "prd",
type: StorageProviders.GCP,
config: Map.of(
"bucketName", "your-gcp-bucket",
config: Map.of(
"type", "service_account",
"project_id", "your-project-id",
"private_key_id", "key-id",
"private_key", "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email", "service-account@project.iam.gserviceaccount.com",
"client_id", "123456789",
"auth_uri", "https://accounts.google.com/o/oauth2/auth",
"token_uri", "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url", "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url", "https://www.googleapis.com/robot/v1/metadata/x509/...",
"universe_domain", "googleapis.com"
)
)
)
{
"slug": "prd",
type: StorageProviders.GCP,
config: {
"bucketName": "your-gcp-bucket",
config: {
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "key-id",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "service-account@project.iam.gserviceaccount.com",
"client_id": "123456789",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/...",
"universe_domain": "googleapis.com",
},
},
}
{
["slug"] = "prd",
type: StorageProviders.GCP,
config: {
["bucketName"] = "your-gcp-bucket",
config: {
["type"] = "service_account",
["project_id"] = "your-project-id",
["private_key_id"] = "key-id",
["private_key"] = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
["client_email"] = "service-account@project.iam.gserviceaccount.com",
["client_id"] = "123456789",
["auth_uri"] = "https://accounts.google.com/o/oauth2/auth",
["token_uri"] = "https://oauth2.googleapis.com/token",
["auth_provider_x509_cert_url"] = "https://www.googleapis.com/oauth2/v1/certs",
["client_x509_cert_url"] = "https://www.googleapis.com/robot/v1/metadata/x509/...",
["universe_domain"] = "googleapis.com",
},
},
}
| Field | Description |
|---|---|
bucketName | The name of the GCP storage bucket |
config | Service account credentials object (from GCP Console JSON key file) |
Azure Blob Storage
- TypeScript
- Java
- Go
- .NET
{
slug: 'prd',
type: StorageProviders.AZURE,
config: {
containerName: 'your-container-name',
connectionString: 'your-connection-string',
},
}
Map.of(
"slug", "prd",
type: StorageProviders.AZURE,
config: Map.of(
"containerName", "your-container-name",
"connectionString", "your-connection-string"
)
)
{
"slug": "prd",
type: StorageProviders.AZURE,
config: {
"containerName": "your-container-name",
"connectionString": "your-connection-string",
},
}
{
["slug"] = "prd",
type: StorageProviders.AZURE,
config: {
["containerName"] = "your-container-name",
["connectionString"] = "your-connection-string",
},
}
| Field | Description |
|---|---|
containerName | The name of the Azure Blob container |
connectionString | The connection string to access the container |
Key Points
- Configure different providers per environment
- Swap providers without code changes
- Consistent interface across all providers
- Built-in logging for all operations
- Support for signed URLs with configurable expiry
- Store credentials securely using environment variables