CodeRabbitはAIコードレビューサービスです。GitHubやGitLab、BitBucketなどと連携し、PRを作成すると自動でコードレビューを開始します。パブリックなリポジトリは、CodeRabbitを無料で利用できます。
その他、VS Code機能拡張やCLIも提供しています。CLIの認証フローでは、これまでWebサイトで認証後にトークンを発行し、それをターミナルにコピペしていたのですが、0.4.0からはデバイス上のアプリ操作という機能を採用しています。
Local Network Access (LNA)についてあまり情報がなかったので、PoCを作って実装を確かめてみました。
ネーミングについて
Chromeでは、127.0.0.1へのアクセスをデバイス上のアプリ、192.168.0.xなどのLAN内のアクセスをLocal Network Access (LNA)と分けているようです。ただ、技術仕様上はおそらくLocal Network Access (LNA)のようなので、今回はLocal Network Access (LNA)としています。
違っていたら指摘お願いします!
CodeRabbit CLIでのフローについて
CodeRabbit CLIをインストールします。
curl -fsSL https://cli.coderabbit.ai/install.sh | sh
# または
curl -fsSL https://cli.coderabbit.ai/install.sh | bash
以下のコマンドを実行します。
coderabbit auth login
そうすると、ブラウザが自動的に開いて、認証画面が表示されます。
CodeRabbit CLI Authentication
Opening your browser to complete CodeRabbit sign-in...
If the browser does not open or the login does not finish automatically, use this fallback URL:
https://app.coderabbit.ai/login?client=cli&state=206...1bc&redirect_uri=http%3A%2F%2F127.0.0.1%3A62030%2Fcallback
認証したあとに、以下のようなダイアログが出ます。これがLocal Network Access (LNA)です。
ここで許可を押すと、自動的にトークンがCLIに送信されて、認証完了となります。
✓ Sign-in callback received
✓ Account loaded
Authentication successful. Welcome goofmint
Local Network Access (LNA)について
Local Network Access (LNA)は簡単に言えば、ChromeからローカルのHTTPプロトコルを呼び出せる仕組みです。Chrome 142から利用できる機能です。
ローカル ネットワークへのアクセスに関する新しい権限プロンプト | Blog | Chrome for Developers
なお、Can I useに該当するAPIが見つからないので、おそらくChrome/Chromiumブラウザ限定の機能になると思います。WICGにはドラフトが上がっているので、そのうち仕様として検討されるかも知れません。
権限はChromeの設定の、プライバシーとセキュリティで設定できます。ローカルネットワークはLAN向け、デバイス上のアプリはlocalhost向けの設定です。
要件
利用する際には幾つかの要件があります。
- ローカル側
- CORS対応
-
Access-Control-Allow-Private-Network: trueというヘッダー
- リモート側
- HTTPS
ローカル側の実装
ローカル側では、OPTIONSリクエストに対して204を返すのと、 Access-Control-Allow-Origin と Access-Control-Allow-Methods ヘッダーへの対応が必要です。
const http = require('http');
const HOST = '127.0.0.1';
const PORT = 8769;
const server = http.createServer((req, res) => {
const origin = req.headers.origin || '*';
// CORS対応
res.setHeader('Access-Control-Allow-Origin', origin);
res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Allow-Private-Network', 'true');
if (req.method === 'OPTIONS') {
res.writeHead(204);
res.end();
return;
}
// それ以外のリクエストに対するレスポンス
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'ok', message: 'Hello from local app' }));
});
server.listen(PORT, HOST, () => {
console.log(`http://${HOST}:${PORT} で起動中`);
});
リモート側の実装
リモート側は、fetchなりでローカルを呼び出すだけです。
<body>
<h1>LNA Test</h1>
<button onclick="send()">Send</button>
<pre id="out"></pre>
<script>
async function send() {
const out = document.getElementById('out');
out.textContent = '送信中...\n';
try {
// ローカルへのリクエスト
const res = await fetch('http://127.0.0.1:8769/api/challenge');
// レスポンス
out.textContent += `${res.status} ${res.statusText}\n`;
out.textContent += await res.text();
} catch (e) {
out.textContent += 'Error: ' + e.message;
}
}
</script>
</body>
そうすると、ボタンを押したタイミングで権限が求められて、許可するとローカルHTTPサーバーへリクエストが実行され、結果が表示されます。
CodeRabbit CLIの場合も同様に、一時的にWebサーバーを立ち上げて、 https://app.coderabbit.ai からトークンを送信してもらう形になります。
懸念点
気になった懸念点です。
- 信頼できるサイトだけ許可しましょう
CodeRabbit CLIではhttps://app.coderabbit.aiに対してLocal Network Access (LNA)の権限がつきます。信頼できるサイト以外では許可しないのが基本です - 許可があらゆるアプリ、サービスに適用される気が…
localhost:3000 と localhost:5000 などは区別されない(ように見える)ので、ローカル探索ができそう?
ただし、実行する際にはCORSの対応が必要です。そのため、Local Network Access (LNA)を利用するアプリ側では、正しいCORS制限であったり、立ち上げる時間をごく短くする、ポート番号をランダムにする、機能を単機能に絞って不正な利用をされないようにする(ローカルファイルを読み書きしないなど)といった工夫が必要そうです。
まとめ
今回はCodeRabbit CLIで新しく実装されたLocal Network Access (LNA)について調べてみました。Chromeとローカルアプリが連携できるのは便利です。HTTP + CORSを使うことで、セキュリティ面も考慮した実装が可能だと思います。
使いどころは色々ありそうなので、ぜひ試してみてください。CodeRabbit CLIのダウングレードは以下より!(無料で利用できます)


![FireShot Capture 061 - LNA Test - [2521-150-246-255-62.ngrok-free.app].jpg](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F197026%2Feac2ed72-9b33-4237-99fa-d5a2b58a775f.jpeg?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=49e7af21a2b15f8dfa58898585eb630d)