Skip to main content
← Back to list
01Issue
FeatureClosedSwamp Club
AssigneesNone

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 to getContent() 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
02Bog Flow
OPENTRIAGEDIN PROGRESSCLOSED

Closed

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.