๐Ÿ” TRusTY: Building a Rust OIDC Server with FAPI 2.0

After exploring Rust for web development, I wanted to go further by tackling an ambitious technical challenge: building a complete OpenID Connect (OIDC) provider, compliant with the FAPI 2.0 security specifications. Not just an academic prototype - a real authentication server with the most demanding security standards from the financial sector.

๐ŸŽฏ Why Build an OIDC Server in Rust?

The origin: a team challenge

It all started with a challenge launched within my former DevOps team, responsible for the SSO of a major French bank. Between two sprints, we asked ourselves: “What if we built our own OIDC server from scratch in Rust?” A stimulating technical challenge combining technological exploration, infrastructure cost optimization, and complete stack mastery.

Field observations

In the Access Management world, we typically use established solutions: Keycloak, Auth0, Okta, or ForgeRock. These tools are mature, battle-tested in production, and cover a wide spectrum of use cases. However, after several years operating them in production, a few friction points emerged:

โ€ข Configuration complexity: Hundreds of parameters, rich but sometimes heavy interfaces - the learning curve can be significant
โ€ข Resource consumption: Some Java-based solutions can require 500 MB to 1 GB RAM per instance - a non-negligible cost in cloud environments multiplied by instances
โ€ข Flow opacity: Understanding what’s happening under the hood during an authentication failure can require debug time
โ€ข Extensibility: Customization via plugins/SPIs is powerful but requires mastering internal APIs
โ€ข Vendor lock-in: Portability between solutions can prove complex depending on features used

The idea behind TRusTY? Take back control by building a modern, performant, and understandable OIDC server. A tool where every line of code is mastered, where flows are transparent. Rust provides exactly what’s needed: memory safety, native performance, and a mature web ecosystem with Axum.

๐Ÿš€ Architecture: DDD + Clean Architecture

Layered separation

Rather than piling code into monolithic controllers, I structured the project following Domain-Driven Design and Clean Architecture principles:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           Presentation Layer (HTTP)              โ”‚
โ”‚  Handlers: /auth, /token, /userinfo, /par...    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚        Application Layer (Use Cases)             โ”‚
โ”‚  Services: TokenService, AuthCodeService...      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚        Domain Layer (Business Logic)             โ”‚
โ”‚  Entities: User, Client, AuthorizationCode       โ”‚
โ”‚  Value Objects: Claims, Scope, JwtRequest        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                  โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      Infrastructure Layer (Technical)            โ”‚
โ”‚  Repositories (SQLite), JWT, DPoP, PAR...        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Why this organization? โœ… Isolated tests: Business logic testable without starting the server
โœ… Maintainability: Clear responsibilities, loose coupling
โœ… Scalability: Easy to add PostgreSQL, Redis, or other backends
โœ… Understanding: Architecture reflects OIDC business concepts

Domain entities

The system’s core relies on well-defined business entities:

  • User: Represents a user with their credentials (password hashed via bcrypt) and claims
  • Client: Registered client application (redirect_uris, JWKS, auth methods…)
  • Session: User session with configurable lifetime
  • AuthorizationCode: Ephemeral code (90s TTL) for Authorization Code Flow exchange
  • AuthorizationSession: Authorization request context (state, nonce, PKCE…)

Each entity encapsulates its own business logic and validation rules. For example, AuthorizationCode automatically verifies:

  • Expiration (90 seconds)
  • Single use (no reuse)
  • Binding to the correct client
  • PKCE code_verifier validation

๐Ÿ”’ FAPI 2.0: Financial-grade Security

Why FAPI 2.0?

FAPI (Financial-grade API) is a security profile developed by the OpenID Foundation to meet banking and financial sector requirements. FAPI 2.0 (released in 2023) goes even further with robust anti-theft and anti-replay mechanisms.

๐Ÿ“– Full specification: FAPI 2.0 Security Profile

Key implemented features:

FeatureRFC/SpecPurpose
PKCE (S256)RFC 7636Prevent authorization code interception
PARRFC 9126Protect authorization parameters (server-side pre-registration)
private_key_jwtRFC 7523Asymmetric client authentication (no shared secrets)
DPoPRFC 9449Token binding to cryptographic key (anti-token theft)
RP-Initiated LogoutOIDC LogoutClient-initiated logout
Token RevocationRFC 7009Explicit token revocation
Token IntrospectionRFC 7662Token validation by Resource Servers

DPoP in detail: the real innovation

The classic problem: Bearer access tokens are like cash - whoever has them can use them. If an attacker intercepts the token (man-in-the-middle, malware, XSS…), they can use it freely until expiration.

The DPoP solution (Demonstrating Proof-of-Possession):

  1. The client generates an ephemeral RSA key pair at session start
  2. With each token request, it signs a cryptographic proof (JWT) with its private key
  3. The server binds the access token to the public key fingerprint (cnf.jkt in token)
  4. To use the token, the client must prove possession of the private key with each API call

Result: Even if an attacker steals the token, they can’t use it without the corresponding private key. The token becomes unusable out of context.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Simplified DPoP validation (server-side)
pub async fn validate_dpop_proof(
    proof_jwt: &str,
    access_token: &str,
    http_method: &str,
    http_uri: &str,
) -> Result<Jwk, DpopError> {
    // 1. Parse and validate proof JWT signature
    let proof = decode_dpop_proof(proof_jwt)?;
    
    // 2. Verify htm (HTTP method) and htu (URI)
    if proof.htm != http_method || proof.htu != http_uri {
        return Err(DpopError::InvalidProof);
    }
    
    // 3. Verify token jkt matches proof public key
    let token_jkt = extract_jkt_from_token(access_token)?;
    let proof_jkt = calculate_jkt(&proof.jwk)?;
    
    if token_jkt != proof_jkt {
        return Err(DpopError::KeyMismatch);
    }
    
    Ok(proof.jwk)
}

PAR: Pushed Authorization Requests

Another important innovation: PAR (RFC 9126) allows pre-registering authorization parameters server-side before redirecting the user.

Classic flow (risky):

1
GET /auth?client_id=app&redirect_uri=https://evil.com&scope=admin&...

๐Ÿ‘‰ Parameters visible in URL, modifiable by attacker

PAR flow (secure):

1
2
3
4
1. POST /par (with all parameters + client signature)
   โ† 201 Created { request_uri: "urn:ietf:params:oauth:request_uri:abc123" }

2. GET /auth?client_id=app&request_uri=urn:ietf:params:oauth:request_uri:abc123

๐Ÿ‘‰ Parameters protected server-side, short and secure URL

Advantages:

  • Guaranteed parameter integrity
  • No URL length limit
  • Automatic expiration (90 seconds)

๐Ÿ› ๏ธ Tech stack and implementation choices

Why Axum for the server?

After testing several Rust web frameworks (Actix-web, Rocket, Warp), I chose Axum for several reasons:

โœ… Ergonomics: Elegant API with typed extractors, expressive routing
โœ… Performance: Built on Tokio and Tower, production-optimized
โœ… Ecosystem: Compatible with entire Tower ecosystem (middleware, rate limiting…)
โœ… Type-safety: Compilation guarantees route and handler consistency
โœ… Maintenance: Developed by Tokio team, long-term support assured

SQLite: pragmatic choice

For the MVP, I opted for SQLite over PostgreSQL/MySQL:

โœ… Zero-configuration: No server to manage, embedded database
โœ… Portable: Single file, easy to backup and migrate
โœ… Sufficient performance: Up to 100k req/s reads, more than enough to start
โœ… Dev ease: Fast tests, no Docker required

PostgreSQL migration planned: The Repository Pattern architecture allows easy switching to PostgreSQL for production (high availability, replication…).

Key dependencies

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
[dependencies]
# Web framework
axum = "0.8"
tokio = { version = "1.0", features = ["full"] }
tower = "0.4"

# Database
sqlx = { version = "0.8", features = ["sqlite", "runtime-tokio"] }

# JWT and Crypto
jsonwebtoken = "9.0"
rsa = "0.9"
bcrypt = "0.15"

# Serialization
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

# Templates and i18n
handlebars = "4.0"
fluent-templates = "0.11"

# Observability
tracing = "0.1"
opentelemetry = "0.24"

๐Ÿ“Š Implemented flows: full demonstration

1. Standard OIDC Flow (Authorization Code + PKCE)

The classic flow for a web application:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Client  โ”‚              โ”‚  TRusTY  โ”‚              โ”‚  User   โ”‚
โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
     โ”‚                         โ”‚                        โ”‚
     โ”‚  1. Redirect /auth      โ”‚                        โ”‚
     โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚                        โ”‚
     โ”‚  (client_id, PKCE...)   โ”‚                        โ”‚
     โ”‚                         โ”‚   2. Login page        โ”‚
     โ”‚                         โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
     โ”‚                         โ”‚                        โ”‚
     โ”‚                         โ”‚   3. POST /login       โ”‚
     โ”‚                         โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚
     โ”‚                         โ”‚   (username, password) โ”‚
     โ”‚                         โ”‚                        โ”‚
     โ”‚  4. Callback with code  โ”‚                        โ”‚
     โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                        โ”‚
     โ”‚                         โ”‚                        โ”‚
     โ”‚  5. POST /token         โ”‚                        โ”‚
     โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚                        โ”‚
     โ”‚  (code, code_verifier)  โ”‚                        โ”‚
     โ”‚                         โ”‚                        โ”‚
     โ”‚  6. access + id tokens  โ”‚                        โ”‚
     โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                        โ”‚

2. FAPI 2.0 Flow with PAR + DPoP

The secure flow for critical applications:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              
โ”‚ Client  โ”‚              โ”‚  TRusTY  โ”‚              
โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜              โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜              
     โ”‚                         โ”‚                   
     โ”‚  1. POST /par           โ”‚                   
     โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚                   
     โ”‚  (client_assertion,     โ”‚                   
     โ”‚   PKCE, scope...)       โ”‚                   
     โ”‚                         โ”‚                   
     โ”‚  2. request_uri         โ”‚                   
     โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                   
     โ”‚                         โ”‚                   
     โ”‚  3. Redirect /auth      โ”‚                   
     โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚                   
     โ”‚  (request_uri only)     โ”‚                   
     โ”‚                         โ”‚                   
     โ”‚  ... (login flow) ...   โ”‚                   
     โ”‚                         โ”‚                   
     โ”‚  4. POST /token         โ”‚                   
     โ”‚โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€>โ”‚                   
     โ”‚  Header: DPoP <proof>   โ”‚                   
     โ”‚  Body: client_assertion,โ”‚                   
     โ”‚        code_verifier... โ”‚                   
     โ”‚                         โ”‚                   
     โ”‚  5. DPoP-bound tokens   โ”‚                   
     โ”‚<โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚                   
     โ”‚  (token_type: DPoP)     โ”‚                   

Note: Each API call with the token requires a new signed DPoP proof. Impossible to reuse an old proof (anti-replay protection via jti + temporal verification).

๐Ÿ’ก Demo client: testing in real conditions

To validate the implementation, I developed a single Python Flask client offering two authentication modes selectable from the home page:

Standard OIDC Mode

  • Classic Authorization Code Flow
  • PKCE S256
  • client_secret_post authentication
  • Flask session for state management
  • Test account: standard user

Secure FAPI 2.0 Mode

  • Complete PAR flow
  • private_key_jwt authentication with RSA keys
  • DPoP proof generation on each request
  • Ephemeral DPoP keys per session
  • Test account: FAPI user

๐ŸŽฏ Interactive demo available: I deployed the server and client on Railway - a great service offering native GitHub integration that allowed me to host the MVP for free for 1 month with their base plan. Perfect for getting started quickly without complex infrastructure!

Available environments:

  • ๐Ÿงช DEV Demo: Development version with detailed logs
  • ๐Ÿš€ PROD Demo: Stable production version

How to test: Go to the home page, choose your mode (Standard or FAPI 2.0), and follow the complete flow. You’ll see generated tokens, DPoP proofs (in FAPI mode), and can inspect JWT claims.

๐Ÿ“š Comprehensive technical documentation

The project includes detailed documentation. While waiting for the GitHub repository opening for v1.0 (H1 2026), technical documentation is hosted directly on this blog:

Architecture & Stack

๐Ÿ“„ Technical Documentation

  • Complete DDD structure (Domain, Application, Infrastructure, Presentation)
  • Technology stack with justifications
  • SQLite database schemas
  • Docker configuration and deployment

OIDC & FAPI 2.0 Flows

๐Ÿ“„ OIDC Flow Documentation

  • Mermaid diagrams of all flows
  • Request/response examples
  • DPoP and PAR validation details
  • Error handling and edge cases

Standards compliance

SpecificationStatusCompliance level
OpenID Connect Core 1.0โœ… ImplementedComplete Authorization Code Flow
OAuth 2.0 PKCE (RFC 7636)โœ… ImplementedS256 only (plain rejected)
PAR (RFC 9126)โœ… Implemented90s TTL, in-memory storage
private_key_jwt (RFC 7523)โœ… ImplementedRS256, JWKS validation
DPoP (RFC 9449)โœ… Implementedjkt binding, htm/htu/ath validation
FAPI 2.0 Security Profileโœ… ImplementedMVP subset (no Hybrid Flow)
RP-Initiated Logoutโœ… ImplementedWith user confirmation
Token Revocation (RFC 7009)โœ… ImplementedAccess + Refresh tokens
Token Introspection (RFC 7662)โœ… ImplementedValidation for Resource Servers

๐Ÿ”ฎ Roadmap: Next steps

Version 0.9.0 (Q1 2026)

  • ๐Ÿ”„ Refresh Token Flow: Token renewal without re-authentication
  • ๐Ÿ”‘ Full SAML Support: Complete SAML 2.0 protocol implementation (IdP and SP)
  • ๐Ÿ” PostgreSQL Backend: Migration for high availability
  • ๐Ÿงช Conformance Testing: OpenID Certification test suite
  • ๐Ÿ“Š Advanced Telemetry: Prometheus metrics, distributed tracing

Version 1.0.0 (Q2-Q3 2026) - Ideas under consideration

Priority 1 - Certification and tooling:

  • โœ… OpenID Certification: Official compliance
  • ๐ŸŽ›๏ธ Admin Console: Management interface for OIDC provider settings and IdP/SP SAML configuration

Priority 2 - Authentication journeys:

  • ๐Ÿšถ Authentication Journeys: First baseline implementation with standard modules (to be determined - MFA, conditional access, step-up auth…)

To explore based on priorities:

  • ๐Ÿ”‘ WebAuthn/FIDO2: Passwordless authentication
  • ๐Ÿ“ฑ CIBA (Client Initiated Backchannel Authentication): For mobile

โš ๏ธ Note: These features are ideas under consideration and not yet fully committed. Development happens with my available resources and time (I have a day job! ๐Ÿ˜…), so the roadmap may evolve based on feedback and priorities.

Exploratory features

  • Internal/External client distinction: Differentiated management based on client type (not to be confused with Device Flow)
  • JAR (JWT Secured Authorization Request - RFC 9101): Encapsulation of authorization parameters in a signed JWT (alternative/complement to PAR)
  • mTLS (Mutual TLS): Mutual authentication at TLS level for highly secure clients
  • Rich Authorization Requests (RAR - RFC 9396): Allows requesting fine-grained and structured authorizations beyond simple scopes. Example: instead of scope=read, request {"type":"account","actions":["read","transfer"],"limits":{"max_amount":1000}}. Very useful for banking APIs where authorizations are complex.

๐Ÿค Need feedback from Access Management experts

If you work in the Identity & Access Management field, your feedback would be valuable:

๐Ÿ” Particular attention points:

  • FAPI 2.0 flow compliance: Are the DPoP implementations (proof generation/validation, jkt binding) and PAR (storage, TTL, client_assertion validation) compliant with specs? Are there uncovered edge cases?
  • Error handling and edge cases: Are OAuth/OIDC error codes appropriate? How do you handle timing attacks, replays, expired codes in your implementations?
  • Token generation/storage security: JWTs are RS256-signed with key rotation. Is authorization code and refresh token storage in SQLite secure enough for an MVP? What are your production practices?
  • Performance and scalability: With SQLite and in-memory PAR storage, the system is limited to a single node. What are recommended patterns for migrating to distributed PostgreSQL + Redis without full refactoring?
  • Interoperability: Have you tested integration with third-party Resource Servers (Spring Boot, .NET, Node.js)? What problems do you typically encounter with ID tokens and DPoP access tokens?

๐Ÿ’ฌ How to submit your feedback:

For now, the project isn’t publicly open yet (planned for v1.0 in H1 2026). Meanwhile, you can send me your feedback, questions, or recommendations by email:

๐Ÿ“ง Email: lostyzen@gmail.com
๐Ÿ” PGP Key: Download from keys.openpgp.org
๐Ÿ“Œ Fingerprint: 0205 9854 864D EE62 C2BB 455F D825 3521 EDD1 630B

Feel free to:

  • Test the demos (DEV/PROD) and report bugs/inconsistencies
  • Challenge the technical documentation
  • Propose specific business use cases from your sector
  • Report deviations from OpenID/FAPI specifications

Official specifications

TRusTY Project

๐ŸŽ‰ Conclusion

Building an OIDC server from scratch in Rust is a serious technical challenge. But TRusTY is above all the result of nearly 10 years of experience in Access Management, gained particularly in the banking sector where security and compliance requirements are especially high. This expertise, I now make available to my clients to support them with their authentication and authorization challenges.

TRusTY isn’t production-ready yet (it’s an MVP!), but it already demonstrates that it’s possible to build a performant, understandable OIDC server compliant with the most demanding standards, based on deep knowledge of real-world challenges.

What you can do right now:

  • Test the demos (DEV/PROD) to see flows in action
  • Browse the detailed technical documentation hosted on this blog
  • Share your feedback and use cases by email

What’s next? Continue implementing missing features, harden security, improve performance… and why not aim for official OpenID certification for v1.0!

Questions? Suggestions? Don’t hesitate to contact me or comment below. Community exchanges are essential for evolving this kind of project.