Splendida domanda!
Per prima cosa, facciamo alcune ipotesi su "meglio".
Presumo che non ti importi molto dello spazio su disco:una maschera di bit è efficiente dal punto di vista dello spazio, ma non sono sicuro che importi molto se stai utilizzando un server SQL.
Immagino che ti interessi la velocità. Una maschera di bit può essere molto veloce quando si utilizzano i calcoli, ma non sarà possibile utilizzare un indice quando si interroga la maschera di bit. Questo non dovrebbe avere molta importanza, ma se vuoi sapere quali utenti hanno accesso alla creazione, la tua query sarebbe qualcosa del tipo
select * from user where permsission & CREATE = TRUE
(non ho accesso a SQL Server oggi, in viaggio). Quella query non sarebbe in grado di utilizzare un indice a causa dell'operazione matematica, quindi se hai un numero enorme di utenti, questo sarebbe piuttosto doloroso.
Presumo che ti interessi la manutenibilità. Dal punto di vista della manutenibilità, la maschera di bit non è così espressiva come il dominio del problema sottostante come la memorizzazione di autorizzazioni esplicite. Quasi sicuramente dovresti sincronizzare il valore dei flag della maschera di bit su più componenti, incluso il database. Non impossibile, ma dolore alla schiena.
Quindi, a meno che non ci sia un altro modo per valutare "meglio", direi che il percorso della maschera di bit non è buono come archiviare le autorizzazioni in una struttura di database normalizzata. Non sono d'accordo sul fatto che sarebbe "più lento perché devi fare un join" - a meno che tu non abbia un database totalmente disfunzionale, non sarai in grado di misurarlo (mentre le query senza il vantaggio di un indice attivo possono diventare notevolmente più lento con anche poche migliaia di record).