コンテンツへ移動

sdk/linux

ブラウザ起動に xdg-open、認可コールバックにループバック TCP、PKCE S256、freedesktop.org Secret Service トークンストレージを使用した Linux デスクトップ向け Rust SDK。

Markdown で表示

状態

パッケージのステータスは 実装済み・ローカル検証済み です。Rust 単体テストスイートは成功しています。Secret Service D-Bus storage、xdg-open、完全な loopback callback、および実際の IdP ラウンドトリップの検証には、引き続き desktop Linux 統合環境が必要です。このページは実装済みの動作を説明するものであり、本番対応済みであるとの主張ではありません。

Registry 状態: UNPUBLISHED。この SDK はリポジトリのソース checkout からのみインストールし、外部 package registry は使用しないでください。

動作要件

  • Rust(stable、2021 エディション)
  • tokio 非同期ランタイム
  • デスクトップ Linux。システムブラウザ起動用に xdg-open(xdg-utils)、Secret Service ストレージ用に gnome-keyring または kwallet を使った D-Bus セッションが必要です
  • ヘッドレス / CI 環境:in-memory-storage フィーチャーを使用するか、InMemoryStorage を直接注入してください

インストール

Cargo.toml に xid-linux を追加します:

[dependencies]
xid-linux = { path = "../xid/sdk/linux" }
tokio = { version = "1", features = ["full"] }

クイックスタート

use xid_linux::{XidClient, XidConfigBuilder};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // 1. Build config. offline_access is rejected until DPoP is implemented.
    let config = XidConfigBuilder::new()
        .issuer("https://xid.dev")
        .client_id("your_client_id")
        .redirect_uri("http://127.0.0.1:51234/callback")
        .redirect_port(51234)
        .build()?;

    // 2. Create client (default: Secret Service storage)
    let client = XidClient::configure(config)?;

    // 3. Sign in. xdg-open launches the browser and loopback TCP receives the callback.
    let session = client.sign_in(None).await?;
    println!("user: {}", session.user.sub);

    // 4. Get the current unexpired access token. Expiry returns SessionExpired.
    let token = client.get_access_token(None).await?;

    // 5. Clear local token and guest state. No revoke request is sent.
    client.sign_out().await?;
    Ok(())
}

ヘッドレス / CI 利用

D-Bus Secret Service デーモンが利用できない場合は、ランタイムエラーを回避するために InMemoryStorage を渡してください:

use xid_linux::{XidClient, XidConfigBuilder};
use xid_linux::storage::InMemoryStorage;
use std::sync::Arc;

let config = XidConfigBuilder::new()
    .issuer("https://xid.dev")
    .client_id("your_client_id")
    .redirect_uri("http://127.0.0.1:51234/callback")
    .build()?;

let client = XidClient::configure_with_storage(config, Arc::new(InMemoryStorage::new()))?;

コア API

方式 説明
XidConfigBuilder::new() XidConfig のビルダー。必須フィールド:issuer、client_id、redirect_uri。オプション:scopes、redirect_port(デフォルト 51234)、http_timeout_secs(デフォルト 30)。
XidClient::configure(config) デフォルト SecretServiceStorage でクライアントを作成します。
XidClient::configure_with_storage(config, adapter) カスタム StorageAdapter(InMemoryStorage など)でクライアントを作成します。
sign_in(options) async xdg-open ブラウザを開き、redirect_port でループバック TCP リスナーを起動し、認可コードコールバックを待機し、交換してトークンを保存し、Session を返します。
get_session() async 保存されている現在の有効期限内のセッションを返します。有効期限が切れている場合はローカルの token state を消去し、SessionExpired を返します。
get_access_token(options) async 現在の有効期限内の access token を返します。有効期限切れまたは force_refresh の場合はローカルの token state を消去し、SessionExpired を返します。
sign_out() async ローカルの token と guest session storage を消去します。revoke request は送信されません。
set_token_storage(adapter) 構築後にストレージアダプターを置き換えます。

ストレージアダプター

アダプター 説明
SecretServiceStorage デフォルト。D-Bus 経由で freedesktop.org Secret Service(gnome-keyring または kwallet)にトークンを保存します。デスクトップセッションの起動が必要です。
InMemoryStorage プロセス内メモリのみ。プロセス終了時にトークンは失われます。Secret Service のないテストや CI 環境に使用してください。

セキュリティ

  • パブリッククライアント — クライアントシークレットは保存・送信されません。
  • PKCE S256 のみ。サーバーは plain チャレンジメソッドを拒否します。
  • CSRF を防ぐため(RFC 8252 ループバックリダイレクト)ループバックコールバックで検証される OAuth state。
  • Secret Service はデスクトップキーリングデーモン経由で保存時にトークンを暗号化します — アプリは暗号化キーを直接管理しません。
  • DPoP が実装されるまで SDK は offline_access を拒否します。予期しない refresh_token response fields は永続化されません。

既知の制限事項

  • JWKS-backed ID token verification、nonce validation、JWKS cache renewal は実装され、ローカルでテスト済みです。L4 support の前に、desktop Secret Service と実 IdP round-trip が引き続き必要です。
  • リダイレクトポートは固定されており、XID コンソールに登録された redirect_uri と一致している必要があります。動的ポートランダム化(RFC 8252)には動的クライアント登録のサポートが必要です。
  • System browser redirect と Secret Service storage には desktop environment の証拠が必要です。
ナビゲーション

入力して検索...

矢印キーで移動Enter キーで選択Escape キーで閉じる