The risky part of bulk administration is usually uncertainty, not the API call itself. Are these the right projects? Is the email correct? Is this a role update or a removal? Is the app authorized in the same account the operator is viewing?
A dry-run should reduce those questions before the first write. Treat it as a review document, not a decorative confirmation screen.
What a dry-run should answer
A useful dry-run gives the operator enough information to stop before damage happens. It should describe the planned operation in operational language, not just API language.
- Which projects will be touched?
- Which users are already present, missing, or inactive?
- Which rows would be skipped and why?
- How many write actions would run if the operator confirms?
- Which account or hub authorization is being used?
Separate read, preview, and write permissions
Read-only review should be cheap and frequent. Writes should require a clearer path: valid credentials, authorized integration, visible project set, and a bounded batch size. This separation makes the admin workflow less brittle.
Cap the blast radius
Batch limits are a design tool. They force large changes into visible chunks, which makes progress easier to understand and failures easier to recover from. The cap should be high enough for real work, but low enough that a mistake is still explainable.
Audit trail closes the loop
After execution, the question changes from "what will happen?" to "what happened?" Store enough detail to reconstruct the decision: target projects, submitted rows, skipped rows, API failures, retry attempts, and final result.