Skip to content

sdk/linux

Rust SDK for Linux desktop using xdg-open for browser launch, loopback TCP for the authorization callback, PKCE S256, and freedesktop.org Secret Service token storage.

Status

Package status is Implemented · verified locally. cargo test passes 24 cases. Secret Service D-Bus storage and the full browser redirect flow require gnome-keyring or kwallet running on a desktop Linux system. Real IdP round-trip is pending manual verification. This page documents implemented behavior; it is not a production-readiness claim.

Requirements

  • Rust (stable, 2021 edition)
  • tokio async runtime
  • Desktop Linux with xdg-open (xdg-utils) for system browser launch and a running D-Bus session with gnome-keyring or kwallet for Secret Service storage
  • Headless / CI environments: use the in-memory-storage feature or inject InMemoryStorage directly

Installation

Add xid-linux to Cargo.toml:

[dependencies]
xid-linux = { path = "../sdk/linux" }   # local development
# published release:
# xid-linux = "0.1"
tokio = { version = "1", features = ["full"] }

Quick start

use xid_linux::{XidClient, XidConfigBuilder};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // 1. Build config
    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 -- opens xdg-open browser, loopback TCP receives callback
    let session = client.sign_in(None).await?;
    println!("user: {}", session.user.sub);

    // 4. Get access token (auto-refresh)
    let token = client.get_access_token(None).await?;

    // 5. Sign out (revokes refresh token + clears storage)
    client.sign_out().await?;
    Ok(())
}

Headless / CI usage

When no D-Bus Secret Service daemon is available, pass InMemoryStorage to avoid a runtime error:

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()))?;

Core API

Method Description
XidConfigBuilder::new() Builder for XidConfig. Required fields: issuer, client_id, redirect_uri. Optional: scopes, redirect_port (default 51234), http_timeout_secs (default 30).
XidClient::configure(config) Create client with default SecretServiceStorage.
XidClient::configure_with_storage(config, adapter) Create client with a custom StorageAdapter (e.g. InMemoryStorage).
sign_in(options) async Open xdg-open browser, start loopback TCP listener on redirect_port, wait for the authorization code callback, exchange it, store tokens, and return a Session.
get_session() async Return the stored session with automatic refresh token rotation if near expiry.
get_access_token(options) async Return a valid access token string, refreshing automatically if needed.
sign_out() async Revoke the refresh token at the /revocation endpoint and clear local storage.
set_token_storage(adapter) Replace the storage adapter after construction.

Storage adapters

Adapter Description
SecretServiceStorage Default. Stores tokens in the freedesktop.org Secret Service (gnome-keyring or kwallet) via D-Bus. Requires a running desktop session.
InMemoryStorage In-process memory only. Tokens are lost on process exit. Use for testing or CI environments without a Secret Service.

Security

  • Public client — no client secret stored or transmitted.
  • PKCE S256 only. Server rejects plain challenge method.
  • OAuth state validated on the loopback callback to prevent CSRF (RFC 8252 loopback redirect).
  • Secret Service encrypts tokens at rest via the desktop keyring daemon — the app does not manage encryption keys directly.
  • Refresh tokens are rotated on every use by the XID server; the SDK saves the new token after each refresh call.

Known limitations

  • JWKS-backed ID token verification and cache refresh are implemented and locally tested. A desktop Secret Service and real IdP round-trip are still required before L4 support.
  • The redirect port is fixed and must match the redirect_uri registered in the XID console. Dynamic port randomization (RFC 8252) requires dynamic client registration support.
  • System browser redirect and Secret Service storage require desktop environment evidence.
Navigation

Type to search...

Use arrow keys to navigateEnter to selectEscape to close