/** * Shared AES-256-GCM encryption for secret values at rest. * * Used by the framework secrets vault, per-user/per-org credentials * (`resolveCredential` / `saveCredential`, stored in `settings`), and other * column-level encrypted values. The `app_secrets` storage layer uses the * shared-key variant below because workspace-scoped vault rows are readable by * sibling apps in the same workspace. When a deployment has not been given * shared key material yet, that variant falls back to the app-scoped key so * existing single-app deployments can keep reading and writing secrets while * they migrate to the shared key. * * The generic encryption key is derived from * `_SECRETS_ENCRYPTION_KEY` when set, then * `SECRETS_ENCRYPTION_KEY`, then `BETTER_AUTH_SECRET`. Workspace-shared vault * rows use a different precedence: `WORKSPACE_SECRETS_ENCRYPTION_KEY`, then * the legacy shared `SECRETS_ENCRYPTION_KEY`, then material derived from the * workspace-wide `A2A_SECRET`, then the app-local auth/key fallbacks retained * for backward-compatible reads. A previous workspace key can be supplied * during rotation with `WORKSPACE_SECRETS_ENCRYPTION_KEY_PREVIOUS`. This keeps * sibling apps on one stable key even when each app correctly has a different * auth secret, and prevents A2A trust rotation from stranding vault data. * * In production we refuse to start without configured key material — a * CWD-derived fallback would be effectively static (e.g. `/var/task` on * Lambda), so anyone with read access to the DB could decrypt every secret. * * Encrypted values are tagged `v1:::`. The `v1:` prefix * lets readers distinguish ciphertext from legacy plaintext during migration. */ export declare function getSecretEncryptionKey(): Buffer; /** * Derive the preferred workspace-shared key used by `app_secrets` rows. * Unlike generic column-level encryption, workspace vault data must decrypt * in sibling apps. An explicit `WORKSPACE_SECRETS_ENCRYPTION_KEY` wins without * changing the key for app-local OAuth and credential ciphertext. The legacy * shared `SECRETS_ENCRYPTION_KEY` remains supported; hosted workspaces * otherwise derive material from their shared `A2A_SECRET` before considering * app-local `BETTER_AUTH_SECRET` or app-scoped key fallbacks. Reads try every * configured legacy/previous candidate and report when the ciphertext should * be refreshed under the preferred key. */ export declare function getSharedSecretEncryptionKey(): Buffer; export declare function hasSharedSecretEncryptionKeyMaterial(): boolean; export declare function encryptSecretValue(plaintext: string): string; export declare function decryptSecretValue(encrypted: string): string; export declare function encryptSharedSecretValue(plaintext: string): string; export declare function decryptSharedSecretValue(encrypted: string): string; export interface DecryptedSharedSecretValue { value: string; needsReencrypt: boolean; } /** * Decrypt workspace ciphertext with the preferred key first, then configured * legacy candidates. The result never exposes which secret material matched. */ export declare function decryptSharedSecretValueDetailed(encrypted: string): DecryptedSharedSecretValue; export declare function isEncryptedSecretValue(value: unknown): value is string;