Skip to main content
Wildo.ai Coming soon

Files and storage

Keep uploaded files in managed object storage

The managed provider stores bytes separately from records and obtains application-confined session credentials for storage access.

A record retains its attachment reference while document contents live in object storage.

Keep uploaded files in managed object storage

Uploaded files can live in S3-compatible object storage while the application keeps their metadata and permissions. Wildo’s managed provider supplies that connection through the common file-storage contract.

In a platform-provisioned deployment, fields without a storage preference use the configured managed store. Applications and workers obtain scoped session credentials rather than receiving the store’s root key.

Example — A worker can read the same attachment as the API

An API accepts a document and stores its file reference. A background operation can later retrieve the bytes through the same configured storage provider, without depending on the API process’s local upload directory.

For engineers

Provide topology and the credential channel

Managed storage reads its endpoint, TLS, bucket and prefix from resolved configuration. Platform provisioning and the credential issuer must be available; the field declaration does not provision an object store for an independently hosted application.

The provider obtains a cached session credential through its configured resolver and rebuilds its client when the credential identity changes. Failure to obtain a session propagates instead of falling back to ambient root credentials.

Follow the object key through the write

wildo-managed-storage-provider.backend.service.ts composes the key, sends the bytes and returns the actual provider handle. Earlier size validation is omitted; the key branch is shown so its configuration remains visible.

const includeAppId = options?.includeApplicationId ?? true;
const key = includeAppId
  ? await this.resolveApplicationObjectKey(effectiveFileId, executionContext, undefined, options?.linkedResourceType, options?.scope)
  : effectiveFileId;
const client = await this.getClient();

try {
  await client.putObject(
    this.bucketName,
    key,
    fileStream,
    size,
    {
      [WildoHeaderKeys.CONTENT_TYPE]: mimeType,
    },
  );
} catch (error) {
  this.convertStorageError(error, 'upload', executionContext, {
    fileId,
    storageRef: key,
    provider: this.providerId,
  });
}

return {
  storageRef: key,
  provider: this.providerId,
};

Use limits that fit the managed path

The normal key includes the application, resource and owner scope. Persisted references are checked before reads and deletes; an object address is not accepted merely because it came from the database. The provider also enforces the configured maximum file size and a 5 GiB single-put ceiling.

This implementation deliberately avoids multipart upload because its required bucket-level operations do not fit the prefix-confined session policy. Keep application limits below that ceiling. Object storage holds the durable bytes, but HTTP upload handling can still use temporary local files; this is not a promise that the server never touches disk.

Connect an application to its provisioned object store

An omitted storageAccepted list already selects managed storage. An explicit declaration makes that requirement visible to a reader:

import { FileStorageAccepted, z_file } from '@wildo-ai/zod-decorators';

const attachment = z_file({
  storageAccepted: [FileStorageAccepted.WILDO_MANAGED],
  maxSize: 25 * 1024 * 1024,
});

This illustrative environment describes a provisioned object-store service reachable as minio from the application backend. The bucket must be the one provisioned for the application; the example does not create it:

STORAGE_ENDPOINT=minio
STORAGE_PORT=9000
STORAGE_USE_SSL=false
STORAGE_BUCKET=application-files

These values seed storage.managed. Use the deployment’s actual endpoint, TLS setting and bucket. Endpoint configuration is only half of the setup: the normal application credential channel also needs its provisioned bootstrap identity.

InputResponsibility
PLATFORM_APPS_MANAGER_URLReach the platform service that issues storage sessions
APPLICATION_IDIdentify this provisioned application
PLATFORM_APPLICATION_PRIMARY_SECRETAuthenticate that application to the issuer; supply through deployment secrets
Storage topologyMatch the bucket and prefix allowed by the issued session

The installed resolver obtains short-lived, prefix-confined credentials from apps-manager. It caches sessions and reacquires them as needed; issuer failure does not select root keys from the environment. Do not copy object-store administrator credentials into application configuration.

This is the application credential channel. Platform services can inject their own resolver and must use their corresponding identity path; the issuer must not be configured as an application client of itself during startup. Verify both session issuance and an authorized object operation before treating a configured endpoint as usable storage.

Building a B2B product or an internal tool?

Wildo is not self-service yet. Tell us what you have in mind and we will say plainly whether it fits, and what happens next.