Repository navigation
Show only the last 4 characters of a license key in log entries and error messages - #52
Merged
Merged
Conversation
…and name the masking literals
# Conflicts: # pipeline/core/phpunit.xml
# Conflicts: # pipeline/core/phpunit.xml
jwrosewell
marked this pull request as ready for review
November 10, 2026 19:37
This was referenced Nov 10, 2026
Merged
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.
Problem
specifications#55 (merged as c9939a78) added a "License keys" section to logging.md, and specifications#123 (247f071) has since changed its wording. At specifications 093bf3e5 it says at lines 20 to 24:
and at lines 32 to 39:
No issue exists in this repository.
What I checked
I searched every PHP package for a place that logs or throws with a license key or a URL that carries one.
DidClient(the only code that holds a license key) sends it in the form body, never in the URL. Its error messages carry text from the server's reply, which can repeat the key, and its transport can raise a message that names it.HttpClientin the Cloud Request Engine package puts the URL it requested into its error messages, and a URL can carry alicense,licenseKeyorlicenseKeysquery parameter, or the same with thelicencespelling, which the cloud service also reads (cloud-request-engine.md, "The server also readslicenceas another spelling oflicense"). The Cloud Request Engine in PHP sends only a resource key today.CloudRequestEngine::addQueryDatawarns withtrigger_errorwhen two pieces of Evidence give the same field, and the warning names the values, so it could name licence key Evidence such asquery.license. #56, now merged, leaves Evidence namedlicenseorlicenceout of the request before that check.licenseKeyproperty that nothing reads or logs. The on-premise engine's licence key is held by the native code, which this repository does not log.Change
LicenseKeyclass in the core package (pipeline/core/src/LicenseKey.php) withmask()(one*for each hidden character and the last 4 characters shown, or all*for a key of 4 or fewer) andmaskQuery(), which masks the value of eachlicense,licenseKeyandlicenseKeysquery parameter, in either spelling, anywhere in a text, including each key of a list separated by|or,.HttpClientpasses the failure messages and the error messages it raises throughmaskQuery().^4.5.207(pipeline/cloudrequestengine/composer.json), becauseHttpClientcallsLicenseKey, which no published core has. With4.*, a site that updates only the Cloud Request Engine would keep core 4.5.206 and fail with "Class not found" on its first failed request. 4.5.207 is the versionci/get-next-package-version.ps1gives the next release, one patch above the highest tag, 4.5.206, so the floor is right if this draft is in the next release frommain. The packages that use the Cloud Request Engine get core through it. CI is not affected, because it installs core from this checkout as4.x-dev.DidClientreplaces its own license key, in plain and URL encoded form, in the messages it builds from a reply and in the message of a failure raised by the transport. The reply text is masked before it is cut to 200 characters, so a key cannot be left half hidden. The new exception for a transport failure has no previous exception, because that would carry the original message. The number of characters shown and the mask character are named constants.Tests
LicenseKeyTestsin the core package, including thelicenceandLicenceKeyspellings.HttpClientFailureTests::testAFailedRequestHoldsOnlyTheMaskedLicenseKeymakes a request to a port nothing listens on, with a license key in the URL.DidClientTestfor a 400 reply, a 500 reply and a transport failure that name the key.Runs.
LicenseKeyTests6 errors,HttpClientFailureTests1 failure,DidClientTest3 failures. Green run 42701302662, all three pass (6, 3 and 86 tests).licencespelling. Red run 42796923319 on the test commit 524ed22,testMaskQueryMasksTheLicenceSpellingfails. Green run 42797120448 on 06abd7c, 284 tests, none failing.HttpClientFailureTests. Red run 42796955790 on 524ed22, where Composer installs core 4.5.206 and three tests fail withClass "fiftyone\pipeline\core\LicenseKey" not found. Green run 42797164599 on 06abd7c, where Composer refuses to install, because the newest published core is 4.5.206 and the package needs^4.5.207.Full build
Run 42885000600 on head 1b67dee passed every job, being Configure, the 8 build and test jobs (Ubuntu PHP 7.4 and 8.0 to 8.5, and Windows PHP 8.3) and Complete. Every one of the 9
Setting 'PullRequestSha'lines reads 1b67dee, and Configure printed "Left out 5 macOS entries".macOS was left out of this draft's full build under the 9 November decision. The rc head is built with macOS before it merges into main.
Other drafts
LicenseKey::mask, so merge this one first.rcat 1fed97f after #48 landed, keeping both lines Set the client-side cache headers, with a weak ETag of the supplied Evidence #48 and this draft add topipeline/core/phpunit.xml. Other open drafts add a line at the same place, and each keeps every line. After #51 landed,rcat 08f7bef was merged in (head 1b67dee), keeping bothphpunit.xmllines, and the full build above is on that head. The head merges cleanly intorcat 0196662, which holds Add the web request to Evidence as a read-only view under server.http-request #49 and Count a sequence only as digits from 0 to 2,147,483,646, with no sign or spaces #59, and the full build above merged thatrc.Not covered
Every third-party transport a site might pass to
DidClient. The contract says a transport throwsRuntimeException, and only that type is masked.CloudExceptionstill carries the reply body as data, outside its message, which the page does not cover.Remaining
Review by someone other than the author.