Design System
Components

AccessDeniedState

The panel shown when a signed-in user may not see what they asked for.

Being refused is an expected outcome of a permission model, not a failure. That distinction drives the whole component: it carries a lock rather than a destructive icon, and it does not take role="alert" — it is the page content, not an interruption to it.

No pricing role assigned

Your account can sign in but has not been given a pricing role, so there is nothing here to show yet. Contact IT to be added to the right group.

Your account has conflicting roles

Two pricing roles are assigned to your account, so we cannot tell which permissions apply. Access is blocked until one is removed.Assigned: rms-revenue-manager, rms-product-team

You don't have access to Pricing Engine Admin

This area is limited to Revenue Managers.

Props

Prop

Type

Choosing between this and ErrorState

The two are easy to conflate and should not be.

SituationComponentWhy
We know who you are and you may not do thisAccessDeniedStateThe system worked correctly. Nothing to retry.
We could not work out what you may doErrorStateA lookup failed or a claim was malformed — that is a fault, so it announces itself and offers a retry.
You are not signed in at allneitherRedirect to sign-in. A panel telling someone they lack access when they simply have no session is a dead end.

Reaching for ErrorState on a refusal interrupts a screen reader for a page that rendered exactly as intended, and offers a retry button that cannot possibly help.

Writing the copy

title and description are props rather than baked in because the only useful sentence is the one that says what to do next, and that differs by cause. "Ask your manager to add you to the Revenue Manager group" and "your account has two conflicting roles" need different next steps.

  • Do name the thing the user needs, not the thing that failed.
  • Do use detail for facts support can act on — which roles conflict, which permission was required. It renders muted beneath the description, so it stays out of the way of the sentence that matters.
  • Don't ship a bare "Access denied" or "403". It is accurate and leaves the reader with nowhere to go.
  • Don't name internal permission strings in description. Put them in detail, where they read as diagnostics rather than as the message.

Accessibility

  • No role="alert", deliberately — see above. If you genuinely need to announce a permission lookup failure as it appears, that is ErrorState.
  • The lock icon is decorative; the title carries the meaning. Never rely on the icon alone.
  • Pass action when the user has somewhere else they can actually go. A panel with no exit in a full-page takeover leaves keyboard users stranded.

Do / Don't

  • Do gate the action, not the page, when the permission model allows viewing. Hiding a whole page from someone who is allowed to read it is a worse outcome than a disabled button.
  • Do pair it with the shown-but-disabled convention for individual controls — a permission-gated control stays visible and disabled with an explanatory tooltip, rather than disappearing.
  • Don't use it for an empty result. An empty list is a normal response; that is EmptyState.

On this page