getContent() should resolve vault expressions for sensitive fields
Opened by swampadmin · 10/4/2025
Problem Statement
When an extension model writes a resource with sensitive fields (marked via .meta({ sensitive: true }) in the Zod schema), swamp stores vault expressions in place of the actual values, e.g.:
${{ vault.get('homekit-secrets', 'abc123') }}However, context.dataRepository.getContent() returns these vault expressions as literal strings rather than resolving them. This forces extension authors to manually detect and resolve vault expressions:
const pairing = JSON.parse(new TextDecoder().decode(rawPairing));
const vaultExprRegex = /^${{s*vault.get(s*'([^']+)',s*'([^']+)'s*)s*}}$/;
for (const key of Object.keys(pairing)) {
const match = typeof pairing[key] === "string" && pairing[key].match(vaultExprRegex);
if (match && context.vaultService) {
pairing[key] = await context.vaultService.get(match[1], match[2]);
}
}This is undocumented, fragile, and leaks vault internals into extension code. It also means extensions that don't know about this pattern will pass vault expression strings where they expect real values, leading to confusing errors (e.g., "private key of length 32 expected, got 52" when the vault expression string is longer than the actual key).
Proposed Solution
The data read path should automatically resolve vault expressions for sensitive fields before returning data to extension code. Extensions should receive the same object shape they wrote, with sensitive values transparently decrypted.
Scope of changes:
- Data repository or MethodContext read path: detect vault expressions and resolve them via the vault service before returning
- This could be part of
readResource()(#708) or applied togetContent()directly - Vault expression format should remain an internal implementation detail, not exposed to extensions
Alternatives Considered
- Document the vault resolution pattern — reduces surprise but still requires every extension to implement it
- Provide a helper function — better, but extensions still need to know to call it
- Automatic resolution at the read boundary is the cleanest approach since it maintains the abstraction that sensitive fields are just fields
Closed
No activity in this phase yet.
Sign in to post a ripple.