재량적 접근 제어(Discretionary Access Control, DAC)

재량적 접근 제어는 리소스의 소유자가 해당 리소스에 대한다른 사용자들의 접근 권한을 직접 제어할 수 있는 접근 제어 방식.
이는 우리가 일상적으로 사용하는 컴퓨터의 파일 시스템과 매우 유사한 방식으로 작동한다.
예를 들어, 여러분이 문서를 만들면 해당 문서의 소유자가 되어 다른 사람들에게 읽기, 쓰기, 또는 실행 권한을 부여할 수 있다.

개인용 컴퓨터나 작은 규모의 조직에서 사용되며, 높은 수준의 보안이 요구되는 환경에서는 다른 접근 제어 방식과 함께 사용되는 것이 일반적이다.
예를 들어, 기업 환경에서는 DAC와 함께 역할 기반 접근 제어(RBAC)나 강제적 접근 제어(MAC)를 함께 사용하여 보안을 강화하는 경우가 많다.

작동방식:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class Resource {
    constructor(owner) {
        this.owner = owner;
        this.permissions = new Map();
        // 기본적으로 소유자에게 모든 권한 부여
        this.permissions.set(owner, ['read', 'write', 'execute']);
    }

    // 권한 부여 메서드
    grantPermission(user, permissions) {
        // 소유자만이 권한을 부여할 수 있음
        if (this.owner !== this.getCurrentUser()) {
            throw new Error('Only the owner can grant permissions');
        }
        this.permissions.set(user, permissions);
    }

    // 권한 확인 메서드
    checkPermission(user, permission) {
        const userPermissions = this.permissions.get(user);
        return userPermissions && userPermissions.includes(permission);
    }

    // 권한 취소 메서드
    revokePermission(user) {
        if (this.owner !== this.getCurrentUser()) {
            throw new Error('Only the owner can revoke permissions');
        }
        this.permissions.delete(user);
    }

    getCurrentUser() {
        // 현재 사용자를 반환하는 로직
        return this.owner; // 예시를 위한 단순화
    }
}

// 사용 예시
const document = new Resource('Alice');

// Alice가 Bob에게 읽기와 쓰기 권한을 부여
document.grantPermission('Bob', ['read', 'write']);

// Bob의 읽기 권한 확인
console.log(document.checkPermission('Bob', 'read')); // true

// Bob의 실행 권한 확인
console.log(document.checkPermission('Bob', 'execute')); // false

주요 특징

  1. 유연성: 리소스 소유자가 접근 권한을 자유롭게 설정할 수 있어 매우 유연하다.
  2. 접근 제어 목록(ACL) 사용: 각 객체에 대한 접근 권한은 ACL을 통해 관리된다.
  3. 권한 위임: 접근 권한을 가진 사용자는 해당 권한을 다른 사용자에게 위임할 수 있다.
  4. 사용자 식별 기반: 사용자의 신원(ID)을 기반으로 접근 권한이 결정된다.

장점

  1. 사용자 친화적: 사용자가 자신의 데이터를 직접 관리할 수 있다.
  2. 관리 부담 감소: 중앙 관리자의 개입 없이 사용자가 권한을 관리할 수 있어 관리 부담이 줄어든다.
  3. 빠른 정보 공유: 사용자 간 빠르고 효율적인 정보 공유가 가능하다.

단점

  1. 보안 취약성: 사용자의 판단에 의존하기 때문에 보안 위험이 증가할 수 있다.
  2. 중앙 관리의 어려움: 전체적인 접근 정책을 일관되게 적용하기 어려울 수 있다.
  3. 내부자 위협: 권한을 가진 사용자가 악의적으로 정보를 유출할 위험이 있다.

예시

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
class FileSystem {
    constructor() {
        this.files = new Map();
    }

    createFile(filename, owner) {
        const file = new File(filename, owner);
        this.files.set(filename, file);
        return file;
    }

    accessFile(filename, user, operation) {
        const file = this.files.get(filename);
        if (!file) {
            throw new Error('File not found');
        }
        return file.checkAccess(user, operation);
    }
}

class File {
    constructor(filename, owner) {
        this.filename = filename;
        this.owner = owner;
        this.accessControl = {
            owner: ['read', 'write', 'execute', 'grant'],
            group: [],
            others: []
        };
        this.groups = new Map();
    }

    setGroupPermissions(group, permissions) {
        if (this.owner !== this.getCurrentUser()) {
            throw new Error('Permission denied');
        }
        this.accessControl.group = permissions;
        this.groups.set(group, true);
    }

    checkAccess(user, operation) {
        if (user === this.owner) {
            return this.accessControl.owner.includes(operation);
        }
        
        // 그룹 멤버십 확인
        if (this.groups.has(user.group)) {
            return this.accessControl.group.includes(operation);
        }
        
        return this.accessControl.others.includes(operation);
    }
}

참고 및 출처