The best way I've seen to handle this is, indeed, to pre-build your validation rules and other logic with some in-built switch. Custom labels are probably the best suited to this if you want to universally turn on/off validation; custom settings would be a perfect fit (since they can be global or user-scoped) but you can't conveniently access them in a number of places. I've seen various other approaches like user role or user name, but those are more brittle.
The problem of course is that you need to either build your org from the ground up with this in mind, or retrofit this logic in hundreds of places. But it's such a common need you'll just get in the habit of putting it everywhere.
If your logic warrants it, I recommend building in more than an on-off switch: build in a number of "switch off" levels so you can gracefully step down to the level of logic you need when data loading. It will cost you almost no more up-front but you'll be thankful. If using custom settings you'll want something compatible with CONTAINS checks. e.g. "123456789" = all checks are on. But removing "9" causes something like all email and chatter notifications to be disabled, "8" disables something like "soft" validation rules, and all of those have checks like
if (Label.myLabel.contains('9')) { // do my stuff
IF(CONTAINS($Label.myLabel, "8"), [fire my semi-optional user-facing validation rule], [auto-pass my rule])
The disadvantage with custom labels of course is that they will have system-wide effects for all users, which won't work for many customers. In those cases, you are probably better off using a single named user or role or profile in these rules (either dedicated API account, or a sys admin user/role/profile) and doing the same type of check against something like username or role AND then using the contents of something like user alias if you want granular on/off control.