참조
Runner Plugin OCI Distribution
Runner-managed on-demand plugin을 OCI로 설치하고 resolve하는 모델과 현재 구현 상태를 설명합니다.
Runner Plugin OCI Distribution
이 문서는 Runner-managed on-demand plugin을 OCI 기반 plugin bundle로 배포하는 권장 모델을 정의합니다.
현재 Runner 구현은 다음 첫 번째 end-to-end OCI install 경로까지 지원합니다.
runner-plugin-runtime.example.yaml형태의 설정 파싱resolution.capability_map기반 capability index 생성- startup 시 preinstall 대상 설치 시도
- 첫 resolve 시 on-demand install 시도
docker pull -> image inspect -> create -> cp -> rm순서로 plugin bundle unpackrunner-plugin.yamlvalidation- 유효한
stdio-jsonplugin의 on-demand 실행 - 설치 또는 실행 실패 시 기존
PLUGIN_*_URLHTTP plugin으로 fallback
다만 OCI signature verification은 아직 미구현이고, 기존 HTTP plugin URL은 호환성 경로로 계속 유지됩니다.
왜 OCI를 써야 하나
Runner 호스트에 임의의 폴더를 복사하는 방식보다 OCI 배포가 더 나은 이유는 다음과 같습니다.
- 버전 관리
- digest pinning
- signature verification
- registry 기반 접근 제어
- 반복 가능한 설치와 롤백
즉 고객 관리형 Runner 환경의 장기 모델로 더 적합합니다.
권장 모델
권장 배포 흐름은 다음과 같습니다.
- plugin author가 plugin bundle 생성
- bundle 안에
runner-plugin.yaml과 runtime 파일 포함 - bundle을 OCI artifact 또는 image로 publish
- publisher가 artifact에 서명
- Runner가 digest 기준으로 pull
- Runner가 관리되는 install 디렉터리로 unpack
- Runner가 manifest를 읽음
- Runner가 capability index 생성
- Core는 capability를 참조하고, Runner가 이를 설치된 bundle로 resolve
패키징 형태
현재 Runner install 로직은 image의 Config.WorkingDir 를 관리되는 install 디렉터리로 unpack 합니다. 따라서 호환되는 image는 다음을 만족해야 합니다.
- 비어 있지 않은 OCI
Config.WorkingDir - 그 working directory 안의
runner-plugin.yaml runner-plugin.yaml이 가리키는 실제 entrypoint 파일
OCI로 전달된 plugin은 unpack 후 다음과 같은 디렉터리 구조를 갖는 것이 좋습니다.
<install-root>/<plugin-name>/<digest>/
runner-plugin.yaml
package.json
src/
shared/
예:
/var/lib/aisopsflow-runner/plugins/gmail/sha256-aaaaaaaa/
runner-plugin.yaml
package.json
src/runner-entrypoint.ts
Runner 디렉터리 레이아웃
권장 로컬 경로:
/var/lib/aisopsflow-runner/
state/
plugin-cache/
plugins/
gmail/
microsoft-email/
microsoft-office/
manifests/
역할:
plugin-cache/- 다운로드된 OCI layer 또는 unpack staging 데이터
plugins/- 실제로 실행 가능한 설치 bundle
manifests/- 선택적으로 로컬 resolution snapshot 또는 catalog cache
권장 Runner 설정 파일
참조 예시:
이 파일은 이제 현재 Runner 구현에서 capability index, install root, preinstall, on-demand resolution에 실제로 사용됩니다.
Capability resolution 모델
Core는 절대 경로가 아니라 plugin capability를 참조하는 것이 좋습니다.
예시 planned job 조각:
{
"kind": "plugin_call",
"plugin_capability": "gmail.read",
"input": {
"query": "from:alerts@example.com newer_than:1d"
}
}Runner는 이를 다음 순서로 resolve 합니다.
- capability map
- local install state
- manifest validation
- local policy
resolve 결과:
- capability -> OCI ref
- OCI ref -> installed digest directory
- digest directory ->
runner-plugin.yaml - manifest -> entrypoint 와 env allowlist
배포 흐름
Publisher 측
- plugin bundle 빌드
runner-plugin.yaml포함- registry에 publish
- artifact 서명
- digest reference를 고객 또는 plugin catalog에 제공
Customer / operator 측
- Runner config에 trusted registry 허용
- pull credential 설정
- 정확한 plugin digest pin
- plugin ref를 install 또는 preinstall 목록에 추가
- Runner 재시작 또는 catalog sync 트리거
Runner 측
현재 구현:
- 로컬
dockerCLI로 image pull Config.WorkingDirinspect- 임시 container 생성
- working directory를 install root로 복사
- 임시 container 제거
runner-plugin.yamlvalidationstdio-json로 plugin on-demand spawn- 실행 실패 시 legacy HTTP plugin URL로 fallback
목표 상태에서 추가될 항목:
- signature 검증
- manifest 선언 기반 네트워크 정책 강제
- 지원 capability에 대한 legacy HTTP fallback 제거
권장 설정 섹션
목표 상태 Runner config에는 다음 섹션이 들어가는 것이 좋습니다.
plugin_runtimeregistrycatalogplugins.preinstallresolutionsecretspoliciesobservability
보안 규칙
현재 코드가 실제로 강제하는 최소 규칙:
- configured capability map에 있는 capability만 resolve
registry.require_digest_pinning이 켜져 있으면 digest pinning 강제runner-plugin.yaml이 없거나 invalid면 managed execution 거부- allowlist된 env var만 managed plugin에 주입
추가로 권장하는 규칙:
- allowlist된 registry에서만 pull
- install 전 signature 검증
- capability mapping이 없으면 실행 거부
강력 권장:
- registry credential과 provider credential 분리
- 설치된 digest와 manifest hash를 Runner telemetry에 기록
- plugin write는 기본 비활성화
- write/delete capability는 승인 필요
왜 로컬 폴더 복사보다 낫나
로컬 폴더 복사는 개발용으로는 쓸 수 있지만, 운영에서는 OCI install이 더 낫습니다. 이유는:
- provenance
- repeatability
- 통제된 업데이트
- 더 쉬운 운영 지원
- 더 명확한 compatibility 추적
현재 호환성 동작
현재 managed execution은 다음 조건이 모두 맞을 때만 적용됩니다.
- capability가
resolution.capability_map에 있어야 함 - OCI image를 pull할 수 있거나 로컬에 이미 있어야 함
- image가 유효한
Config.WorkingDir를 가져야 함 - unpack된 bundle에 유효한
runner-plugin.yaml이 있어야 함 - manifest가 가리키는 entrypoint가 실제로 시작되어야 함
이 중 하나라도 실패하면 현재 코드는 여전히 다음 env var를 사용합니다.
PLUGIN_SLACK_URLPLUGIN_EMAIL_URLPLUGIN_TELEGRAM_URLPLUGIN_KAKAO_URLPLUGIN_TEAMS_URL
참조: Config.hs
또한 notify 응답에는 다음 managed-runtime 메타데이터가 함께 담깁니다.
transportplugin_refinstall_pathmanifest_pathruntime_error
즉 운영자는 Runner가 managed plugin을 실제 실행했는지, 아니면 legacy HTTP 경로로 fallback 했는지 응답만 보고도 확인할 수 있습니다.