본문으로 건너뛰기
Dot Design System
v0.3.1

권한

할 수 없는 이유와 가능한 대안을 막힌 행동 가까이에서 설명합니다.

목표

사용자가 볼 수 있거나 실행할 수 있는 범위를 예측하고, 제한을 만났을 때 이유와 해결 경로를 이해하게 한다. 권한 UI는 보안 경계를 대체하지 않으며 서버가 최종 판단을 소유한다.

시스템 경계

Dot package는 인증, 역할 모델, backend permission type과 PermissionGuard를 제공하지 않는다. 소비 제품이 도메인 정책과 서버 응답을 기준으로 권한을 결정하고 Dot 컴포넌트로 상태를 표현한다.

  • UI에서 숨겼다고 권한이 보호되는 것이 아니다.
  • 서버는 모든 read/write 요청을 다시 검증한다.
  • 역할 이름보다 사용자가 할 수 있는 구체적인 행동을 설명한다.
  • 권한 정책을 디자인 시스템 안에 hard-code하지 않는다.

숨김과 비활성 선택

숨긴다

  • 사용자가 기능의 존재를 알 필요가 없음
  • 노출 자체가 민감한 정보가 됨
  • 현재 제품 범위와 무관한 관리 기능

비활성 또는 제한 상태를 보여준다

  • 사용자가 해당 행동을 기대할 가능성이 높음
  • 다른 역할에서는 사용할 수 있음을 알아야 함
  • 권한 요청이나 담당자 문의로 해결 가능함

비활성 control만 두고 이유를 tooltip에만 숨기지 않는다. 인접 설명 또는 클릭 가능한 안내 경로를 제공한다.

정보 접근 상태

  • 목록 자체를 볼 수 없음: 페이지 수준 제한과 돌아갈 경로
  • 목록은 볼 수 있지만 일부 field가 민감함: 해당 cell의 제한 이유
  • 상세는 볼 수 있지만 편집할 수 없음: read-only 상태와 편집 권한 요청
  • 일부 record만 접근 가능: 전체 데이터라고 오해하지 않게 범위를 설명
  • 권한 확인 중: 결과를 추측해 잠깐 노출하지 않음
  • session 만료: 현재 입력 보존 가능 여부와 재인증 후 복귀 경로

행동 권한

  • create, edit, approve, publish, delete를 하나의 관리자 boolean으로 뭉치지 않는다.
  • 버튼 레이블은 권한 이름이 아니라 실제 행동을 말한다.
  • 승인·발행처럼 역할 분리가 필요한 workflow는 현재 담당자와 다음 요청 경로를 보여준다.
  • 권한이 실행 도중 바뀌면 서버 실패를 일반 오류로 숨기지 않고 최신 제한과 작성 내용 보존 방법을 설명한다.

권한 요청

요청 화면에는 다음을 포함한다.

  1. 필요한 행동
  2. 필요한 이유와 대상 범위
  3. 요청을 받을 사람 또는 팀
  4. 요청 후 상태 확인 위치
  5. 임시 우회나 read-only 대안
  • 권한을 얻으면 생기는 가치보다 보안 영향과 범위를 작게 숨기지 않는다.
  • 이미 요청했으면 중복 요청 대신 pending 상태를 보여준다.
  • 거절되면 이유 공개 범위와 다음 문의 경로를 제공한다.

상태

  • checking: 권한 확인 중, 민감 데이터 미노출
  • allowed: 정상 UI
  • read-only: 데이터는 보지만 변경 불가
  • partially allowed: 일부 field/record/action 제한
  • requestable: 권한 요청 가능
  • request pending: 요청자, 시각, 처리 주체
  • denied: 거절 또는 정책상 불가
  • expired: 기존 권한 만료
  • changed during work: 입력 보존과 최신 정책 안내
  • server rejected: UI 예상과 서버 판단 불일치, 안전하게 제한 상태로 갱신

좁은 화면

  • 제한 이유와 요청 행동을 icon-only로 축약하지 않는다.
  • table의 제한 cell을 숨겨 열이 어긋나게 만들지 말고 일관된 제한 표현을 쓴다.
  • 권한 요청 dialog가 정책 전문으로 길어지면 별도 route 또는 sheet를 사용한다.
  • 핵심 read-only 상태를 header나 workflow 영역에서 계속 확인할 수 있게 한다.

접근성

  • disabled button은 keyboard focus를 받지 못할 수 있으므로 이유를 button에만 연결하지 말고 인접한 설명에도 제공한다.
  • 읽기 전용 field는 필요한 경우 readOnly를 사용해 disabled와 의미를 구분한다.
  • 잠금 icon과 색만으로 제한을 전달하지 않는다.
  • 페이지 접근 제한 시 heading에 focus를 보내고 안전한 navigation을 제공한다.
  • 권한 요청 결과는 status/live region으로 알린다.
  • 민감한 값의 접근 가능한 이름이나 DOM content가 권한 없이 렌더되지 않게 한다.

예제

사용 코드 · TSX
<PageHeader
  title="운영 기준본"
  description="현재 계정은 내용을 볼 수 있지만 발행할 수 없어요."
  badge={<StatusPill tone="neutral">읽기 전용</StatusPill>}
  actions={<Button variant="outline">발행 권한 요청</Button>}
/>

제한된 행동 주변 설명:

사용 코드 · TSX
<div>
  <Button disabled aria-describedby="publish-permission-reason">
    운영 기준본 발행
  </Button>
  <p id="publish-permission-reason" className="mt-2 text-sm text-ink-subtle">
    발행 권한이 필요해요. 워크스페이스 소유자에게 요청할 수 있어요.
  </p>
</div>

피해야 할 사용

  • UI 숨김을 실제 보안 검증으로 간주
  • 모든 권한을 isAdmin 하나로 표현
  • 사용자가 기대하는 행동을 이유 없이 숨김
  • disabled button의 이유를 hover tooltip에만 제공
  • 제한된 데이터를 잠깐 렌더한 뒤 숨김
  • read-only와 disabled를 같은 의미로 사용
  • 작업 중 권한 변경으로 입력을 조용히 버림
  • 권한 요청 결과와 상태 확인 경로 생략

검토 체크

  • 서버가 모든 read/write 권한을 최종 검증한다.
  • 숨김과 비활성의 선택 이유가 사용자 기대에 맞다.
  • 역할명이 아니라 가능한 행동과 제한 범위를 설명한다.
  • checking 중 민감 데이터를 노출하지 않는다.
  • read-only, partial, request pending, denied, expired가 정의돼 있다.
  • 작업 중 권한 변경에서도 입력 보존 경로가 있다.
  • disabled 이유가 keyboard와 screen reader 사용자에게도 보인다.
  • 요청 대상, 범위, 처리 상태와 대안이 명확하다.
  • UI와 서버 판단이 다를 때 fail closed한다.

관련 항목