Authentication Flow: Rust Library

This guide provides detailed instructions for using the Authentication Flow on a server with our Rust library.

Table of content

This library is still in it’s early stages; Below is an excerpt from our documents API to showcase implementation.

1.0 Installation

Add the lbrary to your Cargo.toml file:

[dependencies]
ones-oidc = "0.2.1"

This package is also available on PantherX (or guix, with PantherX channel) as rust-ones-oidc.

Important: You need to register your device with IDP first. You don’t need to have px-device-identity-service running.

2.0 Device Authentication

use ones_oidc_rust::{OpenIdconnectClient, load_device_config};

let device_config = load_device_config(&device_config_path).expect("Failed to load device config");

let client_id = ClientId::new(device_config.client_id.clone().to_string());
let issuer_url = IssuerUrl::new(device_config.issuer_url.to_string())
    .map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Failed to parse issuer URL"))?;

let provider_metadata = CoreProviderMetadata::discover_async(
    issuer_url.clone(),
    async_http_client,
)
.await
.map_err(|_| std::io::Error::new(std::io::ErrorKind::Other, "Failed to discover OIDC metadata"))?;

let openid_client = OpenIdconnectClient {
    client_id: client_id,
    issuer_url: issuer_url,
    issuer_jwks: None,
    provider_metadata: provider_metadata.clone(),
    // read_private_key: you can supply your own implementation here
    private_key: read_private_key(&device_config.private_key_path).unwrap(),
};

2.1 Get Device Access Token

// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };

let device_access_token = openid_client.request_device_access_token().await;

3.0 CIBA

Authenticate with user username (OnesID).

3.1 Make CIBA Request

// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };

let login_hint = LoginHint {
    kind: payload.login_hint_kind,
    value: payload.user_identifier.clone(),
};
let result = openid_client.make_ciba_request(
    &login_hint,
    "openid offline_access profile".to_string(),
    "Authorize login to Example.com?".to_string(),
    Some("https://example.com".to_string())
).await;

if result.is_err() {
    let e = result.err().unwrap();
    debug!("Error: {}", e);
    return Ok(HttpResponse::InternalServerError().finish());
}

let result = result.unwrap();
Ok(HttpResponse::Ok().json(result))

3.2 Check CIBA Status

// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };

let ciba_status = openid_client.check_ciba_status(&auth_request_id).await;
if ciba_status.is_err() {
    let ciba_status = ciba_status.unwrap_err();
    if ciba_status.to_string() == "Authorization pending" {
        println!("Authorization pending");
        Ok(HttpResponse::BadRequest().json(ciba_status.to_string()))
    } else {
        println!("Error: {:?}", ciba_status);
        Ok(HttpResponse::InternalServerError().json(ciba_status.to_string()))
    }
} else {
    let ciba_status = ciba_status.unwrap();
    println!("CIBA Status: {:?}", ciba_status);
    Ok(HttpResponse::Ok().json(ciba_status))
}

Validate token:

// Reuse the `openid_client` from the previous example
let openid_client = OpenIdconnectClient { ... };

openid_client.validate_token(&id_token).await;

4.0 QR

WIP

WIP

Contact

Found a problem, or have a question related to Authentication Flow: Rust Library?

ONES Now Documentation

© 2025 ONES Now Documentation | Author Franz Geffke