Azure Cosmos DB for PostgreSQL의 행 수준 보안

적용 대상: Azure Cosmos DB for PostgreSQL(PostgreSQL에 대한 Citus 데이터베이스 확장 기반)

PostgreSQL 행 수준 보안 정책은 어떤 사용자가 어떤 테이블 행을 수정하거나 액세스할 수 있는지 제한합니다. 행 수준 보안은 다중 테넌트 클러스터에서 특히 유용할 수 있습니다. 이를 통해 개별 테넌트가 데이터베이스에 대한 전체 SQL 액세스 권한을 가지면서 각 테넌트의 정보를 다른 테넌트로부터 숨길 수 있습니다.

다중 테넌트 앱 구현

테이블 행 수준 보안 정책에 연결된 데이터베이스 역할에 대한 명명 규칙을 사용하여 테넌트 데이터 분리를 구현할 수 있습니다. 각 테넌트에 tenant1, tenant2 등 번호가 매겨진 시퀀스대로 데이터베이스 역할을 할당합니다. 테넌트는 이러한 개별 역할을 사용하여 Azure Cosmos DB for PostgreSQL에 연결합니다. 행 수준 보안 정책은 역할 이름을 tenant_id 배포 열의 값과 비교하여 액세스 허용 여부를 결정할 수 있습니다.

다음은 tenant_id에서 배포하는 단순화된 이벤트 테이블에 방법을 적용하는 방법입니다. 먼저 tenant1tenant2역할을 만듭니다. 그런 다음 citus 관리자 사용자로 다음 SQL 명령을 실행합니다.

CREATE TABLE events(
  tenant_id int,
  id int,
  type text
);

SELECT create_distributed_table('events','tenant_id');

INSERT INTO events VALUES (1,1,'foo'), (2,2,'bar');

-- assumes that roles tenant1 and tenant2 exist
GRANT select, update, insert, delete
  ON events TO tenant1, tenant2;

그대로 이 테이블에 대한 선택 권한이 있는 사람은 두 행을 모두 볼 수 있습니다. 두 테넌트의 사용자는 다른 테넌트의 행을 보고 업데이트할 수 있습니다. 행 수준의 테이블 보안 정책으로 데이터 누출을 해결할 수 있습니다.

각 정책은 USING 및 WITH CHECK의 두 절로 구성됩니다. 사용자가 행을 읽거나 쓰려고 하면 데이터베이스는 이러한 절에 대해 각 행을 평가합니다. PostgreSQL은 USING 절에 지정된 식에 대해 기존 테이블 행을 확인하고 WITH CHECK 절에 대해 INSERT 또는 UPDATE를 통해 만들어지는 행을 확인합니다.

-- first a policy for the system admin "citus" user
CREATE POLICY admin_all ON events
  TO citus           -- apply to this role
  USING (true)       -- read any existing row
  WITH CHECK (true); -- insert or update any row

-- next a policy which allows role "tenant<n>" to
-- access rows where tenant_id = <n>
CREATE POLICY user_mod ON events
  USING (current_user = 'tenant' || tenant_id::text);
  -- lack of CHECK means same condition as USING

-- enforce the policies
ALTER TABLE events ENABLE ROW LEVEL SECURITY;

이제 역할 tenant1tenant2는 쿼리에 대해 서로 다른 결과를 얻습니다.

tenant1로 연결됨:

SELECT * FROM events;
┌───────────┬────┬──────┐
│ tenant_id │ id │ type │
├───────────┼────┼──────┤
│         1 │  1 │ foo  │
└───────────┴────┴──────┘

tenant2로 연결됨:

SELECT * FROM events;
┌───────────┬────┬──────┐
│ tenant_id │ id │ type │
├───────────┼────┼──────┤
│         2 │  2 │ bar  │
└───────────┴────┴──────┘
INSERT INTO events VALUES (3,3,'surprise');
/*
ERROR:  new row violates row-level security policy for table "events_102055"
*/

다음 단계