Referring to Vadym Fedyukovych's answer:
Nullifier idea of ZCash could also help.
In this case, a proof is constructed with a nullifier, which is generated and kept by Alice, its hash is provided to Bob and Charlie, as a the Bob/Charlie's side of the authorization. If Alice wants to use this authorization, Alice must provide the nullifier to Bob and Charlie, and the authorization would be invalidated. Further attempts of using this nullifier would give an error stating that it has already been used. In this case, the authorization is associated with the nullifier, but not Alice herself.
Because the authorization can only be used once, we must add another number, provided by Bob or Charlie, known as the status-checker. This number, can be provided to Dan or any other party to check the status of the authorization, but not use it. The authorization is only considered used if Alice has disclosed the nullifier.
In conclusion, Alice may use the authorization by providing Bob or Charlie with the nullifier, and the authorization will be invalidated. Other parties may verify the validity of this authorization with the status checker.
For decentralization, the hash of the nullifier and Bob/Charlie's signature can be distributed, and by distributing the nullifier with Bob/Charlie's signature, the authorization is invalidated. In such a case, any third party (Dan in the example) may verify the status of the authorization without knowing Alice's identity, and only Bob/Charlie may nullify it. The employment of ring signatures may also conceal Bob and Charlie's identity as well.
Expansion to make this suit for most needs:
With the same example as yours, talking about Alice, Bob, Charlie and Dan. We disassociate any element in this system from the identities of Alice, Bob, Charlie and Dan, and associates them with their private/public key pairs. For each authorization, Alice generates a cryptographically secure random number n, which is both its authorization ID and nullifier. This n, is hashed and broadcasted, known as k. Bob/Charlie, upon receiving k, signs it and broadcasts the signature through the network. The signed message is broadcasted with another number generated by Bob/Charlie to be used to check the status. In such a way, there is an anonymous message on the network indicating that Bob/Charlie has authorized an anonymous figure. When Dan wants to check the status, he only needs to find the original authorization message, and whether there is a nullifier present. When Alice wants to use the authorization, she broadcasts the nullifier signed by Bob/Charlie, tagged with the status checking number, known as I. This message, if found by Dan, he would definitely know that the authorization has been used. Because there are no way of anyone else knowing the nullifier n, there are no way of tampering with the authorization.