🌌

Check! GitHub Codespaces (コンテナ) で swa login/deploy の認証エラーの対処

2022/07/04に公開

Prologue

こんにちは、 @dz_ こと、大平かづみです。

最近はもっぱら GitHub Codespaces を使っていて、出張に来ている今も MacBook Air から Codespaces にアクセスして記事を書いています。

そんな Codespaces の環境で、Azure Static Web Apps のツール SWA CLI を使うとき、認証エラーに遭遇し結構悩んだ末に解決できたので、一部始終を書き留めます。

GitHub Codespaces 及び Azure Static Web Apps についての簡単な補足はこちら

GitHub Codespces 補足

GitHub Codespaces の実態は Docker コンテナで、GitHub がホストしてくれているコンテナの実行環境に Visual Studio Code の Remote-Container の仕組みを利用して、あたかも手元の環境で動かしているような感覚でコーディングできるのです。

Azure Static Web Apps 補足

Azure Static Web AppsMicrosoft Azure のサービスで、一言で言うと Azure 版 Netlify または Vercel です。React や Vue などのフロントエンドをデプロイして公開することができます。Azure Static Web Apps の強みは、バックエンドの API を Azure Functions や Web Apps、Container apps で構築できたり、Azure が持つ Webアプリケーションに必要なアーキテクチャと接続できる点だと、筆者は考えています。詳しく知りたい方は、下記がおすすめです。

現象: GitHub Codespaces 内で SWA CLI の login, deploy で認証エラーになってしまう

swa login または swa deploy を実行すると、ブラウザによるログインが促されます。

Note
--no-use-keychain については、後述

swa login --no-use-keychain

Welcome to Azure Static Web Apps CLI (1.0.1)

Checking Azure session...

ここでブラウザでログインし、シェルに戻ってテナントを選択したところで、下記のようなエラーが発生しました。

✔ Successfully logged into Azure!
✔ Choose your tenant › 12345678-1234-1234-1234-123456789012
✖ Failed to setup project: Interactive Browser Authentication Error "Did not receive token with a valid expiration"

✖ If you believe this behavior is unexpected, please raise a GitHub issue at:
  https://github.com/Azure/static-web-apps-cli/issues/new/choose

ブラウザでログインした直後の操作にもかかわらず、トークンの期限切れで認証エラーになってしまいます。手元の環境と codespace 上のタイムゾーンを揃えても改善できませんでした。ドキュメントにも特に記載はありません。

Note
なお、これは Windows で Visual Studio Code から codespace にアクセスしている場合に起きるようです。後述のように Mac ではデバイスログインに誘導され、このエラーは発生しませんでした。今外出先で検証できないので、後日確認でき次第更新します。

原因: コンテナで SWA CLI を利用する場合は、ブラウザによるログインは利用できない

その答えはコードにありました。オープンソース様々です。

下記のコードを見ると、Docker の中で SWA CLI を動かしている場合は、インタラクティブなブラウザによるログインはさせないという処理になっていました。

と言うのも、GitHub Codespaces の実態は Dockerコンテナなので、これに該当します。そりゃ失敗するわけだ!(欲を言うと、適切なエラーメッセージやドキュメントで明記してほしいですね)

  const browserCredential = new InteractiveBrowserCredential({
    redirectUri: `http://localhost:31337`,
    tokenCachePersistenceOptions,
    tenantId: details.tenantId,
  });

  const deviceCredential = new DeviceCodeCredential({
    tokenCachePersistenceOptions,
    tenantId: details.tenantId,
  });

  const environmentCredential = new EnvironmentCredential();

  // Only use interactive browser credential if we're not running in docker
  const credentials = isRunningInDocker() ? [environmentCredential, deviceCredential] : [environmentCredential, browserCredential, deviceCredential];

  if (details.tenantId && details.clientId && details.clientSecret) {
    const clientSecretCredential = new ClientSecretCredential(details.tenantId, details.clientId, details.clientSecret, {
      tokenCachePersistenceOptions,
    });
    // insert at the beginning of the array to ensure that it is tried first
    credentials.unshift(clientSecretCredential);
  }

https://github.com/Azure/static-web-apps-cli/blob/8a058192188344cec7f0acbca5964b36304e417c/src/core/account.ts#L52-L74

解決方法: 引数での指定、または Service Principal によるログイン、デバイスログインを利用する

上記のコードによると、EnvironmentCredentialDeviceCodeCredential、または、テナントID、クライアントID、クライアントシークレットが指定されてる場合は ClientSecretCredential を利用して処理するようです。すなわち、Service Principal によるログイン、またはデバイスコードによるログインを利用できるようです。

Service Principal によるログインを利用する

Azure の認証の仕組みの一つである、Service Principal によるログインが利用できます。Service Principal は、ユーザーとしてのログインと比較して、利用対象の権限の設定などができるなどのユースケースの場合も有用です。

詳細は Azure のドキュメントをご参考ください。

https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/service-accounts-principal

https://docs.microsoft.com/en-us/cli/azure/create-an-azure-service-principal-azure-cli#what-is-an-azure-service-principal

Service Principal を SWA CLI に認識させるには、オプションとして指定するか、環境変数として渡すことができます。

Service Principal をオプションで指定する

CLI のオプションで指定する場合は簡単ですね。それぞれヘルプやドキュメントをご参考ください。

https://azure.github.io/static-web-apps-cli/docs/cli/swa-login

https://azure.github.io/static-web-apps-cli/docs/cli/swa-deploy

Service Principal を環境変数で指定する

環境変数による指定については、下記環境変数に指定します。詳しくは、ドキュメントをご参考ください。

  • AZURE_CLIENT_ID
  • AZURE_CLIENT_SECRET
  • AZURE_TENANT_ID

https://azure.github.io/static-web-apps-cli/docs/cli/env-vars#azure-identity

また、上記の environmentCredential の実態は、@azure/identity なので、下記ドキュメントも参考になると思います。

https://www.npmjs.com/package/@azure/identity#environment-variables

デバイスコードによるログインを利用する

デバイスコードによるログインについては、現時点で詳細な条件を確認できていないのですが、Mac 上の VS Code から codespace に接続した状態で swa login --no-use-keychain を実行すると、デバイスログインを促されるようで、上記のエラーは起きないようです。

swa login --no-use-keychain

Welcome to Azure Static Web Apps CLI (1.0.2)

Using configuration "app" from file:
  /workspaces/github-codespaces-demo/swa-cli.config.json

Checking Azure session...
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code ABCDEFGHI to authenticate.
✔ Successfully logged into Azure!
✔ Choose your tenant › 12345678-1234-1234-1234-123456789012
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code JKLMNOPQ to authenticate.
✔ Successfully logged into Azure tenant: 12345678-1234-1234-1234-123456789012
✔ Choose your subscription › Microsoft Azure Sponsorship
✔ Saved project credentials in .env file.
✔ Successfully setup project!

補足: --no-use-keychain オプションについて

GitHub Codespaces や WSL などの CUI のみの環境では、下記のようなエラーが発生します。

swa login

Welcome to Azure Static Web Apps CLI (1.0.2)

Using configuration "app" from file:
  /workspaces/github-codespaces-demo/swa-cli.config.json

Checking Azure session...
✖ Failed to setup project: libsecret-1.so.0: cannot open shared object file: No such file or directory

✖ If you believe this behavior is unexpected, please raise a GitHub issue at:
  https://github.com/Azure/static-web-apps-cli/issues/new/choose

もしくは、下記のようなエラーログの場合。(発生環境をメモし忘れました)

Checking Azure session...
✖ Failed to setup project: Cannot autolaunch D-Bus without X11 $DISPLAY

このようなエラーが表示されたときは、--no-use-keychain オプションをつけると回避できます。

swa login --no-use-keychain

Epilogue

この記事は、「Alternative Architecture DOJO #6」のLT発表の資料も兼ねて書きました。久しぶりのオフラインイベントで、しどろもどろになったけども楽しいですね!!🤩

https://alterbooth.connpass.com/event/253077/

余談、Apex Legends は ルーキーⅣ → Ⅲ に上がりました!(ブロンズまではまだまだ…

Discussion