Repository navigation
test(config,deploy): map the secret field-name and raw StrKey rejection boundaries - #268
Merged
dDevAhmed merged 1 commit intoOct 18, 2026
Conversation
…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.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configuration
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. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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):The existing
configuration-secret-reflection.test.tscovers fifteen names, butthey cluster into a few shapes and never vary casing or separator style across the
set. Two properties were therefore completely unpinned:
SECRET_KEY,SecretKeyorsEcReTkEyare rejected — so dropping the/iflag would leave the suite green.private[_-]?keypermits aseparator inside the term; every other alternative matches on its head word
alone.
seed_phrase,api-tokenandrefresh_tokenall match viaseed/token, not via a separator rule.41 recognised names now cover casing, separator style and scope prefixes, exercised
both through
validateStellarForgeConfigdirectly and through the realloadProjectConfigfile 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·hdAccountIndexpassphraseis the only multi-word alternative in the pattern and it tolerates noseparator; there is no alternative matching a bare
key. All eight are stillrefused 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 beingmislabelled as secret material.
SW-086 (#186) — where the raw-StrKey rule actually starts and stops
validateIdentityAliasis the single gate in front of both the deploy--sourceand the config
identity:The existing
deploy-source-rejection.test.tsproves the rule fires with twocases. It does not describe where the edge is — and the edge is asymmetric:
G…/S…StrKey is rejected (5 shapes, including thefull base32 alphabet and the digit range
2-7);CLI as an identity name.
The near-miss group is 12 cases: wrong length (55, 57), lowercased
G/S,mixed-case, muxed
M, contractC, and tails carrying0,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
errornever reflecting any rejectedvalue, 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:
stellarforge test#173 (SW-073) requires generating an API Service and runningstellarforge testinside it. The generated project is a Node template, so thefixture needs
node_modulesinstalled before it has anynpm testto run — I wasasked not to install dependencies. Related behaviour (exit-code propagation,
plan resolution) is covered directly in test(test): cover Cargo exit propagation and platform-correct plan resolution #267 by another contributor in this wave.
is feasible, but executing
cargo testin it needs to fetch crate dependenciesfrom the network, and the issue's own acceptance criteria ask for no network.
The plan-resolution half of it is covered in test(test): cover Cargo exit propagation and platform-correct plan resolution #267.
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_moduleswas not installed and the suite was not executed, per yourconstraint. 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.eachmatrices are wide enough that a run is worth having.