Secrets, Retention, and Residency
Runtime secret providers, enforceable data retention, residency checks, and signed deletion evidence.
Runtime secret providers
Commands use secret('NAME') references. The model and session log see the
reference name, never the resolved value. Compose providers in deployment order
and pass one resolver into the agent:
import { chainSecretProviders, environmentSecretProvider, secretResolver } from '@fabric-harness/sdk';
import { vaultSecretProvider } from '@fabric-harness/node';
const secrets = chainSecretProviders(
environmentSecretProvider({ allow: ['LOCAL_TOKEN'] }),
vaultSecretProvider({
address: process.env.VAULT_ADDR!,
token: () => workloadIdentityVaultToken(),
namespace: 'platform',
pathForSecret: (name, tenantId) => `tenants/${tenantId}/${name}`,
}),
);
const fabric = await init({ resolveSecret: secretResolver(secrets) });Provider failures stop resolution instead of falling through to a less-governed provider. Use workload identity or a rotating token callback rather than embedding a provider credential in source.
Azure Key Vault
import { azureKeyVaultSecretProvider } from '@fabric-harness/azure';
const keyVault = azureKeyVaultSecretProvider({
vaultUrl: 'https://my-vault.vault.azure.net',
token: () => managedIdentityAccessToken(),
});Databricks Secrets
import { databricksSecretsProvider } from '@fabric-harness/databricks';
const workspaceSecrets = databricksSecretsProvider({
host: process.env.DATABRICKS_HOST!,
token: () => appServicePrincipalToken(),
scope: (_name, tenantId) => `fabric-${tenantId}`,
});The Databricks adapter calls Secret Management at runtime and decodes the returned value inside the provider closure. Workspace tokens and secret values are not added to model messages, events, audit entries, or telemetry.
Retention policy
enforcePersistenceRetention() applies independent age limits to sessions,
conversation streams, attachments, audit storage, and telemetry storage.
External audit and telemetry systems provide a deleteBefore() adapter, so a
configured rule cannot silently report success without deleting from that
system.
import { enforcePersistenceRetention } from '@fabric-harness/node';
const result = await enforcePersistenceRetention(persistence, {
sessions: { maxAgeDays: 30 },
conversationStreams: { maxAgeDays: 14 },
attachments: { maxAgeDays: 7 },
audit: { maxAgeDays: 365, target: siemRetentionTarget },
telemetry: { maxAgeDays: 30, target: tracingRetentionTarget },
residency: { region: 'us-west-2', allowedRegions: ['us-west-2'] },
});Run the coordinator from a singleton scheduled job. Session expiry uses the bundle's cascade deletion path, which removes submissions, conversation streams, and attachments together. Attachment timestamps are used when available; older stored references inherit their session update time.
Residency
assertDataResidency(region, allowedRegions) fails before data maintenance or
export when the deployment region is not allowed. Use the same configured
region for the database, object backup location, audit sink, telemetry sink,
and Databricks workspace. Region labels are application policy inputs; cloud
network and IAM controls must independently prevent cross-region endpoints.
Signed deletion evidence
Wrap a persistence bundle to emit an append-only completion record after each successful cascade deletion:
import {
hmacDeletionEvidenceSigner,
postgresDeletionEvidenceStore,
postgresPersistence,
withDeletionEvidence,
} from '@fabric-harness/node';
const base = postgresPersistence({ client: pool });
const persistence = withDeletionEvidence(base, {
signer: hmacDeletionEvidenceSigner({
key: process.env.DELETION_EVIDENCE_KEY!,
keyId: 'retention-2026-01',
}),
store: postgresDeletionEvidenceStore(pool),
});The receipt contains deletion counts, completion time, key id, signature, and
a digest chained to the previous record. Session and tenant identifiers are
stored only as keyed HMAC pseudonyms. Prompts, messages, filenames, attachment
bytes, and other deleted content are never copied into the evidence record.
Use ed25519DeletionEvidenceSigner() when verifiers must validate records
without access to the signing key.