본문으로 건너뛰기

보안 모델

Semaphore는 인프라의 자격 증명을 보관하고 그 인프라를 대상으로 코드를 실행합니다. 여기서 두 가지 성질이 따라 나오며, 이 페이지의 다른 모든 결정도 그 두 가지에서 비롯됩니다. 시크릿은 절대로 브라우저로 되돌아가서는 안 되고, 태스크를 시작할 수 있는 사람은 그 태스크가 도달하는 머신에서 코드를 실행할 수 있습니다.

이 페이지는 모델을 설명합니다. 이를 구현하는 설정은 보안을 참고하세요.

신뢰 경계

경계넘나드는 것보호 수단
브라우저 ↔ 서버세션, API 토큰TLS, 보안 쿠키, 리버스 프록시
서버 ↔ 데이터베이스모든 영구 상태네트워크 제한, 기록 전에 암호화되는 시크릿
서버 ↔ 러너시크릿을 포함한 작업 페이로드HTTPS와 러너별 베어러 토큰
태스크 ↔ 관리 대상 호스트사용자의 자동화템플릿에 지정한 키

태스크는 이 모든 경계의 바깥쪽에 있습니다. 필요한 시크릿을 환경으로 전달받으며, 그 순간부터는 저장소에 있는 코드가 그 시크릿을 어떻게 다룰지 결정합니다.

신원 확인

사용자는 세 가지 방법 중 하나로 인증하며, 세 방법 모두 동일한 세션으로 이어집니다.

  • 로컬 계정. 비밀번호는 Argon2id로 해시됩니다(2.20 이전에는 bcrypt였고, 첫 로그인 시 업그레이드됩니다). TOTP 2단계 인증을 필수로 설정할 수 있습니다.
  • LDAP 또는 Active Directory. 디렉터리가 비밀번호를 검증하고, Semaphore는 계정만 보관합니다.
  • OpenID Connect. 공급자가 인증하고 Semaphore는 클레임을 사용자에 매핑합니다.

비대화형 접근에는 사용자가 생성한 API 토큰을 사용하며, 이 토큰은 해당 사용자의 권한을 그대로 가집니다. 러너는 사용자 신원을 전혀 사용하지 않고, 등록 시 발급된 자체 토큰으로 인증합니다.

태스크도 신원을 가질 수 있습니다. 태스크 JWT를 쓰면 실행은 프로젝트, 템플릿, 사용자를 명시한 수명이 짧은 서명 토큰을 받고, 외부 시크릿 저장소가 이를 검증할 수 있으므로 수명이 긴 자격 증명을 저장할 필요가 없습니다.

권한 부여

두 개의 수준이 있으며 서로 독립적입니다.

서버 수준. 관리자는 사용자, 전역 러너, 서버 설정을 관리합니다. 서버 관리자라는 사실만으로 프로젝트의 구성원이 되지는 않습니다.

프로젝트 수준. 각 구성원은 프로젝트마다 하나의 역할을 가집니다.

역할할 수 있는 일
Owner구성원 관리와 삭제를 포함해 프로젝트의 모든 것.
Manager태스크 실행, 리소스와 템플릿 관리.
Task Runner태스크 실행. 그 외에는 아무것도 할 수 없습니다.
Guest읽기.

이 네 가지로는 너무 뭉뚱그려진다면 Enterprise에서 사용자 지정 역할 Enterprisesince 2.17을 추가할 수 있습니다.

보안상 중요한 선은 Task RunnerManager 사이에 그어집니다. Manager는 템플릿이 무엇을 실행할지 바꿀 수 있으므로, 해당 프로젝트의 자격 증명으로 임의의 코드를 실행할 수 있습니다. Task Runner는 이미 존재하는 것만 시작할 수 있습니다. 단, 템플릿이 명령줄까지 전달되는 프롬프트나 설문 변수를 노출한다면 예외이며, 이 경우 템플릿 작성자가 그 경계를 의도적으로 넓힌 것입니다.

시크릿

SSH 개인 키, 비밀번호, 토큰, 비밀 변수 같은 비밀 값은 저장되기 전에 access_key_encryption의 키로 암호화되므로, 데이터베이스 덤프만으로는 내용이 드러나지 않습니다. API는 비밀 값을 절대 반환하지 않으며, UI는 값이 무엇인지가 아니라 값이 설정되어 있다는 사실만 보여 줍니다.

시크릿은 태스크가 시작되는 순간 환경을 통해 태스크에 전달됩니다. 그래서 태스크 출력도 민감 정보로 다루어야 합니다. 변수를 출력하는 플레이북은 그 값을 다른 프로젝트 구성원이 읽을 수 있는 로그에 남기게 됩니다.

시크릿을 아예 보관하고 싶지 않다면, 외부 시크릿 저장소를 사용해 값을 HashiCorp Vault, OpenBao, AWS Secrets Manager, Devolutions Server에 두고 실행할 때마다 가져올 수 있습니다.

신뢰할 수 없는 코드 실행

기본 구성에서 태스크는 Semaphore 서버의 파일 시스템과 네트워크 접근 권한을 가진 서버 프로세스입니다. 템플릿을 편집할 수 있는 모든 사람이 이미 서버를 맡길 만큼 신뢰받는 경우라면 적절한 방식입니다.

그렇지 않다면 실행을 서버 밖으로 옮기세요.

  • 러너는 태스크를 다른 머신에 배치하므로, 태스크가 침해되어도 웹 서비스나 데이터베이스는 영향을 받지 않습니다.
  • Docker 또는 Kubernetes 실행기는 각 작업에 새 컨테이너나 Pod를 제공하므로, 한 실행이 다른 실행의 파일이나 호스트의 파일을 읽을 수 없습니다.
  • 프로젝트와 키를 분리하면 태스크는 자기 프로젝트의 자격 증명이 허용하는 범위까지만 도달할 수 있습니다.
경고

프로젝트 구성원이 변경할 수 있는 저장소는 곧 그 프로젝트의 자격 증명으로 실행될 코드입니다. 템플릿이 사용하는 브랜치를 보호하거나, 검토자만 쓸 수 있는 브랜치를 템플릿이 가리키게 하세요.

사용자에게 남겨지는 부분

Semaphore는 셀프 호스팅 방식이므로, 모델의 일부는 사용자가 직접 갖추어야 합니다.

  • 서비스 앞단의 TLS. 내장 기능을 쓰든 리버스 프록시를 쓰든 상관없습니다.
  • 데이터베이스와 서버 관리 영역에 대한 네트워크 접근 제한.
  • 데이터베이스와 access_key_encryption의 백업. 뒤의 것은 앞의 것 없이는 쓸모가 없고, 앞의 것은 뒤의 것 없이는 읽을 수 없습니다.
  • 최신 버전 유지. 취약점은 [email protected]으로 제보하세요.

다음 단계

  • 보안 — 구체적인 설정, 해싱 매개변수, 강화 절차.
  • 아키텍처 — 이 경계들이 나누는 구성 요소.
  • — 프로젝트에서 역할 할당하기.