권한

강력한 기능을 위한 권한 상호작용

W3C 작업 초안

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2026/WD-permissions-20261026/
최신 공개 버전:
https://www.w3.org/TR/permissions/
최신 편집자 초안:
https://w3c.github.io/permissions/
히스토리:
https://www.w3.org/standards/history/permissions/
커밋 히스토리
편집자:
Marcos Cáceres (Apple Inc.)
Mike Taylor (Google LLC)
이전 편집자:
Mounir Lamouri (Google LLC)
Jeffrey Yasskin (Google LLC)
피드백:
GitHub w3c/permissions (풀 리퀘스트, 새 이슈, 오픈 이슈)
브라우저 지원:
Chrome logo43
Edge logo79
Firefox logo46
Safari logo16.0
데스크탑
Android Chrome logo156
Android Firefox logo158
Android UC logo15.5
iOS Safari logo16.0
Samsung Internet logo4
모바일
자세히 보기

요약

이 명세는 다른 명세들이 브라우저 권한과 상호작용할 때 사용할 수 있는 공통 인프라를 정의합니다. 이 권한들은 사용자가 플랫폼의 "강력한 기능"에 대한 접근을 허용하거나 거부하는 선택을 나타냅니다. 개발자를 위해, 이 명세는 강력한 기능의 권한 상태를 조회하고, 해당 권한이 변경될 때 알림을 받을 수 있는 API를 표준화합니다.

이 문서의 상태

이 섹션은 본 문서가 공개된 시점의 상태를 설명합니다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인 에서 확인할 수 있습니다.

이 문서는 작업 중입니다.

이 문서는 웹 애플리케이션 보안 작업 그룹에서 권고안 트랙을 사용하여 작업 초안으로 발행되었습니다.

작업 초안으로 발행된 것은 W3C 및 회원의 지지를 의미하지 않습니다.

이 문서는 초안이며 언제든지 업데이트, 대체, 또는 폐기될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 부적절합니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었습니다. W3C는 공개 특허 공개 목록을 유지합니다. 이 목록에는 그룹 산출물과 관련하여 제출된 특허 공개가 있으며, 특허 공개 방법에 대한 지침도 포함되어 있습니다. 개인이 특정 특허가 필수 청구항을 포함한다고 판단할 경우, W3C 특허 정책 6절에 따라 정보를 공개해야 합니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서를 따릅니다.

1. 소개

이 섹션은 규범적이지 않습니다.

명세는 강력한 기능으로 명확하게 식별되는 기능을 정의할 수 있습니다. 이러한 기능은 개인정보 보호, 보안, 성능에 중요한 영향을 미칠 수 있으므로 "강력하다"고 합니다. 따라서 사용자는 사용자 에이전트가 명시적 권한을 주기 전까지 사이트가 이러한 기능을 사용할 수 없도록 막아주기를 기대하며, 일반적으로 이 권한은 제한된 기간 동안만 부여됩니다. 사이트가 강력한 기능을 사용하도록 허용하는 명시적 권한은 일반적으로 아래 그림과 같이 브라우저 UI를 통해 제공되고 제어됩니다.

왼쪽은 example.com이 알림을 보내려 한다는 메시지와 허용/허용하지 않음 버튼이 있는 알림 프롬프트의 모형이고, 오른쪽은 example 사이트에 카메라와 마이크 권한을 요청하는 URL 바 근처의 프롬프트 모형입니다.
그림 1 다양한 권한 프롬프트 유형의 예시 스케치

이 의미에서 권한은 특정 유형의 기능, 특히 "강력한 기능"에 대한 사용자 동의의 현재 상태를 나타냅니다. 궁극적으로 사용자는 이러한 권한을 직접 제어할 수 있으며, 사용자 환경설정을 통해 수동으로 권한을 부여하거나 거부할 수 있습니다. 또한 사용자 에이전트는 사용자가 권한을 관리할 수 있도록, 예를 들어 귀찮은 프롬프트를 숨기거나 자동으로 거부하고, 사용자가 일정 기간 사이트를 방문하지 않을 경우 부여된 권한을 자동으로 만료시키는 등의 도움을 제공합니다.

사용자가 위치, 카메라, 마이크, 모션 센서, 알림 권한의 기본값을 설정하거나 재설정할 수 있는 설정 페이지의 모형입니다.
그림 2 사이트별 권한 제어 UI의 예시 스케치

2. 사용 예시

이 섹션은 규범적이지 않습니다.

이 예시는 Permissions API를 사용해 지역 뉴스를 Geolocation API로 보여줄지, 기능을 추가할 수 있는 버튼을 보여줄지 결정합니다.

예시 1: .state 속성 사용
const { state } = await navigator.permissions.query({
  name: "geolocation"
});
switch (state) {
  case "granted":
    showLocalNewsWithGeolocation();
    break;
  case "prompt":
    showButtonToEnableLocalNews();
    break;
  case "denied":
    showNationalNews();
    break;
}

이 예시는 "geolocation"과 "notifications" 강력한 기능의 상태를 동시에 확인합니다:

예시 2: 여러 권한 상태 확인
const queryPromises = ["geolocation", "notifications"].map(
  name => navigator.permissions.query({ name })
);
for await (const status of queryPromises) {
  console.log(`${status.name}: ${status.state}`);
}

이 예시는 사용 가능한 카메라의 권한 상태를 확인합니다.

예시 3: 여러 카메라 권한 상태 확인
const devices = await navigator.mediaDevices.enumerateDevices();

// 비디오 입력만 필터링하고 쿼리 객체로 매핑
const queries = devices
  .filter(({ kind }) => kind === "videoinput")
  .map(({ deviceId }) => ({ name: "camera", deviceId }));

const promises = queries.map((queryObj) =>
  navigator.permissions.query(queryObj)
);

try {
  const results = await Promise.all(promises);
  // 각 카메라의 상태를 로그로 출력
  results.forEach(({ state }, i) => console.log("Camera", i, state));
} catch (error) {
  console.error(error);
}

3. 모델

이 섹션은 웹 플랫폼에서 권한을 사용하여 강력한 기능을 제어하는 모델을 정의합니다.

3.1 권한

권한은 웹 애플리케이션이 강력한 기능을 사용하도록 허용하는 사용자의 결정을 나타냅니다. 이 결정은 권한 상태로 나타냅니다.

명시적 권한은 사용자가 웹 애플리케이션에 부여하여 강력한 기능을 사용할 수 있도록 하는 것을 의미합니다.

참고: 제한 사항 및 확장성

개념적으로 권한은 강력한 기능에 대해 다음 상태 중 하나일 수 있습니다:

"거부됨":
사용자 또는 사용자를 대신하는 사용자 에이전트가 이 강력한 기능에 대한 접근을 거부했습니다. 호출자는 해당 기능을 사용할 수 없습니다.
"허용됨":
사용자 또는 사용자를 대신하는 사용자 에이전트가 명시적 권한을 부여하여 강력한 기능을 사용할 수 있도록 했습니다. 호출자는 사용자 에이전트가 사용자에게 권한을 요청하지 않고도 해당 기능을 사용할 수 있습니다.
"프롬프트":
사용자가 해당 기능을 사용할 명시적 권한을 부여하지 않았습니다(즉, "거부됨"과 동일합니다). 또한 호출자가 해당 기능을 사용하려고 하면 사용자 에이전트가 사용자에게 권한을 요청하거나 해당 기능에 대한 접근이 "거부됨" 상태가 됨을 의미합니다.

사용자의 의도에 관한 새로운 정보를 확인하기 위해, 사용자 에이전트는 사용자의 의도에 관한 정보를 수집하고 해석할 수 있습니다. 이 정보는 명시적인 사용자 동작, 관련 사용자와 다른 사용자 모두의 집계된 행동 또는 이 명세에서 예상하지 못한 암시적 신호에서 얻을 수 있습니다.

참고: 무엇이 암시적 신호를 구성하는가?

모든 권한에는 수명이 있으며, 이는 특정 권한이 "허용됨" 상태로 유지되다가 다시 기본 상태로 돌아갈 때까지의 기간입니다. 수명은 특정 Realm이 소멸될 때까지, 특정 최상위 브라우징 컨텍스트가 소멸될 때까지, 특정 시간 동안 또는 무한할 수 있습니다. 수명은 사용자가 명시적 권한을 부여하여 기능을 사용할 수 있도록 할 때 최종 사용자와 사용자 에이전트 간에 협의됩니다. 일반적으로 일부 권한 UI 또는 사용자 에이전트가 정의한 정책을 통해 이루어집니다.

모든 권한에는 기본 상태 (일반적으로 "프롬프트")가 있으며, 이는 사용자가 아직 상태로서, 해당 권한은 명시적 권한을 부여하여 기능을 사용하도록 하지 않았거나, 해당 권한의 수명이 만료되어 재설정된 경우 이 상태에 있습니다.

3.2 권한 저장소

사용자 에이전트는 권한 저장소 항목의 목록인 하나의 권한 저장소를 유지합니다. 각각의 특정 항목은 해당 설명자와 키로 식별되며, 이 목록에는 최대 한 번만 나타날 수 있습니다.

사용자 에이전트는 각각의 권한의 수명이 만료되면 항목을 권한 저장소에서 제거할 수 있습니다.

권한 저장소 항목은 PermissionDescriptor 설명자, 권한 키 키, 그리고 상태 상태로 구성된 튜플입니다.

PermissionDescriptor descriptor와 권한 키 key가 주어졌을 때 권한 저장소 항목을 가져오려면:

  1. 사용자 에이전트의 권한 저장소에 설명자가 descriptor이고, 키가 descriptor가 주어졌을 때 key와 동일한 항목을 포함하면, 해당 항목을 반환합니다.
  2. null을 반환합니다.

PermissionDescriptor descriptor, 권한 키 key, 그리고 상태 state가 주어졌을 때 권한 저장소 항목을 설정하려면 다음 단계를 실행합니다:

  1. newEntry를 권한 저장소 항목으로 새로 두며, 그 설명자는 descriptor이고, 그 키는 key이며, 그 상태는 state입니다.
  2. 사용자 에이전트의 권한 저장소에 설명자가 descriptor이고, 키가 descriptor가 주어졌을 때 key와 동일한 항목을 포함하면, 해당 항목을 newEntry로 교체하고 이 단계를 중단합니다.
  3. newEntry를 사용자 에이전트의 권한 저장소에 추가합니다.

PermissionDescriptor descriptor와 권한 키 key가 주어졌을 때 권한 저장소 항목을 제거하려면 다음 단계를 실행합니다:

  1. 설명자가 descriptor이고, 키가 descriptor가 주어졌을 때 key와 동일한 항목을 사용자 에이전트의 권한 저장소에서 제거합니다.

권한 키는 기능의 권한 키 유형으로 정의되는 유형을 가집니다.

참고

PermissionDescriptor descriptor가 주어졌을 때, 권한 키 key1이 권한 키 key2와 동일한지 확인하려면 다음 단계를 실행합니다:

  1. key1이 descriptor의 권한 키 유형이 아니거나 key2가 descriptor의 권한 키 유형이 아니면, false를 반환합니다.
  2. descriptor의 name으로 명명된 기능에 대해 권한 키 비교 알고리즘을 실행한 결과를 반환하며, key1과 key2를 전달합니다.

3.3 강력한 기능

강력한 기능은 사용자가 해당 기능을 사용하기 전에 명시적 권한을 부여하는 웹 플랫폼 기능(일반적으로 API)입니다. 몇 가지 주목할 만한 예외(예: Notifications API 표준)를 제외하면, 대부분의 강력한 기능은 또한 정책 제어 기능입니다. 강력한 기능이 또한 정책 제어 기능인 경우, [Permissions-Policy]는 문서가 주어진 기능을 사용하도록 허용되는지를 제어합니다. 즉, 강력한 기능은 해당 명시적 권한에 대응하는 문서에 권한이 위임된 경우에만 사용자에게 이를 요청할 수 있습니다. 이 위임은 대응하는 정책 제어 기능을 통해 이루어집니다(아래 예를 참조하십시오). 이후 해당 기능에 대한 접근은 사용자가 "허용됨" 권한을 가지고 있는지, 또는 권한 부여와 동등한 일부 기준을 충족하는지에 따라 결정됩니다.

강력한 기능은 이름(예: "geolocation")이라는 문자열 리터럴로 식별됩니다.

사용자 에이전트는 사용자가 강력한 기능을 사용할 권한을 가졌는지 환경 설정 객체를 통해 추적합니다.

3.3.1 측면

각 강력한 기능은 추가 측면을 0개 이상 정의할 수 있습니다. 측면은 WebIDL dictionary로 정의되며, 상속을 통해 PermissionDescriptor에서 파생되고, WebIDL 인터페이스의 권한 디스크립터 타입으로 사용됩니다.

3.4 권한 작업 소스

권한 작업 소스는 이 명세에서 권한 관련 작업을 수행하는 데 사용되는 작업 소스입니다.

4. 강력한 기능 명세화

적합한 명세가 강력한 기능을 명세화 할 때:

  1. 반드시 강력한 기능에 이름을 ascii 소문자 문자열로 지정해야 합니다.
  2. 선택적으로 권한 디스크립터 타입을 정의할 수 있으며, 이는 PermissionDescriptor를 상속받습니다.
  3. 선택적으로 측면을 0개 이상 정의할 수 있습니다.
  4. 선택적으로 아래에 정의된 알고리즘 및 타입이 특정 강력한 기능에 적합하지 않은 경우 오버라이드할 수 있습니다.
  5. 반드시 강력한 기능을 권한 레지스트리에 등록해야 합니다.

새로 명세된 강력한 기능을 권한 레지스트리에 등록하면, 작업 그룹이 피드백을 제공하고 본 명세와의 통합이 효과적으로 이루어졌는지 확인할 수 있습니다.

권한 설명자 유형:

PermissionDescriptor 또는 그 하위 유형 중 하나입니다. 지정되지 않은 경우 기본값은 PermissionDescriptor입니다.

기능은 설명자 인스턴스에 대해 부분 순서를 정의할 수 있습니다. descriptorA가 descriptorB보다 강하다면, descriptorA의 권한 상태가 "granted"일 경우, descriptorB의 권한 상태도 반드시 "granted"여야 하며, descriptorB의 권한 상태가 "denied"일 경우, descriptorA의 권한 상태도 반드시 "denied"여야 합니다.

권한 상태 제약 조건:
사용자 에이전트가 설명자의 권한 상태로 반환할 수 있는 값에 대한 제약 조건입니다. 기본값은 사용자의 의도를 넘어서는 제약 조건이 없는 것입니다.
추가 권한 데이터 유형:

일부 강력한 기능에는 단순히 PermissionState보다 더 많은 관련 정보가 있습니다. 이러한 각 기능은 추가 권한 데이터 유형을 정의합니다.

참고

예를 들어, getUserMedia()는 사용자가 접근 권한을 부여한 카메라가 어떤 것인지 확인해야 합니다.

DOMString name이 이러한 기능 중 하나의 이름인 경우, 선택적인 환경 설정 객체 settings에 대한 name의 추가 권한 데이터는 다음 알고리즘의 결과입니다:

  1. settings가 전달되지 않았다면, 이를 현재 설정 객체로 설정합니다.
  2. 동일한 name 및 settings로 이 알고리즘을 이전에 호출하여 previousResult를 반환한 적이 있고, 해당 호출 이후 사용자 에이전트가 사용자의 의도에 관한 새로운 정보를 받지 않았다면, previousResult를 반환합니다.
  3. name에 대한 모든 추가 권한 데이터 제약 조건을 고려하여, 사용자의 의도에 대한 UA의 판단과 일치하는 name의 추가 권한 데이터 유형 인스턴스를 반환합니다.

지정된 경우, 추가 권한 데이터 알고리즘을 이 기능에 사용할 수 있습니다.

선택적 추가 권한 데이터 제약 조건:
사용자 에이전트가 강력한 기능의 추가 권한 데이터로 반환할 수 있는 값에 대한 제약 조건입니다. 기본값은 사용자의 의도를 넘어서는 제약 조건이 없는 것입니다.
권한 결과 유형:
PermissionStatus 또는 그 하위 유형 중 하나입니다. 지정되지 않은 경우 기본값은 PermissionStatus입니다.
권한 쿼리 알고리즘:

권한 설명자 유형의 인스턴스와 권한 결과 유형의 새 인스턴스 또는 기존 인스턴스를 받아, 해당 권한 결과 유형 인스턴스를 쿼리 결과로 업데이트합니다. 이는 Permissions의 query(permissionDesc) 메서드와 PermissionStatus 업데이트 단계에서 사용됩니다. 지정되지 않은 경우 기본값은 기본 권한 쿼리 알고리즘입니다.

PermissionDescriptor permissionDesc와 PermissionStatus status가 주어졌을 때 기본 권한 쿼리 알고리즘은 다음 단계를 실행합니다:

  1. status의 state를 permissionDesc의 권한 상태로 설정합니다.
권한 키 유형:

기능이 사용하는 권한 키의 유형입니다. 기본값은 오리진입니다. 사용자 지정 권한 키 유형을 지정하는 기능은 반드시 권한 키 생성 알고리즘도 지정해야 합니다.

권한 키 생성 알고리즘:

오리진 origin과 오리진 embedded origin을 받아 새 권한 키를 반환합니다. 지정되지 않은 경우 기본값은 기본 권한 키 생성 알고리즘입니다. 사용자 지정 권한 키 생성 알고리즘을 지정하는 기능은 반드시 권한 키 비교 알고리즘도 지정해야 합니다.

오리진 origin과 오리진 embedded origin이 주어졌을 때 기본 권한 키 생성 알고리즘은 다음 단계를 실행합니다:

  1. origin을 반환합니다.
참고: 권한 위임
권한 키 비교 알고리즘:

두 개의 권한 키를 받아 두 키가 동일한지 나타내는 불리언을 반환합니다. 지정되지 않은 경우 기본값은 기본 권한 키 비교 알고리즘입니다.

권한 키 key1과 key2가 주어졌을 때 기본 권한 키 비교 알고리즘은 다음 단계를 실행합니다:

  1. key1이 key2와 동일 오리진인지 반환합니다.
권한 취소 알고리즘:

인수를 받지 않습니다. 권한 상태 또는 추가 권한 데이터의 결과 변경과 동기화 상태를 유지해야 하는 구현의 다른 부분을 업데이트합니다.

지정되지 않은 경우 기본값은 사용자의 권한 취소에 대응을 실행하는 것입니다.

권한 수명:

하나 이상의 강력한 기능을 정의하는 명세는 특정 기능에 가장 적합한 권한 수명을 제안하는 것이 좋습니다. 권한의 수명을 결정하는 데 관한 몇 가지 지침은 아래에 설명되어 있으며, 사용자 개인정보 보호를 특히 강조합니다. 수명이 지정되지 않은 경우 사용자 에이전트가 이를 제공합니다.

오리진에 대한 권한 수명이 만료되면:

  1. 권한을 기본 권한 상태로 되돌립니다(예: 다시 "프롬프트"로 설정합니다).
  2. 오리진과 연결된 각 browsing context(있는 경우)에 대해, browsing context의 전역 객체를 사용하여 전역 작업을 큐에 추가하고, 권한 작업 소스에서 권한 취소 알고리즘을 실행하도록 합니다.
참고: 권한의 수명 결정
기본 권한 상태:

강력한 기능의 권한에 대한 기본 상태 역할을 하는 PermissionState 값입니다.

지정되지 않은 경우 권한의 기본 상태는 "prompt"입니다.

기본 강력한 기능은 위의 모든 타입과 알고리즘을 기본값으로 지정한 강력한 기능입니다.

5. 권한과 인터페이스하는 알고리즘

5.1 현재 권한 상태 읽기

현재 권한 상태 가져오기 알고리즘은 name name과 선택적 환경 설정 객체 settings를 받아 다음 단계를 실행합니다. 이 알고리즘은 PermissionState 열거형 값을 반환합니다.

  1. descriptor를 새로 생성된 PermissionDescriptor로 하며, name을 name으로 초기화합니다.
  2. descriptor의 권한 상태를 settings와 함께 반환합니다.

descriptor의 권한 상태 알고리즘은 선택적 환경 설정 객체 settings를 받아 다음 단계를 실행합니다. PermissionState 열거형 값을 반환합니다:

  1. settings가 전달되지 않았으면 현재 설정 객체로 설정합니다.
  2. settings가 비보안 컨텍스트면 "denied" 반환.
  3. feature를 descriptor의 name으로 설정.
  4. 만약 feature에 대해 정책 제어 기능이 있고 settings의 관련 글로벌 객체가 연결된 Document를 가진다면:
    1. document를 settings의 관련 글로벌 객체의 연결된 Document로 설정.
    2. document가 feature 사용이 허용되지 않은 경우, "denied" 반환.
  5. key를 descriptor, settings의 최상위 origin과 settings의 origin을 사용하여 권한 키 생성의 결과로 둔다.
  6. entry를 권한 저장소 엔트리 가져오기 알고리즘으로 descriptor와 key로 얻음.
  7. entry가 null이 아니면, entry의 state에서 PermissionState 열거형 값을 반환.
  8. feature의 권한 상태를 나타내는 PermissionState 열거형 값을 반환하며, descriptor의 name에 대한 권한 상태 제약을 고려.

약칭으로, DOMString name의 권한 상태는 PermissionDescriptor의 name을 name으로 설정한 경우의 권한 상태입니다.

5.2 강력한 기능 사용 권한 요청

사용 권한 요청 알고리즘은 descriptor에 대해 다음 단계를 실행합니다. 이 알고리즘은 "granted" 또는 "denied"를 반환합니다.

  1. current state를 descriptor의 권한 상태로 설정.
  2. current state가 "prompt"가 아니면, current state를 반환하고 단계 중단.
  3. 사용자에게 명시적 권한을 요청하여 descriptor가 설명하는 강력한 기능을 사용할 수 있도록 함.
  4. 사용자가 명시적 권한을 부여하면 current state를 "granted"로, 아니면 "denied"로 설정. 사용자의 상호작용은 해당 오리진에 대한 사용자 의도에 대한 새로운 정보를 제공할 수 있음.
    참고

    이 알고리즘은 권한 UI 세부사항 및 사용자 에이전트가 사용자 의도를 추론하는 방법에 대해 일부러 모호하게 기술되어 있습니다. 사용자 에이전트는 이 프레임워크 내에서 다양한 UI 구현을 탐구할 수 있습니다.

  5. settings를 현재 settings object로 설정한다.
  6. key를 descriptor, settings의 최상위 origin과 settings의 origin을 사용하여 권한 키 생성의 결과로 둔다.
  7. 작업 큐에 추가 하여 현재 설정 객체의 책임 이벤트 루프에서 권한 저장소 엔트리 설정 알고리즘을 descriptor, key, current state로 실행.
  8. current state 반환.

약식 표현으로, 사용 권한을 요청하는 것, 즉 DOMString name에 대해 요청하는 것은, 사용 권한을 요청하는 것, 즉 PermissionDescriptor의 name 멤버를 name으로 설정하여 요청하는 것과 같습니다.

5.3 사용자에게 선택 프롬프트

사용자에게 선택 프롬프트 알고리즘은 특정 options와 descriptor, 선택적 boolean allowMultiple(기본값 false)을 받아 다음 단계를 실행합니다. 이 알고리즘은 "denied" 또는 사용자의 선택을 반환합니다.

  1. descriptor의 권한 상태가 "denied"이면, "denied" 반환하고 단계 중단.
  2. descriptor의 권한 상태가 "granted"라면, 사용자 에이전트는 사용자가 선택한 options 중 하나(또는 allowMultiple가 true면 여러 개)를 반환하고 단계 중단할 수 있습니다. 프롬프트 없이 반환한 경우, 이후 동일한 옵션 집합 및 동일 descriptor에 대해 선택 프롬프트를 다시 실행해도 동일한 선택을 반환해야 하며, 사용자 에이전트가 사용자 의도에 대한 새로운 정보를 받지 않은 경우에 한합니다.
  3. 사용자에게 하나 이상의 options 또는 권한 거부를 선택하도록 요청하고, 사용자가 선택할 때까지 대기:
    1. 호출 알고리즘이 프롬프트에 추가 정보를 포함하도록 지정했다면 포함합니다.
    2. allowMultiple가 false면 options에서 하나만 선택 가능, 아니면 여러 개 선택 가능.
  4. 사용자가 하나 이상 선택했다면 그것을 반환, 아니면 "denied" 반환.
    참고

    이 알고리즘은 권한 UI 세부사항 및 사용자 에이전트가 사용자 의도를 추론하는 방법에 대해 일부러 모호하게 기술되어 있습니다. 사용자 에이전트는 이 프레임워크 내에서 다양한 UI 구현을 탐구할 수 있습니다(예: 프롬프트가 타임아웃되어 사용자가 명시적으로 선택하지 않은 경우 "denied"를 자동 반환).

약식 표현으로, 사용자에게 선택하도록 요청하는 것, 즉 DOMString name과 연결된 옵션 중에서 선택하도록 요청하는 것은, 사용자에게 선택하도록 요청하는 것, 즉 PermissionDescriptor의 name 멤버를 name으로 설정하고 이와 연결된 해당 옵션 중에서 선택하도록 요청하는 것과 같습니다.

5.4 사용자가 권한을 철회할 때 반응

사용자 에이전트가 사용자가 더 이상 PermissionDescriptor descriptor로 설명되는 기능을 권한 키 key로 설명되는 컨텍스트에서 사용할 권한을 부여할 의사가 없음을 알게 되면, 사용자의 권한 취소에 대응하기 위해 다음 단계를 실행합니다:

  1. descriptor의 name의 권한 취소 알고리즘을 실행합니다.
  2. descriptor와 key를 사용하여 권한 저장소 항목을 제거합니다.

6. 권한 API

WebIDL[Exposed=(Window)]
partial interface Navigator {
  [SameObject] readonly attribute Permissions permissions;
};

[Exposed=(Worker)]
partial interface WorkerNavigator {
  [SameObject] readonly attribute Permissions permissions;
};

6.2 Permissions 인터페이스

WebIDL[Exposed=(Window,Worker)]
interface Permissions {
  Promise<PermissionStatus> query(object permissionDesc);
};

dictionary PermissionDescriptor {
  required DOMString name;
};

6.2.1 query() 메서드

query() 메서드가 호출될 때, 사용자 에이전트는 반드시 아래 권한 쿼리 알고리즘을 permissionDesc와 함께 실행해야 합니다:

  1. 만약 this의 관련 글로벌 객체가 Window 객체라면:
    1. 현재 설정 객체의 연결된 Document가 완전히 활성 상태가 아니면, 거부된 promise를 반환하며, "InvalidStateError" DOMException을 포함합니다.
  2. rootDesc를 permissionDesc가 가리키는 객체로 하여, IDL 값으로 변환합니다. 타입은 PermissionDescriptor.
  3. 변환 과정에서 예외가 발생하면, 해당 예외로 거부된 promise를 반환합니다.
  4. rootDesc["name"] 값이 지원되지 않으면, 거부된 promise를 TypeError와 함께 반환.
    참고: 왜 enum이 아닌가?
  5. typedDescriptor를 permissionDesc가 가리키는 객체로 하여, rootDesc의 name에 해당하는 권한 디스크립터 타입의 IDL 값으로 변환.
  6. 변환 과정에서 예외가 발생하면, 해당 예외로 거부된 promise를 반환.
  7. promise를 새 promise로 생성.
  8. promise를 반환하고, 병렬로 계속 진행:
    1. status를 PermissionStatus 생성 알고리즘으로 typedDescriptor와 함께 생성.
    2. query를 status의 [[query]] 내부 슬롯 값으로 설정.
    3. query의 name에 해당하는 권한 쿼리 알고리즘을 query와 status로 실행.
    4. 글로벌 작업을 큐에 추가 하여 권한 작업 소스에 this의 관련 글로벌 객체를 전달해 resolve로 promise를 status로 완료.

6.3 PermissionStatus 인터페이스

WebIDL[Exposed=(Window,Worker)]
interface PermissionStatus : EventTarget {
  readonly attribute PermissionState state;
  readonly attribute DOMString name;
  attribute EventHandler onchange;
};

enum PermissionState {
  "granted",
  "denied",
  "prompt",
};

PermissionStatus 인스턴스는 [[query]] 내부 슬롯과 함께 생성되며, 이 슬롯은 기능의 권한 디스크립터 타입의 인스턴스입니다.

"granted", "denied", 그리고 "prompt" 열거형 값은 각각 "granted", "denied", 그리고 "prompt" 개념을 나타냅니다.

6.3.1 인스턴스 생성

PermissionStatus 생성 알고리즘은 주어진 PermissionDescriptor permissionDesc에 대해 다음 단계를 실행합니다:

  1. name을 permissionDesc의 name으로 설정.
  2. 단언: name으로 식별되는 기능은 사용자 에이전트가 지원해야 합니다.
  3. status를 name으로 식별되는 권한 결과 타입의 새 인스턴스로 생성:
    1. status의 [[query]] 내부 슬롯을 permissionDesc로 초기화.
    2. status의 name을 name으로 초기화.
  4. status 반환.

6.3.2 name 속성

name 속성은 초기화된 값을 반환합니다.

6.3.3 state 속성

state 속성은 현재 인스턴스에 설정된 최신 값을 반환합니다.

6.3.4 onchange 속성

onchange 속성은 이벤트 핸들러이며, 이에 대응되는 이벤트 핸들러 이벤트 타입은 change입니다.

사용자 에이전트가 PermissionStatus 인스턴스 status의 상태가 변경됨을 인지하면, 비동기로 PermissionStatus 업데이트 단계 알고리즘을 실행합니다:

  1. this의 관련 글로벌 객체가 Window 객체라면:
    1. document를 status의 관련 글로벌 객체의 연결된 Document로 설정.
    2. document가 null이거나 document가 완전히 활성 상태가 아니면, 이 알고리즘 중단.
  2. query를 status의 [[query]] 내부 슬롯 값으로 설정.
  3. query의 name에 해당하는 권한 쿼리 알고리즘을 query와 status로 실행.
  4. 작업 큐에 추가하여 권한 작업 소스에 change 이벤트를 status에 발생시킴.

6.3.5 가비지 컬렉션

PermissionStatus 객체는 change 타입의 이벤트 리스너가 있을 때 가비지 컬렉션되어서는 안 됩니다.

7. 적합성

비규범적으로 표시된 섹션 외에도, 이 명세의 모든 작성 지침, 도표, 예시, 참고 사항은 비규범적입니다. 그 외 모든 내용은 규범적입니다.

이 문서에서 MAY, MUST, MUST NOT, OPTIONAL, SHOULD 와 같은 키워드는 BCP 14 [RFC2119] [RFC8174] 에서 설명된 대로, 이처럼 모두 대문자로 표기될 때에만 해당 의미로 해석되어야 합니다.

이 명세에 적합성을 주장할 수 있는 제품의 유형은 두 가지입니다: 사용자 에이전트와 기타 명세(즉, 이 명세의 요구사항을 준수하는 방식으로 강력한 기능을 명세화하는 기술 보고서).

A. Permissions Policy 명세와의 관계

이 섹션은 규범적이지 않습니다.

이 명세와 Permissions Policy 명세는 모두 "권한"을 다루지만, 각 명세는 플랫폼에서 서로 다른 목적을 수행합니다. 그럼에도 불구하고 두 명세는 명시적으로 겹치는 부분이 있습니다.

한편으로, 이 명세는 사용자 에이전트가 중개하는 권한 UI를 통해 접근이 관리되는 강력한 기능만을 다룹니다(즉, 해당 기능을 사용하기 전에 사용자가 명시적으로 동의하는 권한이며, 사용자는 언제든 어떤 이유로든 해당 권한을 거부할 수 있는 능력을 유지합니다). 이러한 강력한 기능은 Permissions Registry에 등록됩니다.

다른 한편으로, Permissions Policy 명세는 개발자가 "권한 정책"을 통해 정책으로 제어되는 기능을 선택적으로 활성화하거나 비활성화할 수 있도록 합니다(HTTP 헤더이든 allow 속성이든 관계없습니다). 그런 의미에서 Permissions Policy는 이 명세와 독립적으로 어떤 기능을 사용할 수 있는지 자체를 결정한다는 점에서 이 명세를 포괄합니다. 이러한 정책으로 제어되는 기능도 Permissions Registry에 등록됩니다.

Permissions Policy 명세에 의해 비활성화된 강력한 기능은 이 명세에서 항상 그 권한 상태가 "거부됨"으로 반영됩니다. 이는 현재 권한을 읽는 것이 [HTML]의 "사용하도록 허용됨" 검사를 기반으로 하며, 이 검사가 다시 Permissions Policy 명세를 호출하기 때문입니다. 여기에서 중요한 점은 두 명세가 권한 이름을 공유한다는 것입니다. 이 명세와 Permissions Policy 명세 모두 다른 명세에서 권한의 이름과 이름을 정의하는 데 의존하며, 일반적으로 동일한 이름을 사용합니다(예: Geolocation의 "geolocation" 등).

마지막으로, 강력한 기능이 Permissions Policy 명세에서 제공하는 어떤 수단을 통해서도 "허용됨" 상태가 되는 것은 불가능합니다. 강력한 기능이 "허용됨" 상태가 될 수 있는 유일한 방법은 사용자가 명시적 권한을 부여하거나 일부 사용자 에이전트 정책에 의한 것입니다.

B. 자동 테스트

사용자 에이전트 자동화 및 애플리케이션 테스트 목적을 위해, 본 문서는 [WebDriver] 및 [WebDriver-BiDi] 명세에 대한 확장 기능을 정의합니다. 사용자 에이전트가 이를 지원하는 것은 OPTIONAL입니다.

WebIDLdictionary PermissionSetParameters {
  required object descriptor;
  required PermissionState state;
};

permission을 설정하려면 PermissionDescriptor descriptor, PermissionState state, 선택적 permission key key, 그리고 선택적 user agent이 주어졌을 때 다음을 수행한다:

  1. key가 null이라면, target key를 권한 키 생성의 결과로 둔다. descriptor, 현재 settings object의 최상위 origin과 현재 settings object의 origin을 사용한다. 그렇지 않으면 target key는 key로 둔다.
  2. settings list를 목록으로 두는데, user agent가 제공되었다면 해당 environment settings object 전부, 아니면 모든 user agent의 object 전부를 포함한다.
  3. targets를 비어있는 목록으로 둔다.
  4. settings list의 각 environment settings object settings에 대해:
    1. settings key를 권한 키 생성의 결과로 둔다. descriptor, settings의 최상위 origin과 settings의 origin을 사용한다.
    2. matches를 권한 키 비교 알고리즘의 실행 결과로 둔다. descriptor와 settings key, key를 인자로 사용한다.
    3. 만약 matches가 true라면, append를 이용해 settings를 targets에 추가한다.
  5. tasks를 비어있는 목록으로 둔다.
  6. targets의 각 environment settings object target에 대해:
    1. 작업(task)을 큐잉(queue)한다. task를 permissions task source에, target의 관련 settings object의 global object의 browsing context에 큐잉하여 다음 단계를 수행한다:
      1. state를 permission state가 descriptor와 target을 인자로 호출된 결과인 것처럼 해석한다.
    2. Append를 사용해 task를 tasks에 추가한다.
  7. tasks의 모든 task가 완료될 때까지 기다리고, 리턴한다.

B.1 [WebDriver]를 활용한 자동 테스트

본 문서는 [WebDriver] 명세에 대한 확장 명령어를 아래와 같이 정의합니다.

B.1.1 권한 설정

HTTP 메서드 URI 템플릿
POST /session/{session id}/permissions

권한 설정 확장 명령어는 PermissionDescriptor의 권한 상태를 사용자가 변경하는 것처럼 시뮬레이션합니다.

원격단 단계는 다음과 같습니다:

  1. parametersDict를 parameters 인자로 하여, IDL 값 타입 PermissionSetParameters로 변환. 변환 중 예외가 발생하면 invalid argument error를 반환.
  2. parametersDict.state 값이 구현 정의상 부적절한 권한 상태인 경우, invalid argument error를 반환.
    참고

    예를 들어, "midi" 강력한 기능을 "항상 on"으로 정의한 사용자 에이전트는 해당 권한 상태를 "denied"로 변경하는 명령을 거부할 수 있습니다.

  3. rootDesc를 parametersDict.descriptor 값으로 설정.
  4. typedDescriptor를 rootDesc가 가리키는 객체로 하여, IDL 값으로 변환. 타입은 권한 디스크립터 타입이며, Get(rootDesc, "name") 결과에 맞춤. 변환 중 예외 발생 시 invalid argument error 반환.
  5. 권한 설정 알고리즘을 typedDescriptor와 parametersDict.state로 실행.
  6. 성공과 함께 data null 반환.

B.2 [WebDriver-BiDi]를 활용한 자동 테스트

본 문서는 [WebDriver-BiDi] 명세에 대한 확장 모듈을 아래와 같이 정의합니다.

B.2.1 permissions 모듈

permissions 모듈은 원격단 브라우저 권한 관리를 위한 명령어를 포함합니다.

B.2.1.1 정의

remote end definition

CDDLPermissionsCommand = (
  permissions.setPermission
)
B.2.1.2 타입
B.2.1.2.1 permissions.PermissionDescriptor 타입
CDDLpermissions.PermissionDescriptor = {
  name: text,
}

permissions.PermissionDescriptor 타입은 PermissionDescriptor를 나타냅니다.

B.2.1.2.2 permissions.PermissionState 타입
CDDLpermissions.PermissionState = "granted" / "denied" / "prompt"

permissions.PermissionState 타입은 PermissionState를 나타냅니다.

B.2.1.3 명령어
B.2.1.3.1 permissions.setPermission 명령어

권한 설정 명령어는 PermissionDescriptor의 권한 상태를 사용자가 변경하는 것처럼 시뮬레이션합니다.

명령어 타입
CDDLpermissions.setPermission = (
  method: "permissions.setPermission",
  params: permissions.SetPermissionParameters
)

permissions.SetPermissionParameters = {
  descriptor: permissions.PermissionDescriptor,
  state: permissions.PermissionState,
  origin: text,
  ? embeddedOrigin: text,
  ? userContext: text,
}
결과 타입
EmptyResult

원격단 단계는 session과 command parameters로 다음과 같이 실행합니다:

  1. descriptor를 command parameters의 descriptor 필드 값으로 설정.
  2. permission name을 descriptor의 name 필드 값으로 설정하며, name을 나타냄.
  3. state를 command parameters의 state 필드 값으로 설정.
  4. user context id를 command parameters의 userContext 필드 값(있으면) 또는 default로 설정.
  5. state 값이 구현 정의상 부적절한 권한 상태인 경우, error와 error code invalid argument 반환.
  6. typedDescriptor를 descriptor가 가리키는 객체로 하여, (descriptor, state)를 IDL 값으로 변환, 타입은 PermissionSetParameters의 permission name에 해당하는 권한 디스크립터 타입. 변환 중 예외 발생 시 error와 error code invalid argument 반환.
  7. origin을 command parameters의 origin 필드 값으로 둔다.
  8. embedded origin을 command parameters의 embeddedOrigin 필드 값이 있으면 그것으로, 없으면 origin으로 둔다.
  9. key를 origin과 embedded origin을 사용하여 descriptor에 대해 권한 키 생성의 결과로 둔다.
  10. user agent를 user context id를 가진 user context를 나타내는 user agent로 설정한다.
  11. permission을 설정한다 (typedDescriptor, state, key, user agent 사용).
  12. 데이터 null과 함께 성공을 반환한다.

C. 권한 레지스트리

이 섹션은 규범적이지 않습니다.

C.1 목적

이 W3C 레지스트리는 웹 플랫폼의 정책 제어 기능 및 강력한 기능을 중앙 집중식으로 확인할 수 있는 장소를 제공합니다. 변경 프로세스를 통해 플랫폼 내 권한이 여러 명세에 걸쳐 일관되게 명세되도록 돕습니다.

레지스트리를 표준화된 권한과 임시 권한으로 분리함으로써, 기능의 상태를 추적할 수 있는 방법을 제공합니다.

C.2 변경 프로세스

이 레지스트리에 추가/업데이트하는 변경 프로세스는 다음과 같습니다:

  1. 필요한 경우, 명세에 "Permissions Policy" 섹션을 추가합니다. 여기에는 다음이 포함됩니다:
    1. 정책 제어 기능을 식별하는 문자열(예: "super-awesome"). 문자열은 dfn 요소로 링크 가능하게 만듭니다.
    2. 기본 허용 목록 값(예: 'self').
  2. 기능이 강력한 기능의 정의에 부합하는지 판별합니다(즉, 사용에 명시적 권한이 필요한지). 부합한다면:
    1. 강력한 기능 명세화를 Permissions 명세 준수 방식으로 명세서 내에 진행합니다.
  3. 표준화된 권한 표 또는 임시 권한 표를 수정하며, 각 열에 필요한 정보를 입력합니다.
  4. Powerful Features Registry Repository에 변경사항을 포함한 풀 리퀘스트를 제출합니다. 저장소 유지관리자가 내용을 검토하고 통합 여부를 확인합니다.

C.3 표준화된 권한 레지스트리 표

표준화된 권한 표에 등재되기 위해서는, 표준화된 권한 요건을 충족해야 합니다:

각 권한은 고유한 리터럴 문자열로 식별됩니다. Permissions Policy에서는 문자열이 정책 제어 기능을 식별합니다. Permissions 명세에서는 문자열이 강력한 기능을 식별합니다.

참고: 권한과 Permissions Policy
웹 플랫폼의 표준화된 권한 표
식별 문자열 정책 제어 기능 여부 강력한 기능 여부 명세 구현체
Chromium Gecko WebKit
"geolocation" YES YES 지오로케이션 YES YES YES
"notifications" NO YES 알림 API 현행 표준 YES YES YES
"push" NO YES Push API YES YES YES
"web-share" YES NO 웹 공유 API YES YES YES

C.4 임시 권한 레지스트리 표

임시 권한은 아직 표준화된 권한이 아닌 권한(즉, 실험적이거나 인큐베이팅 단계, 또는 단일 브라우저 엔진에만 구현됨)입니다.

임시 권한 표
식별 문자열 정책 제어 기능 여부 강력한 기능 여부 명세 구현체
Chromium Gecko WebKit
"accelerometer" YES YES 디바이스 방향 및 모션 YES NO NO
"window-management" YES YES 창 관리 YES NO NO
"local-fonts" YES YES 로컬 폰트 접근 API YES NO NO

D. 개인정보 고려사항

공격자는 권한 상태를 최종 사용자에 해당하는 "지문"을 생성하는 요소로 활용할 수 있습니다. 이미 공격자는 실제로 API를 사용하여 권한 상태를 확인할 수 있지만, 그 경우 권한이 이미 "허용됨(granted)" 상태가 아니면 UI 프롬프트가 사용자에게 표시되는 경우가 많습니다. 이 API가 웹사이트에 새로운 지문 정보(fingerprinting information)를 노출하지는 않지만, 공격자가 해당 정보를 조용히 더 쉽게 접근할 수 있도록 해줍니다.

사용자 에이전트는 권장됨(SHOULD) 사용자가 특정 강력한 기능과 연결된 오리진에 대한 권한 상태를 검토, 업데이트, 리셋할 수 있는 방법을 제공해야 합니다.

E. 보안 고려사항

현재 문서화된 보안 고려사항은 없습니다. 대신, D. 개인정보 고려사항 섹션을 참고하시기 바랍니다.

F. IDL 색인

WebIDL[Exposed=(Window)]
partial interface Navigator {
  [SameObject] readonly attribute Permissions permissions;
};

[Exposed=(Worker)]
partial interface WorkerNavigator {
  [SameObject] readonly attribute Permissions permissions;
};

[Exposed=(Window,Worker)]
interface Permissions {
  Promise<PermissionStatus> query(object permissionDesc);
};

dictionary PermissionDescriptor {
  required DOMString name;
};

[Exposed=(Window,Worker)]
interface PermissionStatus : EventTarget {
  readonly attribute PermissionState state;
  readonly attribute DOMString name;
  attribute EventHandler onchange;
};

enum PermissionState {
  "granted",
  "denied",
  "prompt",
};

dictionary PermissionSetParameters {
  required object descriptor;
  required PermissionState state;
};

G. 감사의 글

이 섹션은 규범적이지 않습니다.

편집자들은 API 설계 및 편집 작업에 도움을 준 Adrienne Porter Felt, Anne van Kesteren, Domenic Denicola, Jake Archibald, Wendy Seltzer에게 감사를 표합니다.

H. 참고 문헌

H.1 규범적 문헌

[dom]
DOM 현행 표준. Anne van Kesteren. WHATWG. 현행 표준. URL: https://dom.spec.whatwg.org/
[ecma-262]
ECMAScript 언어 명세. Ecma International. URL: https://tc39.es/ecma262/multipage/
[HTML]
HTML 현행 표준. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. 현행 표준. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra 현행 표준. Anne van Kesteren; Domenic Denicola. WHATWG. 현행 표준. URL: https://infra.spec.whatwg.org/
[Notifications]
알림 API 현행 표준. Anne van Kesteren. WHATWG. 현행 표준. URL: https://notifications.spec.whatwg.org/
[Permissions-Policy]
Permissions Policy. Ian Clelland; Ari Chivukula. W3C. 2026년 9월 22일. W3C 작업 초안. URL: https://www.w3.org/TR/permissions-policy-1/
[permissions-registry]
Permissions Registry. W3C. 초안 레지스트리. URL: https://w3c.github.io/permissions-registry/
[RFC2119]
RFC에서 요구 수준을 나타내는 키워드. S. Bradner. IETF. 1997년 3월. Best Current Practice. URL: https://www.rfc-editor.org/info/rfc2119/
[RFC8174]
RFC 2119 키워드의 대소문자 모호성. B. Leiba. IETF. 2017년 5월. Best Current Practice. URL: https://www.rfc-editor.org/info/rfc8174/
[WebDriver]
WebDriver. Simon Stewart; David Burns. W3C. 2026년 7월 2일. W3C 작업 초안. URL: https://www.w3.org/TR/webdriver2/
[WebDriver-BiDi]
WebDriver BiDi. James Graham; Alex Rudenko; Maksim Sadym. W3C. 2026년 10월 8일. W3C 작업 초안. URL: https://www.w3.org/TR/webdriver-bidi/
[WEBIDL]
Web IDL 현행 표준. Edgar Chen; Timothy Gu. WHATWG. 현행 표준. URL: https://webidl.spec.whatwg.org/

H.2 참고용 문헌

[appmanifest]
웹 애플리케이션 매니페스트. Marcos Caceres; Daniel Murphy; Christian Liebel. W3C. 2026년 10월 16일. W3C 작업 초안. URL: https://www.w3.org/TR/appmanifest/
[Geolocation]
지오로케이션. Marcos Caceres; Reilly Grant. W3C. 2026년 3월 26일. W3C 후보 권고안. URL: https://www.w3.org/TR/geolocation/
[GETUSERMEDIA]
미디어 캡처 및 스트림. Cullen Jennings; Jan-Ivar Bruaroey; Henrik Boström; youenn fablet. W3C. 2025년 10월 9일. CRD. URL: https://www.w3.org/TR/mediacapture-streams/
[local-font-access]
로컬 폰트 접근 API. W3C. 초안 커뮤니티 그룹 보고서. URL: https://wicg.github.io/local-font-access/
[orientation-event]
디바이스 방향 및 모션. Reilly Grant; Marcos Caceres. W3C. 2025년 2월 12일. CRD. URL: https://www.w3.org/TR/orientation-event/
[Permissions]
Permissions. Marcos Caceres; Mike Taylor. W3C. 2025년 10월 6일. W3C 작업 초안. URL: https://www.w3.org/TR/permissions/
[push-api]
Push API. Marcos Caceres; Kagami Rosylight. W3C. 2026년 10월 5일. W3C 작업 초안. URL: https://www.w3.org/TR/push-api/
[w3c-process]
W3C Process Document. Elika J. Etemad (fantasai); Florian Rivoal. W3C. 2025년 8월 18일. URL: https://www.w3.org/policies/process/
[Web-Share]
웹 공유 API. Marcos Caceres; Eric Willigers; Matt Giuca. W3C. 2023년 5월 30일. W3C 권고안. URL: https://www.w3.org/TR/web-share/
[window-management]
창 관리. Mike Wasserman. W3C. 2026년 9월 8일. W3C 작업 초안. URL: https://www.w3.org/TR/window-management/