권한
어떤 상대가 어떤 것에 무엇을 해도 되는지를 미리 정해 둔 것입니다. 시스템은 요청을 받을 때마다 이 내용을 보고 통과시킬지 막을지를 정합니다. 파일을 읽는 것도 표에 행을 넣는 것도 전부 이 확인을 거칩니다.
상세
사무실 출입증에는 어느 방에 들어가도 되는지가 적혀 있습니다. 문 앞의 판독기는 그 사람이 마음에 드는지를 보지 않고 그 카드에 이 방이 적혀 있는지만 봅니다.
권한은 출입증보다 잘게 나뉩니다. 같은 대상이라도 읽는 것과 고치는 것이 따로 적힙니다. 권한은 세 짝으로 적힙니다. 조작을 하려는 쪽인 주체, 조작이 닿는 쪽인 대상, 그리고 그 사이에 놓인 조작입니다. 이 세 짝마다 허용인지 아닌지가 붙고, 그 붙어 있는 것이 권한입니다.
주체는 사람 한 명일 수도 있고 사람을 대신해 도는 프로그램일 수도 있습니다. 어느 쪽이든 시스템이 권한을 부여하는 단위이고, 동시에 책임을 묻는 단위입니다. Saltzer 와 Schroeder 의 용어집은 이 자리를 principal 이라고 부릅니다.
조작이 따로 적힌다는 것이 권한의 기본 모양입니다. 같은 용어집은 permission 을 "허용된 접근의 한 가지 형태" 로 풀고, 읽기 허용과 쓰기 허용이 서로 다른 것이라는 예를 붙였습니다. 그래서 어떤 대상을 읽을 수 있다는 사실이 그것을 고쳐도 된다는 뜻이 되지 않습니다.
한 주체가 지금 직접 손댈 수 있는 대상을 다 모은 것에도 이름이 있습니다. 같은 용어집은 그것을 도메인이라고 적었습니다.
배경
한 대의 컴퓨터에 여러 사람의 정보가 같이 얹혔습니다. 그 정보를 저장한 쪽이 의도하지 않은 사용이나 변경이 문제가 됐습니다. Saltzer 와 Schroeder 는 논문의 첫 줄에서 다루려는 대상을 그렇게 못 박습니다 — 컴퓨터에 저장된 정보를 허가받지 않은 사용이나 변경으로부터 지키는 일입니다.
지키려면 두 가지가 따로 필요했습니다. 하나는 요청을 낸 쪽의 신원을 확인하는 일이고, 다른 하나는 확인된 그 쪽에게 이 정보에 대한 접근을 이미 내주었는지 보는 일입니다. 같은 논문의 용어집은 앞을 authenticate, 뒤를 authorize 로 갈라 적습니다. 내준 것을 도로 거두는 일에는 revoke 라는 이름이 따로 붙어 있습니다.
내주었다는 사실 자체를 가리키는 이름이 permission 입니다. 권한이라는 말은 그 자리를 가리킵니다. 확인하는 행위가 아니라 확인의 대상이 되는 내용입니다.
예시
권한은 한 자리에만 있는 것이 아닙니다. 아래 넷은 도메인이 다 다른데 세 짝의 모양은 같습니다.
파일 시스템의 모드 비트
chmod(2) 는 파일의 모드 비트를 바꾸는 시스템콜입니다. 새 모드는 아래 상수를
비트 논리합으로 묶어 만듭니다.
S_IRUSR (00400) read by owner
S_IWUSR (00200) write by owner
S_IXUSR (00100) execute/search by owner
S_IRGRP (00040) read by group
S_IWGRP (00020) write by group
S_IXGRP (00010) execute/search by group
S_IROTH (00004) read by others
S_IWOTH (00002) write by others
S_IXOTH (00001) execute/search by others
상수 이름 자체가 세 짝입니다. 뒤쪽 세 글자가 주체 자리로 USR·GRP·OTH 셋이고,
그 앞 한 글자가 조작 자리로 R·W·X 셋입니다. 대상은 이 비트가 붙어 있는 파일 하나입니다.
S_IRUSR·S_IWUSR·S_IRGRP·S_IROTH 넷을 묶으면 흔히 보는 0644 가 됩니다.
모드에는 S_ISUID·S_ISGID·S_ISVTX 도 같이 들어갑니다.
매뉴얼은 파일 모드가 권한 비트에 이 셋을 더한 것이라고 적습니다.
권한을 바꾸는 일에도 권한이 걸립니다. 매뉴얼은 부르는 쪽 프로세스의 실효 UID(User ID,
사용자 식별자)가 파일 소유자와 같거나, 그 프로세스가 특권을 가져야 한다고 적습니다.
리눅스에서 그 특권은 CAP_FOWNER 케이퍼빌리티입니다.
데이터베이스의 GRANT
PostgreSQL 은 GRANT 문으로 권한을 내줍니다. 공식 문서의 예문은 이렇게 생겼습니다.
GRANT INSERT ON films TO PUBLIC;
GRANT ALL PRIVILEGES ON kinds TO manuel;
GRANT admins TO joe;
첫 줄에서 조작은 INSERT, 대상은 films 표, 주체는 PUBLIC 입니다.
내줄 수 있는 조작의 이름은 정해져 있습니다 — SELECT·INSERT·UPDATE·DELETE·
TRUNCATE·REFERENCES·TRIGGER·CREATE·CONNECT·TEMPORARY·EXECUTE·USAGE·
SET·ALTER SYSTEM·MAINTAIN 입니다.
셋째 줄은 성격이 다릅니다. 문서는 GRANT 에 두 갈래가 있다고 적습니다.
하나는 데이터베이스 객체에 대한 권한을 주는 것이고, 다른 하나는 역할의 구성원 자격을
주는 것입니다. 셋째 줄은 뒤쪽 갈래입니다.
역할을 주는 구문에는 WITH INHERIT 옵션이 붙을 수 있습니다.
구문에는 WITH GRANT OPTION 이 따로 있습니다. 받은 권한을 남에게 다시 내줄 수 있느냐가
그 자리에서 갈립니다.
웹 위임의 스코프
RFC(Request for Comments) 6749 §3.3 은 요청할 접근의 범위를 scope 파라미터로 적게 합니다.
값은 공백으로 나뉜 대소문자 구분 문자열의 목록입니다.
scope = scope-token *( SP scope-token )
scope-token = 1*( %x21 / %x23-5B / %x5D-7E )
각 문자열이 무엇을 뜻하는지는 인가 서버가 정합니다. 여러 개가 공백으로 이어지면 순서는 상관이 없고, 하나가 붙을 때마다 요청하는 범위가 하나씩 늘어납니다.
여기서 권한의 한 성질이 드러납니다. 요청한 범위가 그대로 나온다는 보장이 없습니다.
명세는 인가 서버가 정책이나 자원 소유자의 지시에 따라 요청된 스코프를 전부 또는 일부
무시할 수 있다(MAY)고 적습니다. 그리고 발급된 스코프가 요청과 다르면 인가 서버가
scope 응답 파라미터로 실제 내준 범위를 알려야 한다(MUST)고 못 박습니다.
모바일 앱의 선언된 권한
안드로이드에서 앱은 필요한 권한을 매니페스트에 미리 적습니다.
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
android:name 에 들어가는 것이 권한의 이름입니다. android.permission.CAMERA 나
android.permission.READ_CONTACTS 처럼 패키지 이름을 접두사로 붙인 꼴입니다.
내주는 시점이 이름의 종류마다 다릅니다. 공식 문서는 설치 시점 권한이 앱을 설치할 때 시스템에 의해 자동으로 부여된다고 적습니다. 런타임 권한은 그렇지 않아서, 제한된 데이터에 접근하거나 제한된 동작을 하기 전에 앱이 앱 안에서 따로 요청해야 합니다. 문서는 런타임 권한이 시스템과 다른 앱에 더 크게 영향을 주는 자리라서 이렇게 갈린다고 적습니다.
경계
로그인은 분명히 됐는데 화면이 열리지 않습니다. 이것도 권한 문제인가. 맞습니다. 신원 확인이 끝난 뒤에 막히는 자리가 권한의 자리입니다.
근거는 RFC 9110 이 상태 코드 둘을 갈라 놓은 방식입니다. 401 은 요청에 대상 자원에 대한 유효한 인증 자격 증명이 없어서 적용되지 않았음을 가리킵니다. 403 은 서버가 요청을 이해했는데도 수행을 거절한다는 뜻입니다. 그리고 요청에 자격 증명이 들어 있었다면, 403 은 서버가 그 자격 증명으로는 접근을 내주기에 모자란다고 본 것입니다.
flowchart TD
A[요청] --> B{누구인지 확인됐나}
B -->|아니다| C["401 — 자격 증명이 없다"]
B -->|맞다| D{이 조작이 허용돼 있나}
D -->|아니다| E["403 — 이해했지만 거절"]
D -->|맞다| F[수행]
앞의 갈림이 인증이고 뒤의 갈림이 인가입니다. 인가는 확인하는 일이고, 권한은 그 확인이 들여다보는 내용입니다. 둘은 같은 말이 아닙니다.
다만 403 이 곧 권한 부족이라고 못 박을 수는 없습니다. 명세는 자격 증명과 무관한 이유로도 요청이 금지될 수 있다고 적습니다. 막힌 자원이 지금 있다는 사실 자체를 감추려는 서버는 403 대신 404 로 답할 수도 있습니다(MAY). 그래서 겉으로 본 상태 코드만으로 권한이 원인이라고 단정하지 않습니다.
관련 항목
권한을 나타내는 자료구조
접근 제어 목록 · 능력 · 접근 행렬
권한을 정하는 정책 모델
임의적 접근 제어 · 강제적 접근 제어 · 역할 기반 접근 제어 · 속성 기반 접근 제어
권한에 적용되는 원칙과 그 위반
권한에 관여하는 역할과 참여자
권한이 미치는 범위를 나타내는 이름
권한이 실제로 나타나는 분야
권한을 실제로 구현·채택한 제품
PostgreSQL · 안드로이드 · 리눅스
권한의 경계를 정하는 근거
인증 · 인가 · 특권 · 자격 증명 · RFC 9110 · 상태 코드 · 401 Unauthorized · 403 Forbidden
유닉스에서 마주치는 이름
모드 비트 · setuid · CAP_FOWNER · CAP_SETUID · 케이퍼빌리티 · 슈퍼유저
모바일에서 마주치는 이름
런타임 권한 · 설치 시점 권한 · 매니페스트
다른 이름: permission · privilege · 퍼미션