이 글을 읽으시는 분께

  • 뭐야 딱딱한 글이야? 권한.. 복잡하지... 이미 우리 시스템은 권한별 구분을 해놨어..등등 ^^
    저는 딱딱한 기술 글을 쓰고자 하는게 아니라 😂
    웹 서비스나 클라우드 서비스를 개발하면서 가장 중요하게 고려해야 하는 부분중 하나가
    사용자들이 서비스의 어느 부분까지 사용할수 있고 없고를 판단하는 기준이 중요해습니다.
    권한이란 부분이 현재 어떤 모델이 적용되어 있고, 어떤 방식이 있는지 소개하는 글이며
    글을 읽고, 우리 시스템은 이런 권한이 적용 되었었구나,, 혹은 아 이런방식도 있네.. 좀더 개선해볼까? 라는 바램에서 간단하게 읽어보고 생각해보자는 취지에서 작성하였습니다.

들어가며

  • 현시대 클라우드를 비롯한 모든 플랫폼의 컴퓨팅 자원은 보안이 중요해진 시점이 왔습니다. (그 누구도 부정할 수 없죠 ㅎ)
    그러므로 우리는 (혹은 우리 시스템은) 권한이란 부분이 존재해야 하고, 그 권한을 가진 사용자에게만 접근을 허용해야 합니다.
    하지만 점점 많은 시스템과 어플리케이션이 클라우드로 옮겨지면서, 권한관리가 어려워진 부분이 존재하고 있습니다.
    이에 따라 접근 제어 모델의 종류를 알아보고, 어떤 권한 관리에 초점을 두면 될지 고민해보는 시간을 갖고자 합니다.

접근 제어란?

  • 웹 서비스나 클라우드 서비스 등을 개발하면서, 가장 중요하게 고려해야 하는 부분 중 하나는 바로 각 사용자들이 서비스의 어느 부분까지 사용할 수 있고, 어느 부분은 사용을 못하게 할지, 접근을 막을지 등을 제어하는 것입니다.
    이건 보안에 매우 밀접한 관련이 있기 때문에 올바르게 접근 제어를 구현하는 것은 매우 중요해졌죠!! 🧐
  • 서비스 개발자는 해당 서비스를 통해 어떤 기능을 제공할 것인지에 대한 고민 뿐만 아니라, 서로 다른 사용자들의 서비스 접근 권한을 어떻게 제어할 지도 고민해야 합니다.
    그러기 위해서는 접근제어 모델의 종류와 예시를 아는 것이 매우 중요!!

인증(Authentication) vs 인가(Authorization)

  • 인증(Authentication)과 인가(Authorization)는 항상 함께 등장하는 개념이면서 사용하기에 헷갈리는 용어이기도 합니다.
    하지만 인증(Authentication)과 인가(Authorization)는 엄연히 다른 개념으로 둘의 차이점을 명확히 알고 있어야 하죠.

인증 (Authentication)

  • 사용자가 누구인지 판별하는것.
    • 보통 서비스의 로그인 하는 과정이 이에 해당합니다.
    • 사용자가 서비스에 회원가입을 한 사용자이며, 그 사용자가 맞는지를 판별하는 작업 등을 인증절차 라고 합니다.

예시 : 은행에서 돈을 인출하려 할때 은행직원은 신분증을 제시해 달라고 요청합니다.
다른 예로 비행기 티켓을 구매하려고 하면, 비행기를 탈수 있는 자격이 되는지 증명하기 위해 여권을 제시해야 할 수도 있는것 처럼요..

  • 두 예시 모두 신원(인증된 사용자)를 확인하기 위해 인증절차가 어떻게 진행되는지를 보여주고 있습니다.
  • 간단히 뒤집어서 생각해보면, 온라인이나 서비스개발도 다를게 없다는걸 아실겁니다.
    • 쇼핑몰에 접속하려고 할때, 혹은 사내 서비스 메인페이지에 접근하려 할때, 여권이나 신분증을 제시하는 대신 아이디/패스워드를 입력하거나, 휴대폰에 전달된 SMS 에 적혀있는 2차 인증코드를 입력하는것 처럼요.
      • 이처럼 인증요소는 하나일수도 있고, 두개(two-factor) 또는 그 이상(multi-factor) 일 수도 있습니다.

인가 (Authorization)

  • 어떤 사용자가 어떤 행위를 수행할 권한을 가지고 있는가를 판별하는것.
    • 어떤 개체가 어떤 리소스에 접근할 수 있는지 또는 어떤 동작을 수행할 수 있는지를 검증하는 것을 뜻합니다. (즉 접근 권한을 얻는 일)

예시 : 공연장에 입장하기 위해 티켓을 구매하는 상황이 있다고 가정해보죠.. 기획사는 신원이 무엇인지에는 관심이 없습니다. 단지 공연장에 입장할 권한이 있는지에 대한 여부만 관심이 있겠죠?
신원정보를 포함하지 않더라도, 인가 과정에서 검증이 실패하거나 하는것이 아닌것처럼요..

  • 인터넷 기반 앱에서는 일반적으로 토큰이라 부르는 가공물을 사용하여, 인가를 다루고 있습니다.
    유저가 로그인을 하고 오면, 무엇을 할수 있는가에 대한 관심을 갖는것
    사용자 신원을 바탕으로 인가 세부사항을 가진 토큰을 생성하게 됩니다.
    시스템은, 인가 토큰을 이용해서 어떤 권한을 부여할지, 리소스 접근 요청을 허용할지 거부할지를 결정합니다.

인증 VS 인가

  • 위에서 무엇을 뜻하는지 밝히기는 했지만, 이 용어들은 자주 중복해서 사용되고 혼란의 원인이 됩니다.

    예시 : 은행에서처럼 신분증을 제시했지만, 그 신분증은 본인의 계좌에 접근하기 위한 인가에도 사용되는 것처럼 혼합될 수 있고
    사원증을 아무리 찍어도, 대표님 방문은 열수 없으니까요!

  • 인증과 인가는 밀접하게 연관되어 있으나, 어떤 시나리오에서는 서로 바꿔서 사용할 수 있는 주제가 되기도 합니다.

  • 여기서 중요한 점은 인증은 인가로 이어지지만, 인가가 인증으로 이어지지는 않는다는 점이 핵심입니다.

    • 신원증명이 접근권한을 증명하기에는 충분하다 할지라도.. 무언가를 얻는 인가가 항상 개체를 식별하는데 사용할수 있는게 아닌것처럼..🤔
    • 복잡해 지네요.. ㅎ 예를 다시 들어보겠습니다.

예시 : 비행기탈때 탑승권으로 승무원은 내가 비행기를 탈수 있음을 나타내는 증명과 동시에 내 신원을 알수 있지만.. 반대로 공연티켓으로는 공연을 볼수있다 할지라도, 입장은 가능하지만 입장 외에는 아무것도 아닌것처럼요..

돌아와서..

  • 당연하게도 ‘인가’를 수행하기 위해서는 ‘인증’이 선행되어야 합니다.
    먼저 그 사용자가 누구인지 판별이 되어야 그 사용자에 대한 권한을 판별할 수 있기 때문이죠.

용어 정의

  • 접근 제어 모델을 설명하기 전에 먼저 접근 제어 모델에서 사용하는 용어에 대해 알 필요가 있습니다.

    • 접근 제어 모델에서 인가를 받으려는 사용자를 주체(Subject) 라고 합니다.

      • 주체는 특정 사용자 개인이 될 수도 있고, 특정 사용자 그룹이 될 수도 있으며, 또는 전체 사용자를 가리킬 수도 있습니다.
    • 객체(Object)는 사용자가 접근하고자 하는 서비스나 자원, 정보와 같은 접근 대상을 말합니다.

      • 네이버 카페의 게시판이 객체의 예입니다.
      • 권한(Permission)객체에 허용된 주체가 수행할 수 있는 행위의 목록을 말합니다. 보통 권한에는 읽기, 쓰기, 생성, 삭제, 실행, 검색 등과 같은 권한이 존재할 수 있습니다.
  • 결국 접근 제어(Access Control)라는 것은 객체(Object)에 접근하고자 하는 주체(Subject)가 해당 객체(Object)에 접근할 수 있는 권한(Permission)을 가지고 있는지 판단하는 것입니다.

접근 제어 모델의 종류

  • 접근 제어를 어떻게 구현할지에 대해서는 많은 고민이 필요합니다.
    • 예를들어, 이 기능호출(API)을 뭘로 막을까? 테이블로 권한관리를 할까? 권한을 세분화 해버릴까? 아님 유저별로 호출할수 있는걸 분리할까?
    • 하지만 이미 잘 정립된 여러 종류의 접근 제어 모델들이 제시되어 있으므로, 어떤 것들이 있는지 살펴보고 각각의 장단점을 파악하면 자신만의 접근 제어 모델을 수립하는 데 도움이 됩니다.

강제적 접근 제어 모델 (Mandatory Access Control, MAC)

  • 미리 정해진 정책과 보안 등급에 의거하여 주체(Subject)에게 허용된 접근 권한과 객체(Object)에 부여된 허용 등급을 비교하여 접근을 제어하는 방법

예시 : 네이버나 다음 까페에서 회원 등급에 따라 접근할 수 있는 게시판과 없는 게시판을 구분하는것 입니다.
각 게시판(객체)마다 접근할 수 있는 허용 등급이 정해져 있기 때문에 객체와 주체 사이의 권한 등급을 직접 비교하여 접근 허용 여부를 결정하는 것이죠
우리 어릴때 막 등업하려고 노력 많이 한것처럼요 ㅎㅎ

  • 강제적 접근 제어 모델에서는 높은 보안 수준을 요구하는 정보는 낮은 보안 수준을 가진 주체가 접근할 수 없습니다.

    • 시스템 관리자가 이러한 권한 수준을 제어하며, 사용자들은 어떠한 접근 권한 수준도 설정할 수 없게 됩니다.
    • 객체의 소유자라고 할지라도 그 객체에 접근할 수 있는 보안 등급을 부여받지 못하면 그 객체에 접근할 수 없습니다.
  • 장점 : 강제적 접근 제어 모델은 중앙 집권적인 관리자에 의해 제어되기 때문에 보안성이 높은 편이어서 주로 군(military)이나 방화벽처럼 강력한 보안이 필요한 곳에서 주로 사용합니다.

  • 단점 : 권한 관리 기능이 단순하고 제한적이어서 주체별로 접근 제어를 다르게 적용할 수 없으며, 모든 주체와 객체에 일일이 허용 등급 설정을 해주어야 하므로 설정이 복잡합니다.

임의적 접근 제어 모델 (Discretionary Access Control, DAC)

  • 객체에 대한 접근을 사용자나 그룹의 신분을 기준으로 제한하는 방법
    • 객체의 소유자는 다른 주체에 대해 객체에 대한 접근 권한을 설정하는 방식입니다.

예시 : 리눅스 파일이나, 디렉토리에 대해 접근제어 방식을 말합니다.
이 유저의 권한은 RWX, 이 유저의 권한은 R.. 등
파일은 파일의 소유자가 그 파일에 대한 접근 제어를 설정할 수 있습니다.

  • 여기서 임의적(Discretionary)이라는 말은 객체 소유자의 판단에 따라 권한을 줄 수 있다는 뜻입니다.

  • DAC 을 구현하는 방법은 대표적으로 다음 4가지의 구현 방법이 있습니다. (이것에 대한 구현방법은 내용이 너무 길어지므로, 종류만 소개할께요)

    • 접근 제어 행렬 (Access Control Matrix)
    • 접근 제어 목록 (Access Control List: ACL)
    • 가용성 티켓 (Capability Tickets)
    • 권한 테이블 (Permission Table)
  • 장점 : 주체와 객체를 알고 있으면 어떤 권한을 가지고 있는지 바로 알아낼 수 있습니다.

  • 단점 : 주체의 수나 객체의 수가 많아지면 쓸데없이 사용되는 메모리 공간이 많아지는 단점을 가지고 있습니다.
    어느 한 객체에 대해 많은 사용자가 권한을 부여받았을 경우에는 리스트가 길어져 탐색이 오래 걸리게 됩니다.

역할 기반 접근 제어 모델 (Role Based Access Control, RBAC)

  • 권한을 사용자 개인이 아닌 역할 그룹에 부여하고, 사용자에게 역할을 할당하여 접근 제어를 하는 방식

  • 이름 그대로 역할에 따라 자원에 대한 접근을 제어하는 방식입니다.

    • 대부분의 상용 플랫폼이 지원하는 권한 관리 체계로 권한 영역에 역할이라는 개념을 도입해 표현력을 확장한 방식입니다.
    • 임의적 접근 제어(DAC)과 강제적 접근 제어(MAC)의 단점을 보완한 방식으로써 사용자에게 정적 혹은 동적으로 역할 그룹을 할당할 수 있습니다.
      • 이는 사용자 정보는 자주 바뀌어도 역할 정보는 자주 바뀌지 않는다는 것에 착안한 모델이죠.
  • 일반적으로 직무를 기반으로 하는 서비스들에서 많이 사용되는 접근 제어 방법으로 강제적 접근 제어(MAC)과 비슷하게 각 주체에 허용된 접근 수준(Clearance)과 객체에 부여된 허용등급(Classification)에 근거하여 접근 제어가 이루어집니다.

실제로 많은 서비스들이 회원 가입과 탈퇴는 빈번하게 일어나지만, 그 회원들이 부여받을 수 있는 역할의 종류와 역할과 객체 사이의 권한 관계는 잘 변하지 않습니다.
예시 : 이 유저는 이런이런 페이지를 볼수있는 기능을 가진 뷰어 권한을 가지고 있는것처럼요!
그럼 유저의 탈퇴와는 상관없이 역할기반 권한이 존재하는거고, 사용자는 그걸 받아갈 테지요.

  • 사용자와 역할 사이의 관계는 보통 다대다(N:M) 관계이기 때문에 한 사용자가 여러 개의 역할을 부여받을 수 있습니다.

    • 역할과 객체 사이의 관계도 다대다(N:M) 관계이기 때문에 한 역할이 여러 객체에 대한 접근 권한을 부여받을 수 있습니다.
  • 역할 정의

{
  "name": "roles/testRole",
  "title": "billing role",
    "includedPermissions": [
    "paymentStatement.list",
    "usage.list"
    ]
}
  • 역할 부여
{
  "bindings": [{
  "role": "roles/testRole",
    "members": [
    "user:viewrain@hohoho.com"
    ]
  }]
}
  • 장점 : 권한 관리자는 다수의 사용자에 대해 일일이 접근 권한을 관리하지 않아도 되고 적절한 역할만 부여해주면 되기 때문에 권한 관리 부담이 줄어듭니다.
  • 단점 : 다양한 권한 요소를 고려하다 보면 권한 조건이 늘어날 때마다 역할의 개수가 과도하게 늘어날 수 있는 단점이 있으므로 역할을 개수를 적절히 유지하는 것이 중요합니다.

속성 기반 접근 제어 모델 (Attribute Based Access Control, ABAC)

  • 객체와 주체의 속성에 대한 조건을 기술하여 접근 제어를 하는 방식
    • 어떤 객체에 접근하기 위해 만족시켜야 하는 속성에 대해 정의하고, 그 객체에 접근하려는 주체가 그 속성을 가지고 있는지를 검사하여 접근 제어를 수행합니다.
    • 속성은 주체 이름, 자원 유형, 현재 시간 등 다양하게 존재하며 지원하는 속성의 종류는 각 플랫폼마다 상이하다고 합니다.

예시 : 예를 들어 파일 1에 접근하기 위해서는 사용자의 type 속성에 admin이라는 태그가 달려 있어야 한다고 정의할 수 있는것 처럼요.

  • 속성 기반 접근 제어 적용
{
  "bindings": [{
      "role": "roles/testRole",
      "members": [
          "user:viewrain@hohoho.com"
          ]}
          ],
  "condition": {
  "title": "DateTime Expires",
  "description": "Expires at noon on 2023-12-31 UTC",
  "expression": "request.time < timestamp('2022-06-01T12:00:00Z')"
  }
}
  • 장점 : 시스템의 다양한 요소를 반영할 수 있기 때문에 표현력과 유연성이 좋습니다.
  • 단점 : 큰 규모의 시스템에서는 일일이 속성을 적용하기 어렵고 각 객체 접근마다 복잡한 속성 조건을 계산해야 하기 때문에 성능이 다소 느립니다. (혹은 느려질 수 있습니다.)

결론

  • 지금까지 일반적으로 사용되는 접근 제어 모델의 종류에 대해 알아 보았습니다. 제가 위에서 소개해드린 일반적인 접근 제어 모델들이 모든 서비스에 적합한 것은 아닐테죠 당연히..🤭

  • 각 서비스마다 보호해야 하는 객체의 종류나 정책이 다를 수 있고, 객체들 사이의 관계도 복잡할 수 있습니다.

  • 결국 완벽한 접근 제어(사용하기도 쉽고 성능도 나쁘지 않은)를 하기 위해서는 그 시스템을 사용하는 사용자가 누구인지, 그리고 보호하려는 객체는 어떤 것이 있으며, 각 객체 사이의 관계와 특징은 무엇인지, 어느 정도 복잡한 접근 제어까지 지원해야 하는지 등의 요구 사항을 명확히 파악하는 것이 무엇보다도 중요하다고 할수 있습니다.

  • 인터넷에 권한관리에 대한 내용을 검색해보면, 큰 틀이지만 공통된 방안을 제시하고는 있습니다. (이게 어려워서 그렇지!!)

    1. 미리 제공되는 역할을 사용할 것
    2. 서비스별 계정을 분리할 것
    3. 최소 권한만 부여할 것
  • 플랫폼이나 서비스에 따라 지원 수준과 표현법은 다르지만 역할 기반속성 기반 접근 제어는 권한 관리의 기본이기 때문에 조금 복잡하더라도 한 번만 제대로 익혀두면 다양한 서비스에 적용할 수 있습니다.
    권한 관리의 허점을 파고든 클라우드 보안 사고의 발생 가능성은 항상 존재합니다. 특히 클라우드가 기업 IT 전략 방향의 중심에 위치하면서 시스템, 애플리케이션 및 데이터에 대한 접근 권한 관리에 많은 신경을 써야 하는 시대가 이미 와있는 만큼, 이글을 보시는 모든 분들이 권한의 소중함을 짚어보셨으면 좋겠습니다. 😊

reference

profile
깨끗한 스케치북 일수록 우아한 그림이 그려지법, 읽기 쉽고, 짧은 코드가 더 아름다운 법.. 또한 프로그래머의 개발은 구현할 프로그래밍이 아닌, 풀어갈 이야기로 써내려가는것.

1개의 댓글

comment-user-thumbnail
2022년 6월 19일

너무 알찬 내용 깔끔한정리 감사하모니카
많이 배워갑니다

답글 달기