Skip to main content
← Back to list
01Issue
BugOpenSwamp CLIPublic
AssigneesNone

Relationships

#3641 Generated vault keys carry raw data-name and vary characters that strict vault providers reject

Opened by zack · 10/19/2026

Problem

processSensitiveResourceData (src/domain/models/data_writer.ts) builds a sensitive field's generated vault key from <modelType>/<modelId>/<method>/<spec>/<instanceName>/<fieldPath> and passes it through sanitizeVaultKey, which only handles @, /, \, ', .. and NUL. Everything else in the instance name reaches the vault provider as-is.

Since swamp-club#3633 the instance segment includes the vary suffix, and vary values are much more likely than hand-picked data names to hold characters such as spaces, braces, double quotes, colons and commas. coerceToSuffix (src/domain/workflows/data_suffix.ts) falls back to truncated JSON for an object without key, name or id, so a vary input like {region: us} becomes a suffix of {"region":"us"}, and a string input us east keeps its space.

local_encryption accepts these characters. Providers with stricter key rules may refuse the put, so the write fails. AWS Secrets Manager, for example, allows only alphanumerics and /_+=.@-. A data name holding these characters could already trigger this before #3633; vary makes it far more likely.

Expected

The instance segment of a generated key is normalised to a conservative character set (for example [A-Za-z0-9._-]) in a way that keeps distinct instance names distinct, for example a short hash suffix whenever characters had to be replaced, so two vary instances never fold onto one key again.

Notes

  • Raised by the adversarial review of the swamp-club#3633 fix. Out of scope there: it changes the key-derivation design rather than which name is passed.
  • Stored references carry the key literally, so changing the derivation affects new writes only.
  • An explicit field vaultKey is not sanitised and is out of scope.
  • A pre-existing related collision: segments are joined with - after sanitising, so spec a-b with instance c and spec a with instance b-c produce the same key. A redesign of the instance segment could address both.
02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

10/19/2026, 8:50:22 PM

No activity in this phase yet.

03Sludge Pulse
Editable. Press Enter to edit.

zack commented 10/19/2026, 9:29:47 PM

Scope update from swamp-club#3633. Testing after its first verification showed the vary suffix could not reach the key raw without regressions (a quote vs a dash and an at-sign vs nothing folded onto one key; a 200-character plain value hit File name too long in local_encryption). So #3633 now encodes the vary suffix itself: kept as written when it is at most 64 letters, digits, dot, underscore and dash, otherwise a plus sign and 32 hex digits of its SHA-256. What remains here is the base data name (and the rest of the key), which still passes through sanitizeVaultKey alone, plus the spec/instance split ambiguity noted above. A non-vary data name with characters outside the safe set, or a very long one, still has both problems.

zack commented 10/19/2026, 9:41:07 PM

Further scope from swamp-club#3633. The vary suffix is now kept as written only when it is at most 32 letters, digits and dashes, and is otherwise hashed to h- plus 32 hex digits (34 characters, all Azure Key Vault safe), so a vary write's key is at most 35 bytes longer than the same write without vary. That bounds the suffix, not the key. A behavior whose type, method, spec and field names already produce a key near the 255-byte local_encryption file name still overflows it, with or without vary (a test behavior with type user/very-long-vendor-name/service-category/resource-type-name, method [REDACTED-SECRET-1] and a nested field has a 210-byte key before any suffix). A real guarantee needs a cap on the whole generated key, which belongs here with the base-name normalisation. The same applies to Azure Key Vault: a dot in a nested field path or an underscore elsewhere in the key is still passed through, and Azure also caps names at 127 characters.

Sign in to post a ripple.