Open6

ghcr.io のパッケージのデフォルトの可視性(個人アカウント用の構成)

hankei6kmhankei6km

Dev Container の Feature を作っていると、パッケージの可視性について テンプレートの README に記載されている状況と少し食い違った。あと、関連して ORAS が面白そうなので少し調べている。

ということで ghcr.io [1]でのデフォルトのパッケージ可視について調べてみると込み入っていたので(記述が分散している)メモ。

脚注
  1. GitHub Packages 全体で同じと思うけど、検証していないので ghcr に限定している。 ↩︎

hankei6kmhankei6km

思ったよりも長くなのったので、とりあえず簡単にまとめると下記のようになる。

  • GitHub Actions の自動トークン認証のトークン(GITHUB_TOKEN)を使う場合はリポジトリの可視性を継承
    • GitHub Actions でも PAT(Classic) を使った場合はプライベート
  • PAT(Classic) を使う場合はプライベート

なお、いったんパブリックにするとプライベートには戻せないとあるが、これは本当にそうなのかは不明。

hankei6kmhankei6km

認証方法

ghcr へ push するための認証方法は現状では 2 種類ある。

  • GitHub Actions の自動トークン認証のトークン(GITHUB_TOKEN)を利用する方法
  • PAT(Classic) を利用する方法

それぞれでデフォルトの可視性が異なる。なお、GitHub Apps でトークンを取得する方法は使えない。

hankei6kmhankei6km

GitHub Actions の自動トークン認証を使う場合

Actions の自動トークン認証を使う場合。

たとえば、ワークフローで GITHUB_TOKEN を使ってパッケージを作成する場合は、既定では次のようになります。

  • パッケージは、ワークフローが実行されたリポジトリの可視性とアクセス許可モデルを継承します。
  • パッケージが作成されると、ワークフローが実行されたリポジトリの管理者が、そのパッケージの管理者になります

これはパッケージをリポジトリへリンクしない場合でも適用されるもよう。なお、Actions でも PAT を利用して作成した場合はプライベートになる。

hankei6kmhankei6km

PAT(Classic)を使う場合

oras-cli などで認証に PAT(Classic)を使う場合。

可視性についてのページがあるのだが冒頭の記述は(たぶん)正しくない(この後の節で否定されている)。あとは、リポジトリにリンクしないパッケージも push できるので、どちらにしてもグローバルなデフォルトは存在することになる。

パッケージは、その可視性とアクセス許可をリポジトリから継承できますが、詳細なアクセス許可をサポートするレジストリの場合、リポジトリとは別にパッケージの可視性とアクセス許可を設定できます。

リポジトリにリンクされているパッケージを発行すると、既定で、パッケージはリンクされているリポジトリのアクセス許可を自動的に継承します (可視性はしません)

英語版のドキュメントだと違うのかなと思ったが、同じだった。

A package can inherit its visibility and access permissions from a repository,

By default, if you publish a package that is linked to a repository, the package automatically inherits the access permissions (but not the visibility) of the linked repository.

では、デフォルトはどうなのかというと、とりあえず個人アカウントの場合。

個人アカウントにスコープが指定されているパッケージを初めて公開する場合は、既定の可視性はプライベートであり、パッケージを表示できるのは自分だけです。 アクセス設定を変更すると、プライベートやパブリックのパッケージのアクセス権限を変更できます。

なお、ちょっと怖いことが書いてある。が試してみるとそうでもないような気もしないでもない(後述の検証より)。

パブリックパッケージは認証なしに匿名でアクセスできます。 いったんパッケージをパブリックに設定すると、そのパッケージをプライベートに戻すことはできません。

hankei6kmhankei6km

検証

パブリックなリポジトリを作って試してみた(プライベートなリポジトリの場合は今回未検証)。

https://github.com/hankei6km/test-oras-oras-cli

package1 は GITHUB_TOKEN を使っているのでプライベートではない(パッケージ名の横に Private が付いていない)。

GitHub のウェブ UI で package1 を表示しているスクリーンショット

package2 は PAT(Classic) を使っているのでプライベート(パッケージ名の横に Private が付いている)。
GitHub のウェブ UI で package2 を表示しているスクリーンショット

上の方でも少し触れたが、なぜかパブリックになっている状態からプライベートにできてしまう。

package1 の可視性を変更し、それぞれの状態で pull している様子。

$ ../bin/oras pull ghcr.io/hankei6km/test-oras-oras-cli/pacakge1:latest --registry-config=<(echo "{}")
Downloading c3447692c12a README.md
Downloaded  c3447692c12a README.md
Pulled [registry] ghcr.io/hankei6km/test-oras-oras-cli/pacakge1:latest
Digest: sha256:c5a25d105ef34ee6cc0e9f28eddac506ccaee5c81a37c8f690508a7cba5ff4e7

$ cat README.md
# test-oras-oras-cli

[ORAS](https://oras.land/) などを試してみるリポジトリ。

$ rm README.md

$ ../bin/oras pull ghcr.io/hankei6km/test-oras-oras-cli/pacakge1:latest --registry-config=<(echo "{}")
Error: failed to resolve latest: GET "https://ghcr.io/v2/hankei6km/test-oras-oras-cli/pacakge1/manifests/latest": GET "https://ghcr.io/token?scope=repository%3Ahankei6km%2Ftest-oras-oras-cli%2Fpacakge1%3Apull&service=ghcr.io": response status code 401: unauthorized: authentication required

$ cat README.md
cat: README.md: そのようなファイルやディレクトリはありません

$ ../bin/oras pull ghcr.io/hankei6km/test-oras-oras-cli/pacakge1:latest --registry-config=<(echo "{}")
Downloading c3447692c12a README.md
Downloaded  c3447692c12a README.md
Pulled [registry] ghcr.io/hankei6km/test-oras-oras-cli/pacakge1:latest
Digest: sha256:c5a25d105ef34ee6cc0e9f28eddac506ccaee5c81a37c8f690508a7cba5ff4e7

$ cat README.md
# test-oras-oras-cli

[ORAS](https://oras.land/) などを試してみるリポジトリ。

ドキュメントはこういう意味では言っていない?(パブリックにしてダウンロードされたものは無かったことにできないぞ、的なこと?)