Demesne

Fóir가 동작하는 기반이 되는 권한 부여 엔진입니다. 액세스 규칙을 하나의 스펙 파일에 한 번만 작성하면 Demesne이 이를 Postgres 행 수준 보안으로 컴파일하고, 데이터베이스가 모든 쿼리에 이를 적용합니다. Fóir를 위해 만들었고 Apache 2.0 라이선스로 공개했습니다.

할 수 있는 일

Demesne 스펙은 네 가지를 기술합니다. 테넌시의 구조, 동작하는 사용자와 자격 증명의 종류, 그들이 다루는 테이블, 그리고 소유권, 역할, 공유, 그룹 구성원 자격 같은 이들을 잇는 관계입니다.

컴파일러는 이 파일에서 행 수준 보안 정책과 그 정책이 호출하는 데이터베이스 함수를 생성합니다. 행과 관계없는 질문("이 사용자가 게시할 수 있는가?")을 위한 Go와 TypeScript용 권한 맵, 그리고 세션이 지녀야 하는 클레임도 함께 생성합니다. 스펙을 바꾸고 다시 생성하면 데이터베이스와 애플리케이션 코드가 함께 바뀝니다.

규칙이 데이터베이스에 있는 이유

권한 부여는 보통 애플리케이션 코드에 있습니다. 호출하는 서비스이거나, 요청 핸들러 곳곳에 흩어진 검사입니다. 어느 쪽이든 확인을 잊지 않은 경로만 보호합니다. 백그라운드 작업, 새 엔드포인트, 데이터베이스 콘솔에 입력한 쿼리는 이를 우회합니다.

Demesne은 결정을 데이터 자체에 둡니다. 같은 정책이 어떤 코드가 보냈든 모든 쿼리를 필터링하므로, 검사를 잊은 경로도 호출자가 볼 수 있는 행만 돌려받습니다.

컴파일러를 만든 이유

행 수준 보안은 규칙을 두기에 알맞은 자리이지만 손으로 쓰기에는 까다롭습니다. 멀티 테넌트 제품에는 소유권, 역할, 중첩 그룹, 공유가 모든 테이블에 반복해서 필요하고, 이런 패턴은 미묘하게 틀리기 쉽습니다.

Demesne과 모델을 공유하는 엔진, 즉 Google의 Zanzibar와 이를 따르는 오픈 소스 프로젝트는 별도의 서비스로 실행됩니다. 애플리케이션은 결정마다 그 서비스를 호출해야 하고, 관계 정보의 사본을 데이터와 맞춰 유지해야 합니다. 저희는 서비스 없이 모델만 원했기 때문에, Demesne의 규칙은 쿼리와 같은 트랜잭션 안에서 기존 테이블을 읽습니다.

출력을 검증하는 방법

Demesne의 빌드는 생성된 모든 파일을 커밋된 사본과 바이트 단위로 비교합니다. 애플리케이션 쪽의 권한 검사는 각각 대응하는 정책의 조건을 그대로 담고 있으므로, 코드가 데이터베이스와 어긋나면 빌드가 실패합니다. 테스트 스위트는 실제 Postgres에서 실행되며 생성된 함수를 설치하고, SQL이 Go 및 TypeScript 버전과 사례별로 일치하는지 확인합니다.

이미 배포된 데이터베이스에는 demesne diff 명령으로 스펙과 현재 적용 중인 정책의 차이를 확인할 수 있습니다.

오픈 소스인 이유

누가 데이터를 읽을 수 있는지 결정하는 구성 요소는 직접 살펴볼 수 있어야 하는 구성 요소입니다. 어떤 플랫폼이든 테넌트가 격리되어 있다고 말할 수 있습니다. Demesne을 쓰면 저희 정책을 작성하는 컴파일러, 그 컴파일러가 통과해야 하는 테스트, 그리고 생성되는 SQL을 직접 읽을 수 있고, 이 모두를 직접 실행해 볼 수도 있습니다.

Demesne에는 Fóir에만 해당하는 부분이 없습니다. 모든 Postgres 데이터베이스에서 동작하며, 여러분의 로그인 공급자가 발급하는 세션을 읽습니다. 저장소의 가이드에는 기존 스키마에 도입하는 방법이 안내되어 있습니다. 저희 플랫폼에 관심이 없는 팀도 사용할 수 있으며, 이것이 모델이 제대로 버티는지 확인하는 가장 좋은 방법이라고 생각합니다.

Fóir에서의 의미

Fóir의 액세스 모델은 하나의 Demesne 스펙이며, 이 글을 쓰는 시점에 약 백 개의 테이블을 관장합니다. 테스트가 스키마의 모든 테이블을 나열하고, 보호 방식에 대한 기록된 결정 없이 추가된 테이블이 있으면 실패합니다.

레코드의 소유자나 모델을 읽을 수 있는 역할처럼 프로젝트에 직접 설정하는 규칙은 이러한 정책이 읽는 데이터이므로, 이 규칙도 데이터베이스 안에서 효력을 갖습니다. 데이터베이스에서의 강제 적용 페이지에서는 정책이 어떻게 생성되고, 강제되고, 테스트되는지 설명합니다.

여러분과 함께 가는 것

프로젝트의 Postgres 내보내기에는 각 사용자가 읽을 수 있었던 행을 그대로 재현하는 행 수준 보안 정책이 포함되어 있어, 이제 여러분이 소유하게 된 데이터베이스에 바로 적용할 수 있습니다. 전체 모델을 직접 운영하는 인프라에서 쓰고 싶다면, 이를 허용하는 라이선스로 엔진을 사용할 수 있습니다.

맞지 않는 경우

Demesne은 Postgres 전용입니다. 라이브러리이자 명령줄 도구이며, 호출할 호스팅 서비스는 없습니다. 모든 규칙을 SQL 조건으로 표현할 수 있어야 하고, 반대 방향의 질문("누가 이 레코드를 볼 수 있는가?")에는 보수적으로 답합니다. 저장소에는 Zanzibar, Ory Keto, OpenFGA, Cerbos, Oso와의 비교가 있으며, 각각이 더 나은 선택이 되는 경우를 설명합니다.

직접 확인하기

스펙 언어, 생성된 SQL, 테스트 스위트가 모두 저장소에 있습니다.