[이제와서 시작하는 Metabase 마스터하기 #10] 권한과 보안 - Collections와 그룹 관리
[이제와서 시작하는 Metabase 마스터하기 #10] 권한과 보안 - Collections와 그룹 관리
학습 목표
이 포스트를 마치면 다음을 할 수 있습니다:
- 조직의 권한 구조 설계
- Groups와 Collections로 접근 제어
- Data permissions로 데이터베이스 수준 보안
- Row-level security로 세밀한 접근 제어
- SQL permissions로 쿼리 제한
- 감사 로그로 사용 추적
권한 시스템 개요
3계층 권한 모델
graph TD
A[Metabase Permissions] --> B[User Management]
A --> C[Data Permissions]
A --> D[Collection Permissions]
B --> B1[Users & Groups]
C --> C1[Database Access]
C --> C2[Table Access]
D --> D1[Questions & Dashboards]
style A fill:#e1f5ff
style B fill:#fff4e1
style C fill:#e8f5e9
style D fill:#fce4ec
1. User Management (사용자 관리)
- 사용자 계정 생성/삭제
- 그룹 할당
- 관리자 권한
2. Data Permissions (데이터 권한)
- 어떤 데이터베이스에 접근 가능한가?
- 어떤 테이블을 볼 수 있는가?
- Native query 작성 가능한가?
3. Collection Permissions (컬렉션 권한)
- 어떤 Questions/Dashboards를 볼 수 있는가?
- 편집 가능한가?
- 새로 만들 수 있는가?
Users & Groups
사용자 생성
1
2
3
4
5
6
7
8
Admin > People > Add someone
Email: john@company.com
First name: John
Last name: Doe
Groups:
- All Users (자동)
- Sales (수동 선택)
Groups (그룹)
기본 그룹:
1
2
3
4
5
6
7
8
1. Administrators
- 모든 권한
- 설정 변경 가능
- 사용자 관리
2. All Users
- 모든 사용자 자동 포함
- 기본 권한 설정
사용자 정의 그룹 예시:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
조직 구조 기반:
- Sales Team
- Marketing Team
- Engineering Team
- Finance Team
- Executives
역할 기반:
- Analysts
- Managers
- Viewers
- Data Scientists
프로젝트 기반:
- Project Alpha
- Product Launch Team
- Customer Success
그룹 생성 및 관리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Admin > People > Groups > Create a group
Name: Sales Team
Description: 영업팀 멤버 - 매출 및 고객 데이터 접근
Members:
- jane@company.com (Sales Manager)
- john@company.com (Sales Rep)
- sarah@company.com (Sales Rep)
Data permissions:
✅ Sample Database > Orders (Full access)
✅ Sample Database > Customers (Full access)
❌ Sample Database > Internal (No access)
Collection permissions:
✅ Sales Analytics (Edit)
👁️ Executive Dashboard (View only)
❌ Finance Reports (No access)
Data Permissions
권한 레벨
graph LR
A[No access] --> B[Limited access]
B --> C[Unrestricted access]
A --> A1[테이블 안 보임]
B --> B1[GUI만 사용]
B --> B2[승인된 쿼리만]
C --> C1[GUI + SQL]
C --> C2[모든 쿼리]
1. No access (접근 불가)
1
데이터베이스/테이블이 존재하지 않는 것처럼 보임
2. Limited access (제한된 접근)
1
2
3
- GUI Query Builder만 사용 가능
- Native SQL 불가
- 또는 승인된 Models/Questions만 사용
3. Unrestricted access (무제한 접근)
1
2
3
- GUI + Native SQL 모두 사용
- 모든 테이블 접근
- 임의의 쿼리 실행
데이터베이스 수준 권한
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Admin > Permissions > Databases
Database: Sample Database
Group permissions:
┌─────────────────┬──────────────────────┐
│ Group │ Access Level │
├─────────────────┼──────────────────────┤
│ Administrators │ Unrestricted │
│ All Users │ No access │
│ Sales Team │ Limited (GUI only) │
│ Analysts │ Unrestricted │
│ Executives │ Limited (GUI only) │
└─────────────────┴──────────────────────┘
테이블 수준 권한
1
2
3
4
5
6
7
8
9
10
11
12
Admin > Permissions > Databases > Sample Database
Sales Team permissions:
┌───────────────┬──────────────────────┐
│ Table │ Access Level │
├───────────────┼──────────────────────┤
│ Orders │ Unrestricted │
│ Customers │ Unrestricted │
│ Products │ Sandboxed (특정 행만)│
│ Employees │ No access │
│ Financial │ No access │
└───────────────┴──────────────────────┘
SQL Permissions
Native Query 권한:
1
2
3
4
5
6
7
8
9
10
11
12
Group: Junior Analysts
SQL permissions:
○ No native query access
● Can write native queries
☑ Must be approved before running
☑ Query results reviewed
Use case:
- 학습 중인 분석가
- 쿼리 리뷰 후 실행
- 데이터 보안 유지
Collection Permissions
Collection 구조 설계
Best Practice 폴더 구조:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Our analytics/
├── Executive/
│ ├── Company Overview (View: Executives, Edit: Admin)
│ └── Board Reports (View: Board, Edit: CFO)
├── Sales/
│ ├── Daily Metrics (View: Sales, Edit: Sales Analysts)
│ ├── Customer Analysis (View: Sales + Marketing)
│ └── Forecasting (View: Sales Managers, Edit: FP&A)
├── Marketing/
│ ├── Campaign Performance (View: Marketing, Edit: Marketing Analysts)
│ ├── Attribution (View: Marketing + Sales)
│ └── Ad Hoc Analysis (Edit: Marketing Team)
├── Product/
│ ├── Usage Metrics (View: Product + Eng)
│ ├── Feature Performance (Edit: Product Analysts)
│ └── A/B Tests (Edit: Data Science)
├── Finance/
│ ├── Revenue Reports (View: Finance + Exec)
│ ├── Cost Analysis (View: Finance only)
│ └── Internal (View: CFO only)
└── Shared/
├── Company KPIs (View: All Users)
└── Data Dictionary (View: All Users)
Collection 권한 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Collection: Sales Analytics
Permissions:
┌─────────────────┬──────────────────────┐
│ Group │ Access Level │
├─────────────────┼──────────────────────┤
│ Administrators │ Curate (최고 권한) │
│ Sales Managers │ Curate │
│ Sales Team │ Edit │
│ Marketing │ View │
│ All Users │ No access │
└─────────────────┴──────────────────────┘
Access levels:
- Curate: 보기 + 편집 + 권한 관리
- Edit: 보기 + 편집
- View: 보기만
- No access: 접근 불가
Row-Level Security (행 수준 보안)
📝 용어 변경: v0.56부터 “데이터 샌드박싱(Data Sandboxing)”이 공식적으로 “행 수준 보안(Row-level Security)”으로 명칭이 변경되었습니다. 기능은 동일하며, 열 수준 권한(Column-level Permissions)과 함께 더 세밀한 보안 제어가 가능합니다.
개념
특정 사용자/그룹이 테이블의 일부 행만 볼 수 있도록 제한
1
2
3
4
5
6
7
8
-- 일반 쿼리
SELECT * FROM orders
-- 모든 주문 표시
-- Row-level security 적용 후
SELECT * FROM orders
WHERE sales_rep_id =
-- 해당 영업 담당자의 주문만 표시
열 수준 권한 (Column-level Permissions) - v0.56+
특정 컬럼 숨기기:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Admin > Permissions > Databases > Sample Database
Table: Customers
Group: Sales Reps
Column permissions:
✅ id (view)
✅ name (view)
✅ email (view)
❌ credit_card (hidden)
❌ ssn (hidden)
✅ total_spent (view)
Result:
Sales Reps는 민감한 컬럼(신용카드, SSN)을 볼 수 없음
Sandboxing 설정
1
2
3
4
5
6
7
8
9
10
11
12
13
Admin > Permissions > Databases > Sample Database
Table: Orders
Group: Sales Reps
Sandboxed access:
☑ Enable row-level permissions
Attribute to filter on: sales_rep_id
User attribute to use: user_id
Result:
Sales Rep #123은 sales_rep_id = 123인 주문만 볼 수 있음
User Attributes (사용자 속성)
속성 정의:
1
2
3
4
5
6
7
Admin > People > john@company.com > Edit
User attributes:
- user_id: 123
- region: West
- department: Sales
- level: Manager
Sandboxing 예제:
예제 1: 지역별 접근
1
2
3
4
5
6
7
8
9
10
11
Table: Customers
Group: Regional Managers
Sandbox:
Filter: state IN ()
User: Jane (Regional Manager - West)
user_regions: ['CA', 'OR', 'WA', 'NV']
Result:
Jane은 서부 지역 고객만 볼 수 있음
예제 2: 계층 기반 접근
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Table: Orders
Group: Managers
Sandbox:
Filter:
CASE
WHEN = 'Executive' THEN TRUE
WHEN = 'Manager' THEN department =
ELSE sales_rep_id =
END
Result:
- Executive: 모든 주문
- Manager: 자신의 부서 주문
- Rep: 자신의 주문만
예제 3: 시간 기반 접근
1
2
3
4
5
6
7
8
9
10
11
Table: Financial_Reports
Group: Auditors
Sandbox:
Filter: report_date >= DATE_SUB(CURRENT_DATE, INTERVAL DAY)
User: External Auditor
retention_days: 90
Result:
최근 90일 리포트만 접근 가능
Advanced Sandboxing
다중 조건:
1
2
3
4
5
6
7
8
9
10
11
12
Table: Orders
Group: Sales Analysts
Sandbox filters (AND 조건):
1. region =
2. created_at >= '2024-01-01'
3. status IN ('completed', 'shipped')
Result:
- 자신의 지역만
- 2024년 이후만
- 완료/배송 상태만
동적 테이블:
1
2
3
4
5
6
-- User attribute: accessible_customers (쉼표 구분 ID 목록)
-- "101,102,103"
SELECT *
FROM orders
WHERE customer_id IN ()
권한 설계 패턴
패턴 1: Role-Based (역할 기반)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Groups:
- Admin
- Analyst
- Manager
- Viewer
Permissions:
Admin:
Data: All databases (Unrestricted)
Collections: All (Curate)
Analyst:
Data: Production DB (Unrestricted)
Collections: Analytics (Edit), Others (View)
Manager:
Data: Production DB (Limited - GUI only)
Collections: Department (Edit), Company (View)
Viewer:
Data: Production DB (No access)
Collections: Dashboards only (View)
패턴 2: Department-Based (부서 기반)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Groups by Department:
- Sales
- Marketing
- Finance
- Engineering
- HR
Permissions:
Sales:
Data: Orders, Customers (Unrestricted)
Collections: Sales folder (Edit)
Sandboxing: own territory
Finance:
Data: Financial tables (Unrestricted)
Collections: Finance folder (Curate)
Sandboxing: none (full access)
Marketing:
Data: Campaigns, Analytics (Limited)
Collections: Marketing folder (Edit)
Sandboxing: own campaigns
패턴 3: Project-Based (프로젝트 기반)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Groups by Project:
- Project Alpha Team
- Product Launch Team
- Customer Success Initiative
Permissions:
Project Alpha:
Data: Alpha DB (Unrestricted)
Collections: Project Alpha folder (Curate)
Duration: 2025-01-01 to 2025-06-30 (임시)
Product Launch:
Data: Products, Orders (Limited)
Collections: Launch Metrics (Edit)
Collaboration: with Marketing, Sales
패턴 4: Hybrid (혼합)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Groups:
- By Role: Admin, Analyst, Viewer
- By Department: Sales, Marketing, Finance
- By Project: Special initiatives
User: Jane
Groups:
- Analyst (role)
- Marketing (department)
- Project Alpha (project)
Effective permissions:
- Analyst 권한 (기본)
- Marketing 데이터 추가 접근
- Project Alpha 컬렉션 추가 접근
계산: 모든 그룹 권한의 합집합 (가장 높은 권한 적용)
보안 Best Practices
1. 최소 권한 원칙
1
2
3
4
5
6
7
8
9
10
기본: No access
필요시: 점진적으로 권한 부여
❌ 나쁜 예:
신규 사용자에게 "All Users = Unrestricted" 부여
✅ 좋은 예:
1. 신규 사용자는 View only
2. 필요성 검증 후 Edit 권한
3. 비즈니스 케이스 있으면 Curate
2. 정기 권한 감사
1
2
3
4
5
6
7
8
9
10
11
12
13
14
월간:
- 비활성 사용자 확인
- 불필요한 권한 제거
- 새 팀원 온보딩
분기별:
- 그룹 구조 리뷰
- 데이터 접근 패턴 분석
- 권한 매트릭스 업데이트
연간:
- 전체 권한 재설계 검토
- 비즈니스 변화 반영
- 보안 정책 업데이트
3. 민감 데이터 보호
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
High sensitivity (높은 민감도):
- PII (개인식별정보)
- 금융 데이터
- 비밀 프로젝트
Protection:
1. 별도 데이터베이스 분리
2. 최소한의 그룹만 접근
3. No SQL access (GUI only)
4. Row-level security 적용
5. 감사 로그 모니터링
Example:
Table: customer_financial
Access: Finance team only
Sandboxing: 특정 고객만 (customer_id IN (...))
SQL: No (GUI only)
Logging: All queries logged
4. 외부 사용자 관리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
External Users (고객, 파트너, 컨설턴트):
Restrictions:
- 전용 그룹 생성 (External)
- 제한된 컬렉션 접근
- Public Links 대신 계정 제공 (추적 가능)
- Expiration date 설정
- 데이터 export 제한
Example:
Group: External Consultants
Data: Custom database view (민감 정보 제거)
Collections: Project X (View only)
Duration: 2025-01-01 to 2025-03-31
No download: CSV export disabled
5. 관리자 계정 보호
1
2
3
4
5
6
7
Admin account best practices:
- 2FA (Two-factor authentication) 활성화
- 강력한 비밀번호
- 정기적 비밀번호 변경
- 일반 작업은 일반 계정 사용
- 관리 작업만 Admin 계정 사용
- 모든 관리 작업 로깅
감사 및 모니터링
Audit Log
활성화:
1
2
3
4
5
6
7
8
9
Admin > Settings > General > Enable audit logging
Logged events:
- User login/logout
- Question/Dashboard created/edited/deleted
- Database connections added/modified
- Permissions changed
- Data exports
- Failed login attempts
로그 확인:
1
2
3
4
5
6
7
8
9
10
11
Admin > Troubleshooting > Logs > Audit
Filter:
User: john@company.com
Action: query
Date range: Last 7 days
Result:
- 2025-03-20 10:30: Created question "Sales by Region"
- 2025-03-20 11:15: Exported data (1,234 rows)
- 2025-03-20 14:00: Modified dashboard "Executive Summary"
사용 분석
활용도 모니터링:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- 사용자별 활동 (예: PostgreSQL 기반)
SELECT
user_id,
COUNT(*) as query_count,
COUNT(DISTINCT DATE(created_at)) as active_days
FROM query_execution_log
WHERE created_at >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY user_id
ORDER BY query_count DESC
-- 미사용 컨텐츠
SELECT
q.id,
q.name,
q.created_at,
COUNT(qe.id) as executions
FROM questions q
LEFT JOIN query_executions qe
ON q.id = qe.question_id
AND qe.created_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY q.id, q.name, q.created_at
HAVING COUNT(qe.id) = 0
ORDER BY q.created_at DESC
보안 알림
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Alert 설정:
1. 비정상적 데이터 export:
IF user.export_rows > 10000
THEN notify security_team
2. 권한 변경:
IF permission_changed
THEN notify admin + log
3. 실패한 로그인:
IF failed_logins > 5 IN 10 minutes
THEN lock account + notify
4. 민감 데이터 접근:
IF table = 'financial'
THEN log + notify (real-time)
실전 연습 문제
연습 1: 기본 권한 설정 (초급)
과제: 3개 부서의 권한 구조 설정
부서:
- Sales: Orders, Customers 접근
- Marketing: Campaigns, Analytics 접근
- Finance: 모든 데이터 접근
해답 보기
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
Groups 생성:
1. Sales Team
2. Marketing Team
3. Finance Team
Data Permissions:
Sales Team:
Database: Production
Orders: Unrestricted
Customers: Unrestricted
Products: Limited (GUI only)
Campaigns: No access
Financial: No access
Marketing Team:
Database: Production
Campaigns: Unrestricted
Analytics: Unrestricted
Customers: Limited (GUI only)
Orders: Limited (GUI only)
Financial: No access
Finance Team:
Database: Production
All tables: Unrestricted
Native SQL: Allowed
Collection Permissions:
Sales Team:
- Sales Analytics: Edit
- Company Dashboards: View
- Others: No access
Marketing Team:
- Marketing Reports: Edit
- Company Dashboards: View
- Sales Analytics: View (협업)
- Others: No access
Finance Team:
- Finance Reports: Curate
- All other collections: View
연습 2: Row-Level Security (중급)
과제: 영업 담당자별 데이터 분리
요구사항:
- 각 영업 담당자는 자신의 고객만 볼 수 있음
- 매니저는 팀 전체 볼 수 있음
- VP는 모든 데이터 볼 수 있음
해답 보기
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
User Attributes 설정:
User: john@company.com (Sales Rep)
- user_id: 123
- role: rep
- team_id: 5
User: jane@company.com (Sales Manager)
- user_id: 456
- role: manager
- team_id: 5
User: mike@company.com (VP Sales)
- user_id: 789
- role: vp
Groups:
- Sales Reps
- Sales Managers
- Sales Leadership
Sandboxing:
Table: Customers
Group: Sales Reps
Filter:
sales_rep_id =
Table: Customers
Group: Sales Managers
Filter:
sales_rep_id IN (
SELECT id FROM sales_reps
WHERE team_id =
)
Table: Customers
Group: Sales Leadership
Filter: (none - 모든 데이터)
Table: Orders
(동일한 로직 적용)
Result:
- John (Rep): 자신의 고객 123번만
- Jane (Manager): 팀 5의 모든 담당자 고객
- Mike (VP): 모든 고객
연습 3: 복합 보안 시나리오 (고급)
과제: 외부 컨설턴트 접근 관리
요구사항:
- 특정 프로젝트 데이터만 접근
- 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
1. 전용 Database View 생성:
CREATE VIEW consultant_view AS
SELECT
o.id,
o.created_at,
o.total,
-- PII 제외
CONCAT('Customer ', o.customer_id) as customer_ref,
-- 주소 제외
c.state as customer_state,
-- 이메일/전화 제외
p.category as product_category
FROM orders o
JOIN customers c ON o.customer_id = c.id
JOIN products p ON o.product_id = p.id
WHERE o.project = 'Project Alpha'
AND o.created_at >= '2025-01-01';
2. Group 생성:
Name: External Consultants - Project Alpha
Description: 임시 접근 (2025-01-01 ~ 2025-03-31)
Members:
- consultant@external.com
3. Data Permissions:
Database: Analytics
consultant_view: Limited (GUI only)
All other tables: No access
Native SQL: No
4. Collection Permissions:
Project Alpha Reports: View only
All others: No access
5. Additional Restrictions:
Settings > External Consultants group:
- Disable data exports
- Disable dashboard subscriptions
- Link sharing: No
6. Monitoring:
Audit log filter:
Group: External Consultants
Alert on:
- Any export attempt
- Access outside working hours
- More than 100 queries/day
Weekly report to:
- Project owner
- Security team
7. Expiration:
Calendar reminder: 2025-03-31
- Disable accounts
- Revoke all access
- Export activity log
- Archive project data
다음 단계
권한과 보안을 마스터했습니다. 다음 포스트에서는:
- 임베딩과 공유: Public dashboards, iFrames
- 외부 통합: 웹사이트에 대시보드 삽입
- 화이트라벨링: 브랜딩 커스터마이징
요약
권한 체크리스트
사용자 관리:
- 조직 구조 기반 그룹 생성
- 역할 정의 및 문서화
- 신규 사용자 온보딩 프로세스
- 퇴사자 접근 제거 프로세스
데이터 권한:
- 데이터베이스별 접근 정책
- 테이블별 세밀한 권한
- Row-level security 검토
- SQL 권한 제한
컬렉션 권한:
- 논리적 폴더 구조
- 부서별 컬렉션 분리
- 공유 리소스 식별
- 편집 권한 최소화
보안:
- 최소 권한 원칙 적용
- 정기 감사 스케줄
- 민감 데이터 보호
- 감사 로그 모니터링
다음 포스트에서는 Metabase를 외부에 공유하고 임베딩하는 방법을 배웁니다!
📚 시리즈 전체 목차
🚀 기초편 (1-5화)
💪 활용편 (6-10화)
- 필터와 파라미터
- SQL 네이티브 쿼리
- 데이터 모델링
- 자동화와 알림
- [권한과 보안] (현재 글)
🎯 고급편 (11-16화)
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.