2024/1/20 Colab の認証に任意のスコープを設定したい
code:auth.py
from google.colab import auth
auth.authenticate_user(project_id=PROJECT)
これでログインするやつ便利に使っているがスコープが足りなくて困ることがしばしばある
ちなみに scope を設定するインタフェースは公開されていない
code:scope
すると
code:out
がついている、よくあるやつ + Drive
読む
最近は認証を許可するウィンドウが開かれるやつになっている
環境変数 USE_AUTH_EPHEMが 1 なら今のやつ
_message.blocking_request これなんだ、これで済むの何〜
無理やり呼ぶ
code:call
auth._message.blocking_request(
'request_auth',
request={'authType': 'auth_user_ephemeral'}, # これ type 変えたらエラーだなあ
timeout_sec=None,
)
Colab の ipython カーネルがなんかカスタムされていて、このメッセージ送るとログインするフローが起動するって感じかなあ
request_type にどういうものがあるのか知る方法はあるのか?
code:kernel.py
from google.colab import _ipython as ipython
instance = ipython.get_kernelapp()
pprint(vars(instance)) # それっぽいのない
pprint(vars(instance.session))
たぶんこの仕組みだな
handler を list する方法ないか
message のパラメータでスコープ送れたら最高なのだが、期待できない気もする
InteractiveShellApp なんじゃろ
vars(instance.session)['_trait_values']['config'] 辺りを見ていくと
google.colab._kernel.Kernel やら
'InteractiveShellApp': {'extensions': ['google.colab'], ... やらが見える
Jupyter の kernel 側でやっていて、そこのコードは公開されていなさそう
以前のは auth._gcloud_login() で呼び出せる
URL おして Enter authorization code にコピペするやつ
これ再現する & gcloud_command 書き換えれば行けそうではある
その後 auth._install_adc() 呼ぶ
まあこれと同等のことやればスコープは渡せそう
こんな感じでやれば任意の scopes を渡して ADC を作れる /content/adc/application_default_crednetials.json に置かれる
内部で gcloud auth login 実行するところをフックする
前後で色々やっていてコピペしたくないので...
作れるのだが books API はブロックされる(そもそも手元からでも)
code:hack.py
from unittest.mock import patch
import subprocess
import google.colab
def add_scopes(scopes: liststr) -> callable: orig_popen = subprocess.Popen
def hook(*args, **kwargs):
opt_scopes = f"--scopes={','.join(scopes)}"
return orig_popen(cmd, **kwargs)
return hook
scopes = [
]
with patch('google.colab.auth._subprocess.Popen', side_effect=add_scopes(scopes)):
google.colab.auth._gcloud_login()
試行錯誤するためにログアウトしたい
!gcloud auth revoke はだめ
auth._get_adc_path() #=> /content/.adc/adc.json
空やな
auth._install_adc() すると /content/.config/credentials.db から読んで↑のパスに書かれる
任意のスコープ付ける別の手段として impersonate するのはアリ
これが一番無理がないな...
OAuth2 Login した際の scope は変えられないが tokenCreator として impersonate する際には scope をいじれる
code:impersonated.py
import google.colab
google.colab.auth.authenticate_user()
from google.auth import impersonated_credentials
sa = 'impersonate-test@******.iam.gserviceaccount.com'
creds, _ = google.auth.default(quota_project_id='******')
impersonated_creds = impersonated_credentials.Credentials(
source_credentials=creds,
target_principal=sa,
target_scopes=scopes,
lifetime=500,
)
from google.auth.transport.requests import AuthorizedSession
authed_session = AuthorizedSession(impersonated_creds)
response.json()