
Give each service temporary storage access
A service needs access to its files without holding the object store’s root key. Wildo’s managed storage uses short-lived sessions whose allowed prefix is chosen by the credential issuer.
Applications and platform services authenticate through distinct channels, then use the same storage provider. Credentials are cached, refreshed before expiry and replaced in the storage client when their identity changes.
Example — A long-running worker renews its access
A worker handles attachments throughout the day. When its session approaches expiry, concurrent file operations share one credential refresh. If the issuer cannot provide a replacement, storage access fails instead of silently switching to a more privileged key.
For engineers
Bind the correct identity channel
Applications use the application-to-manager credential resolver. Platform peers use createPlatformServiceStsStorageCredentialResolver, which authenticates with the platform bootstrap contract and requests the platform-service endpoint. Apps-manager itself uses an in-process resolver rather than an HTTP request to its own issuer.
The platform resolver’s request is shown below from storage-platform-sts-credential-resolver.backend.utils.ts; bootstrap validation above is omitted.
const payload = await requestStsCredentialPayload({
url: `${appsManagerUrl.replace(/\/+$/, '')}`
+ API_ROUTES_BACKEND_DEFINITIONS.APPS_MANAGER.GET_PLATFORM_SERVICE_STORAGE_SESSION_CREDENTIALS(),
headers: {
[WildoHeaderKeys.CONTENT_TYPE]: 'application/json',
[WildoHeaderKeys.PLATFORM_SECRET]: primarySecret,
[WildoHeaderKeys.SERVICE_ID]: serviceName,
},
});
return parseStsCredentialPayload(payload);
Let the provider own session refresh
StorageCredentialProvider.getCredentials returns a still-valid cached session, joins an ongoing refresh or asks the resolver for a new one. Comments are omitted from this implementation excerpt.
public async getCredentials(): Promise<ResolvedStorageCredentials> {
if (this.cached && !this.isDueForRefresh(this.cached)) {
return this.cached;
}
if (this.inFlight) {
return this.inFlight;
}
this.inFlight = this.resolve()
.then((credentials) => {
this.cached = credentials;
return credentials;
})
.finally(() => {
this.inFlight = null;
});
return this.inFlight;
}
Keep confinement separate from authentication
The issuer returns the application identity used by the session policy, and key composition uses that identity. A service name is not itself a storage permission. Platform bootstrap secrets remain sensitive even though the resulting object-storage credential is temporary.
The cache renews within a 60-second expiry margin. An invalid expiry is treated as requiring refresh; a failed refresh propagates, clears the in-flight attempt and can be retried by a later caller. The production managed resolvers have no ambient root-key fallback. This reduces the privilege and lifetime of credentials distributed to storage consumers; it does not remove the issuer’s own privileged storage responsibility.
Install the resolver in the platform service container
The crontabs/batches manager binds the resolver below in its container. This is the actual registration, with imports shown for application-developer readability; c is that service’s initialized dependency-injection container:
import {
SAAS_SERVICE_TYPES,
createPlatformServiceStsStorageCredentialResolver,
} from '@wildo-ai/saas-backend-lib';
c.bind(SAAS_SERVICE_TYPES.StorageCredentialResolver)
.toConstantValue(createPlatformServiceStsStorageCredentialResolver());
Binding this resolver supplies the managed provider’s credential source. The platform peer needs its own bootstrap values, in addition to storage topology:
| Bootstrap value | Meaning |
|---|---|
PLATFORM_APPS_MANAGER_URL | Address of the credential issuer |
SERVICE_NAME | This platform service’s identity, sent in the service header |
PLATFORM_APPLICATION_PRIMARY_SECRET | Its provisioned bootstrap secret, sent to authenticate that identity |
The resolver checks that all three are present, calls the platform-service credential endpoint and parses the returned session. It does not require an application APPLICATION_ID to impersonate an application. Missing bootstrap values fail before a request; an issuer refusal propagates rather than selecting another credential source.
| Caller | Installed channel |
|---|---|
| Generated application | Application-to-manager resolver and provisioned application identity |
| Platform peer such as the batches manager | The platform-service resolver binding above |
| Apps-manager, the issuer itself | Its in-process resolver; no startup HTTP call to itself |
Use the provider’s credential cache instead of adding another timer or copying the resulting keys into environment variables. Its refresh logic shares an in-flight request among concurrent callers and discards a failed attempt so a later call can retry.