OCI Registryはcontainer image以外のcontent distribution primitiveにもなる
OCI Registryはcontainer image専用のpackage repositoryとして理解されがちだが、現在のOCI Distribution Specificationはより一般に、contentをpush/pull/discover/manageするprotocolとして定義されている。仕様自身がcontent typeにagnosticであり、container imageは最も主要な利用例だとしている。
この性質は、binary cacheとpackage repositoryは似ているが一次性が違う のさらに下にあるstorage/distribution primitiveとして見ると分かりやすい。
OCI Distributionでは、binary contentはdigestでaddressされるBlobとして保存される。ManifestはJSON documentで、Descriptorを通じてblobや別manifestをmedia type・size・digest付きで参照する。Tagはhuman-readableなmutable pointerであり、一つのmanifest digestに複数tagを付けられる。
この構造はpackage managerを作るうえで有用な部品を既に提供している。
- content-addressed blob storage
- manifestによる複数blobのbundle/graph表現
- digestによるcontent verification
- resumable push/pull
- blob upload de-duplication
- registry/repository namespace
- tagによるhuman-readable reference
- subject/referrersによる別artifactの関連付け
しかしOCI Distribution Specは、それだけでは「package manager」にならない。package name/version semantics、dependency solver、OS/ABI compatibility、build recipe、source fallback、install prefix、activation等は上位layerが決める必要がある。
つまりOCI Registryは、ビルド済みパッケージ配布を一括りにしない のどのモデルにもbackendとして使い得る。例えばSpackはOCI registryをbuild cacheとして利用できる。別のsystemではOCI artifactをbinary package repositoryとして扱うことも、build provenanceやsignatureをsubject/referrerとして付けることもできる。
この点はcontent addressingはprovenanceではないとも関係する。OCI Blobのdigestは「取得したbytesがdescriptorで期待されたcontentか」を検証する。しかし、そのblobがどのsource/build pipelineから作られたかはdigestだけでは分からない。signature、attestation、SBOM、provenance等は別objectとして関連付ける必要がある。
またTagとDigestの違いは署名検証だけではrollback・freeze attackを防げないにも繋がる。latestやversion tagのようなhuman-readable pointerは別manifestへ動かせる一方、digest referenceは特定contentを固定する。reproducible deploymentではdigest pinningが有効だが、pinningした古いdigestがsecurity上いつまでも安全という意味ではない。
OCIの重要な特徴は、package formatとdistribution protocolを分離できることである。独自binary cache protocolを作らず、CAS・upload/download・registry authentication・mirroring等をOCI ecosystemへ委ね、その上にpackage-specific metadataだけを載せる設計が可能になる。
ただしその場合も、manifest schemaやmedia type、dependency relation、garbage collection、tag mutation policy等を設計しなければならない。OCIを採用しただけでNix/Conda/aqua型のpackage semanticsが得られるわけではない。