Symptom
When a user clicks Add AWS Account, populateAwsAccountFields(undefined) calls generateExternalID() which auto-fills the External ID input with a fresh UUID X. If the user copies X into their AWS IAM trust policy, then closes the modal without saving (cancel / browser refresh / nav / auth-token expiry), and reopens Add AWS Account later, the input is populated with a different UUID Y. The user saves with Y but their trust policy still has X. STS AssumeRole then fails with AccessDenied: ExternalId mismatch and the operator has no easy way to see the mismatch.
This is a real workflow that produces a silently-broken account configuration with no diagnostic affordance.
Reproduction
- Settings → Accounts → Add AWS Account.
- Note the auto-generated External ID (call it
X). Open the AWS console, paste X into the IAM role's trust-policy sts:ExternalId condition. Save the role.
- Close the modal in CUDly without saving.
- Reopen Add AWS Account. Observe a different External ID (
Y) auto-fills the field.
- Fill the rest of the form, save. CUDly stores
Y.
- CUDly tries to assume the role → AWS rejects with
AccessDenied because Y ≠ X.
Expected
One of:
- Persist a draft external_id in
sessionStorage keyed on a draft-account-id, and only regenerate if no draft exists. Clear on successful save.
- Generate at save-time instead of open-time. Modal shows a placeholder ("auto-generated on save"); after save, the operator returns to a confirmation/instruction view that displays the now-frozen External ID + ready-to-paste trust-policy snippet.
- Explicit "Regenerate" button beside a stable, modal-lifetime ID — never silent regeneration.
- Diagnostic UI on AssumeRole failure that surfaces the configured ExternalId so the operator can compare against what's in their trust policy.
The first option is the smallest change: persist on every keystroke / focus-out, regenerate only when missing.
Severity
High. Most likely real-world breakage path for the External ID feature, with no user-facing affordance to detect or recover from it.
Test coverage gap
settings-accounts.test.ts:362 (add-aws-account-btn auto-generates the External ID) only verifies some value is generated — it doesn't lock in the stability across modal reopens behaviour that any of the mitigations above would introduce.
Related
Symptom
When a user clicks Add AWS Account,
populateAwsAccountFields(undefined)callsgenerateExternalID()which auto-fills the External ID input with a fresh UUIDX. If the user copiesXinto their AWS IAM trust policy, then closes the modal without saving (cancel / browser refresh / nav / auth-token expiry), and reopens Add AWS Account later, the input is populated with a different UUIDY. The user saves withYbut their trust policy still hasX. STSAssumeRolethen fails withAccessDenied: ExternalId mismatchand the operator has no easy way to see the mismatch.This is a real workflow that produces a silently-broken account configuration with no diagnostic affordance.
Reproduction
X). Open the AWS console, pasteXinto the IAM role's trust-policysts:ExternalIdcondition. Save the role.Y) auto-fills the field.Y.AccessDeniedbecauseY ≠ X.Expected
One of:
sessionStoragekeyed on a draft-account-id, and only regenerate if no draft exists. Clear on successful save.The first option is the smallest change: persist on every keystroke / focus-out, regenerate only when missing.
Severity
High. Most likely real-world breakage path for the External ID feature, with no user-facing affordance to detect or recover from it.
Test coverage gap
settings-accounts.test.ts:362(add-aws-account-btn auto-generates the External ID) only verifies some value is generated — it doesn't lock in the stability across modal reopens behaviour that any of the mitigations above would introduce.Related