Secret
A Secret is an encrypted credential — an API key, a token, a connection string. Same await secret.value() in your code on both targets.
Quick example
import { Project, Secret } from '@sprintsail/sdk';
export const app = new Project('orders');
export const stripeKey = new Secret(app, 'stripe-key', {
initialValue: 'sk_test_seeded_on_first_deploy',
});
Usage:
import { stripeKey } from '../infra.js';
const key = await stripeKey.value();
Config
interface SecretConfig {
initialValue?: string; // used only on first deploy; not overwritten on re-deploy
}
initialValue is optional. If omitted on first deploy, the SDK fills in a random sail-placeholder-<random> so apps reading the secret on first boot don't see "" and crash. You then rotate it via the cloud console, sail secret set (v1.1), or your secrets manager of choice.
Rotation-safe: re-running sail deploy does not overwrite the live value. The SDK reads the existing Secret and leaves it alone.
Target mapping
| Target | Maps to | Notes |
|---|---|---|
aws | Secrets Manager | sail destroy schedules deletion with a 7-day recovery window. |
sprintsail-runtime | sealed-secrets SealedSecret → materialized Secret | Encrypted at rest (RSA-OAEP + AES-GCM, strict-scoped). The controller materializes the plaintext Secret in the project namespace. Falls back to a bare K8s Secret on clusters without the sealed-secrets controller. |
Runtime methods
secret.value(): Promise<string>;
- On AWS:
GetSecretValueCommand→SecretString. - On Runtime: read from the projected file
/var/run/sprintsail/secrets/<bindingName>/value.
Values are cached per process for the lifetime of the container. Rotating a secret in the cloud does not invalidate an already-running pod's cached value — restart the workload to pick up the new value (or use a short-lived primitive like Function/CronJob, which has no cache).
What sail migrate does
| Path | What happens |
|---|---|
| AWS → AWS | GetSecretValue from source, PutSecretValue on destination. |
| AWS → Runtime | GetSecretValue from source, patch the materialized destination Secret on the runtime. |
| Runtime → Runtime | Read source K8s Secret, overwrite destination's materialized Secret. |
| Runtime → AWS | Planned. |
At-rest encryption
On the runtime, secrets are stored as SealedSecret CRs in etcd. Only the in-cluster sealed-secrets controller can decrypt them. The materialized Secret is owner-referenced by the SealedSecret — sail destroy removes both.