Skip to content

test(config,deploy): map the secret field-name and raw StrKey rejection boundaries - #268

Merged
dDevAhmed merged 1 commit into
DigiNodes:mainfrom
ridercoder4:test/sw-081-sw-086-secret-field-and-strkey-matrices
Oct 18, 2026
Merged

dDevAhmed merged 1 commit into
DigiNodes:mainfrom
ridercoder4:test/sw-081-sw-086-secret-field-and-strkey-matrices

Conversation

@ridercoder4

Copy link
Copy Markdown
Contributor

Summary

Two P0 security-sensitive issues, both pure test additions with no fixture or
network cost. Neither area had the coverage its risk profile implies.

SW-081 (#181) — the secret field-name guard was barely mapped

The guard is one regex (src/config/schema.ts):

/(?:secret|private[_-]?key|seed|mnemonic|password|passphrase|token)/i

The existing configuration-secret-reflection.test.ts covers fifteen names, but
they cluster into a few shapes and never vary casing or separator style across the
set. Two properties were therefore completely unpinned:

  1. Casing is irrelevant. Nothing asserted that SECRET_KEY, SecretKey or
    sEcReTkEy are rejected — so dropping the /i flag would leave the suite green.
  2. Separator style is inconsistent by design. Only private[_-]?key permits a
    separator inside the term; every other alternative matches on its head word
    alone. seed_phrase, api-token and refresh_token all match via seed /
    token, not via a separator rule.

41 recognised names now cover casing, separator style and scope prefixes, exercised
both through validateStellarForgeConfig directly and through the real
loadProjectConfig file path, each asserting the value is never reflected.

The second group is the more interesting half. Eight names look secret but are
not recognised by the regex, and are therefore refused as ordinary unsupported
fields rather than as secret material:

pass_phrase · pass-phrase · encryptionKey · encryption_key · signingKey
· signing-key · signing_key · hdAccountIndex

passphrase is the only multi-word alternative in the pattern and it tolerates no
separator; there is no alternative matching a bare key. All eight are still
refused before the config is usable — just via the generic path. That boundary is
now asserted explicitly, so widening the regex has to be a deliberate change rather
than a side effect of an edit.

The legitimate-field half of the acceptance criteria is covered too: all three
networks, five alias shapes and a fully populated config still validate, plus an
ordinary typo (nickname) still reports "unsupported field" rather than being
mislabelled as secret material.

SW-086 (#186) — where the raw-StrKey rule actually starts and stops

validateIdentityAlias is the single gate in front of both the deploy --source
and the config identity:

/^[GS][A-Z2-7]{55}$/        → reject
!/^[A-Za-z][A-Za-z0-9_-]{0,63}$/ → reject

The existing deploy-source-rejection.test.ts proves the rule fires with two
cases. It does not describe where the edge is — and the edge is asymmetric:

  • a canonical 56-character G… / S… StrKey is rejected (5 shapes, including the
    full base32 alphabet and the digit range 2-7);
  • a near-miss is accepted as an ordinary alias and forwarded to the Stellar
    CLI as an identity name.

The near-miss group is 12 cases: wrong length (55, 57), lowercased G/S,
mixed-case, muxed M, contract C, and tails carrying 0, 1, 8, - or _
— none of which are in the base32 alphabet.

No secret material is exposed by that group, because none of those values is a
valid Stellar seed, so the CLI simply fails to resolve them as an identity. But it
is a real asymmetry and worth knowing about, so it is asserted rather than left to
be discovered. I did not change the regex — that would be a behaviour change beyond
this issue's scope, and narrowing it could reject legitimate aliases. Flagging it
for a maintainer decision instead.

Also covered: 14 values refused by the alias rule rather than the StrKey rule, the
exact 64/65-character alias boundary, the error never reflecting any rejected
value, rejection happening before any subprocess is planned for both groups,
and network validation taking precedence over source validation.

Issue references

Closes #173

Closes #174

Closes #181

Closes #186

What this PR actually changes

Implemented in full — #181 (config-secret-field-name-variants.test.ts) and
#186 (deploy-strkey-rejection-matrix.test.ts).

Not implemented here, and why:

Both are the same fixture-boundary problem, and both would need a dependency
install to be meaningful — which is why I took the two P0 security issues instead.
They were the higher-risk gap and the only pair that needs nothing installed.

How this was verified

Every field name and StrKey value in this PR was checked against the actual
regexes in the source
rather than by eye — including confirming that the eight
"unrecognised" config names genuinely do not match, and that all twelve near-miss
StrKeys genuinely are accepted. Two entries that would have been wrong
(passphrase, privateSecretKeyBase) were caught and corrected that way.

Not run

node_modules was not installed and the suite was not executed, per your
constraint. Worth one local run before merge. Everything here is pure regex
behaviour with no platform or subprocess dependency, so I expect it to pass as
written — but the it.each matrices are wide enough that a run is worth having.

…on boundaries

SW-081 (DigiNodes#181): the config secret guard is one regex,
/(?:secret|private[_-]?key|seed|mnemonic|password|passphrase|token)/i, and the
existing suite covers fifteen names without ever varying casing or separator
style. Two properties were unpinned: nothing asserted that casing is irrelevant,
so dropping the /i flag would leave the suite green; and only private[_-]?key
permits a separator inside a term, so every other name matches on its head word
alone. Adds 41 recognised names across casing, separator style and scope
prefixes, each exercised through validateStellarForgeConfig and through the real
loadProjectConfig path, asserting the value is never reflected.

Also pins the boundary the guard does NOT cover - pass_phrase, encryptionKey,
signingKey and similar are refused as ordinary unsupported fields rather than as
secret material. They are still refused before use, just via the generic path, so
the asymmetry is asserted rather than left to be discovered.

SW-086 (DigiNodes#186): validateIdentityAlias is the single gate for both deploy --source
and config identity. The existing rejection test proves the rule fires with two
cases but not where its edge is, and the edge is asymmetric - a canonical 56-char
G/S StrKey is rejected, while a near-miss (wrong length, lowercased, muxed M,
contract C, or a tail carrying 0/1/8/-/outside base32) is accepted as an ordinary
alias and forwarded to the Stellar CLI as an identity name. No secret is exposed
there since none of those values is a usable seed, but it is worth pinning from
both sides so widening the regex has to be deliberate. Adds 5 canonical shapes,
14 alias-rule rejections, the exact 64/65-character boundary, non-reflection of
every rejected value, and rejection before any subprocess is planned.

The regex was left unchanged - narrowing it is a behaviour change beyond a test
issue and could reject legitimate aliases.
@coderabbitai

coderabbitai Bot commented Oct 18, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 767272f0-e30b-4571-a8dc-bbeb285a66b1
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@dDevAhmed
dDevAhmed merged commit 6caae11 into DigiNodes:main Oct 18, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants