Is it safe to use a global wp nonce per user instead of a nonce per action?

With the user-name-based nonces, i think you are trying to protect yourself from CSRF attacks, this should work to some extent (hard to tell without the full source code), that being said the nonces should be assigned to a specific action (not only an action), so, for example, you do not assign it to a “delete item” action but rather to “delete item with ID=X” action.

Here is why you should do it like that.

Lets assume you have 2 users one with login “john” and the other with login “hacker”.

If you generate the nonce per user only then for each user you could generate a nonce like “{$user_name}-delete-item“. Any logged-in user would have this nonce generated and by looking in the source code they could find out what their nonce code is.

Now imagine the “hacker” user has a delete link which looks like this https://example.com/?delete-item=1000&nonce=qwertyuiop where (qwertyuiop is his generated nonce code).

The “hacker” user could manipulate the link and replace 1000 with for example 2000 and open the link in the browser. The nonce would validate and the “hacker” would be able to delete the item with id 2000 even though the “john” user owns it.

To improve the security you should generate a nonce name like “my-delete-item-{$id}” (in this case “my-delete-item-1000“), then nonce will be generated for a specific action, and if the “hacker” will change the ID from 1000 to 2000 the nonce will not validate as he does not have a nonce generated for “my-delete-item-2000” only for “my-delete-item-1000”.

Of course, i assume you have some additional code for checking if the user owns the 2000 item so you might get away with using nonces like that in this case, my point is just that if the nonce is not generated for a specific action it might create a false sense of security.

One final note, even with generating the nonces per specific action if possible you should have additional code for checking if the user can perform the given action. As pointed out in the nonces documentation https://codex.wordpress.org/WordPress_Nonces

Nonces should never be relied on for authentication or authorization, access control. Protect your functions using current_user_can(), always assume Nonces can be compromised.