Repository navigation
Tighten the password pin step after the schema 165 upgrade - #5466
Merged
Merged
Conversation
The upgrade records which old-format saved passwords are in the store, with the hash of each value and the connection it is saved for. The one-time pin step works from that record: a value is pinned only when its text and its connection both still match, and only when this machine opens it. The opened password is never held. A pin step that fails at start is tried again, and a Windows host takes over a step a Linux host left open.
The pin step runs after the key step on every path, and a step that could not run is tried again on each sweep. The re-enter line says to wait while that is the case.
The candidate record is taken only while the pin marker is pending. A store whose step is set aside or done records nothing, and a Windows host then finds no match and sets the step done. Provisioning script: keep the schema 165 revoke when the newer table is missing. The four-table guard and revoke are as before, the candidate table has its own branch, and the rung numbers in the comments say V167.
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.
After the schema upgrade, the service takes one-time pins for saved passwords in the old format so they keep working. The upgrade now records which old-format values are in the store, with the hash of each value and the connection it is saved for, and the pin step works from that record. A value is pinned only when its text and its connection both still match the record and this machine can open it. The step no longer keeps an opened password in memory, and a Windows host takes over a step a Linux host left open.
SECTION: Fixed
ENTRY: - The one-time password pin step after the schema 165 upgrade is tightened ([#5466]) - a pin step that fails at start is tried again on the next sweep instead of waiting for a restart.
Details
What changes (all under
Darling/):legacy-pin-candidates(PerformanceMonitor.Darling.Storage/LegacyPinCandidateTables.cs,PgMigrations.cs,StorageVersion.cs= 167). It createsconfig.legacy_secret_pin_candidate(row-level security on, no policy, owner-only row and truncate triggers made before the capture) and records the old-format values present while the pin marker ispending. A store whose step is done orskippedrecords nothing. V165 is not changed. The first number was 166 and dev took 166 for the PagerDuty auto-resolve column, so this rung is 167.DarlingPasswordKeyStore.SnapshotLegacyPinsAsync(PerformanceMonitor.Darling.Service/DarlingPasswordKeyStore.cs): checks every owner-only trigger first (the candidate table's two included); locks the marker (Windows may take overskipped, Linux only turnspendingintoskipped); matches a live value only when both the stored-text hash and the connection hash equal the record (fixed-time compare); only matches are offered tocanOpen.doneclears the record and raisesconfig_versionin the same transaction as the pins. Nothing matching any more isdonewith no pins and no bump. Matches but none opened is a rollback andnot-here.DarlingSecrets.CanUnprotect(string): answers whether this machine opens a value; the opened bytes are zeroed and no string is built.DarlingManagedRoles.csandtools/provision-roles.sql): the new table has its own revoke, and is in theto_regclasslists and the trigger allow list. In the script the four V165 tables keep their guard and revoke, and the candidate table is revoked in its ownto_regclassbranch.hasLegacyPinCandidates,GetBoolean(142), returns 167.Tests (local PostgreSQL in UTC; Total / Failed):
*PasswordKey*170 / 0 (12 skipped, platform-specific),*LegacyPin*8 / 0,*Rung*350 / 0,*Grant*45 / 0,*TablesLive*6 / 0,*CaggGroupIndexDrop*9 / 0,*SchemaVersion*35 / 0,*StoreUpgrade*269 / 0 (13 skipped),*Secrets*58 / 0*Census*440 / 0,*Ratchet*15 / 0,*Scrub*120 / 0,*Guard*244 / 0,*Hygiene*90 / 0 (*Scrub*ran before the merge with dev; the rest ran after it)LegacyPinCandidateRungTests(5, includes the liveAStoreAt165_CapturesItsValues_ADoneStoreNone),DarlingSecretsCanUnprotectTests(2),ThePinStep_NeverBuildsThePlaintext, and liveARowWrittenAfterTheUpgrade_IsNeverPinned_AndIsRefused,ARowMovedToAnotherHost_IsNotPinned,ALinuxHostLeavesTheStepToWindows,AHostThatOpensNone_LeavesTheStepOpen,WhenNothingStillMatches_TheStepIsDone,ADroppedCandidateTrigger_RefusesAndPinsNothingUpdated pins:
PasswordKeyRungTests,PagerDutyAutoResolveRungTests(no longer the top rung, the arm sits below V167's),PasswordKeyGrantParityTests,PasswordKeyTablesLiveTests,CaggGroupIndexDropLiveTests, the fixtures inDarlingPasswordKeyStoreLiveTestsandPasswordKeySeamLiveTests.Follow-up changes
LegacyPinCandidateTables.cs:107: the record is taken only while the marker ispending; a store whose marker isskippedordonerecords nothing, and a Windows host then finds no match and sets the step done. Tests:LegacyPinCandidateRungTests.AStoreAt165_CapturesItsValues_ADoneStoreNone(also coversskipped) andDarlingPasswordKeyStoreLiveTests.AStoreWhoseStepWasSkippedBeforeTheRecord_RecordsNothing_AndAWindowsHostSetsItDone.tools/provision-roles.sql:638-646: the four-table guard and revoke for the V165 tables are as before, so a store at V165 or V166 still gets them; the candidate table has its own branch. Comments in the script andDarlingManagedRoles.cs:1161say V167. Tests:PasswordKeyGrantParityTests.TheScriptsGuard_NamesTheFourV165Tables_AndTheCandidateTableHasItsOwnBranchand the updated parity test; the script also ran clean inComposeStoreRolesLiveTests(9 / 0).Tests after these changes (local PostgreSQL in UTC; Total / Failed):
LegacyPinCandidateRungTests+DarlingPasswordKeyStoreLiveTests+PasswordKeyGrantParityTests33 / 0;*PasswordKey*,*LegacyPin*,*Rung*,*Grant*,*Provision*,*Secrets*together 649 / 0 (12 skipped);*Census*440 / 0,*Ratchet*15 / 0,*Scrub*120 / 0,*Guard*244 / 0,*Hygiene*90 / 0; build 0 warnings.Part B (start-up retry)
The one-time pin step now runs after the password key step on every path, including the one where the key step itself fails, and a step that could not run is tried again on each sweep.
What changes (all under
Darling/PerformanceMonitor.Darling.Service/):DarlingPasswordKeyRuntime.cs:RunPinStepAsync(:515) is called after the key step on the normal path (:170), the key-step failure path (:183) and the unresolved-directory path (:121). Only a cancellation escapes it. A failure, or a key table whose protection is incomplete, setsPinsWaiting(:100) and logs one Warning ("Old-format saved passwords wait for the one-time pin step, which could not run ... The service tries it again on every sweep."), then Debug lines. A step that matches values but opens none here (not-here), and a step a Linux host left open, are not waiting;not-herelogs one Warning that the step stays open for the machine that saved them.SweepCheckAsync(:222) retries first while the step is waiting, before it returns for a runtime that holds no key. The earlier one-shot snapshot call inStartAsyncis gone.StoreConfigProvider.cs:LegacyPinsWaiting(:71), set by the worker right after the key step and before the first view (DarlingWorker.cs:2940);ReenterLine(count, waiting)(:1830) is the old re-enter line extracted, with a "wait for the one-time pin step, do not enter them again yet" text while waiting. The line is logged again when the pair (count, waiting) changes. The saved-password text inDarlingSecretsis unchanged.config_versionin the same transaction as the pins (part A), so every host's reload beacon picks it up on its next pass; at start the bump precedes the first view.Tests (local PostgreSQL in UTC; Total / Failed):
*PasswordKey*172 / 0 (12 skipped, platform-specific),*LegacyPin*8 / 0,*ReenterLine*4 / 0,*Secrets*58 / 0,*StoreConfig*43 / 0*Census*,*Ratchet*,*Scrub*,*Guard*,*Hygiene*,*Rung*,*Grant*,*TablesLive*,*CaggGroupIndexDrop*,*SchemaVersion*together: 1255 / 0ReenterLineTests(4),DarlingPasswordKeyRuntimeTests(the start-up order test, bounded toRunCollectionLoopAsync), and inDarlingPasswordKeyStoreLiveTeststhe two retry tests plus a not-waiting check in the existing "host that opens none" test