Skip to content

Repository files navigation

VeriFido .NET

NuGet

Open-source .NET libraries for HiTRUST VeriFido FIDO2 / WebAuthn: shared contracts, core flow logic, and ASP.NET Core RP (Relying Party) integration.

Disclaimer: This project is a community-maintained, unofficial implementation. It is not affiliated with or endorsed by HiTRUST. "HiTRUST" and "VeriFido" are trademarks of HiTRUST. Evaluate compliance and security requirements before use.

Choose your integration path

Pick the path that matches your app. The install command and wiring differ.

Path When to use Install HTTP surface
Standalone RP host You want /fido2/* endpoints with minimal code, or a dev RP proxy in front of VeriFido VeriFido.Rp.AspNetCore /fido2/* (built-in)
Embedded BFF You already have an ASP.NET Core BFF with its own auth routes and token issuance VeriFido.Contracts + VeriFido.Abstractions + VeriFido.Core Your own controllers (e.g. /app/auth/fido/*)
Need /fido2/* with minimal setup?
  → Standalone RP host (VeriFido.Rp.AspNetCore)

Already have a BFF and only need ceremony + gateway abstractions?
  → Embedded BFF (Contracts + Abstractions + Core)

Need shared DTOs or interfaces only?
  → VeriFido.Contracts and/or VeriFido.Abstractions

Topology overview:

Deployment Client talks to ApiBaseUrl on that host
Production BFF direct BFF HiTRUST VeriFido API
Dev: BFF → RP proxy BFF → RP host → VeriFido BFF points at RP URL; RP still points at VeriFido API
Standalone RP RP host HiTRUST VeriFido API

See docs/integration.md for endpoint tables, tunnel setup, and troubleshooting.


NuGet packages (1.1)

Package Who references it Responsibility
VeriFido.Contracts BFF, RP, tests Request/response and flow DTOs
VeriFido.Abstractions BFF, RP, tests IVeriFidoGateway, IFidoTransactionStore, IAuthSessionIssuer
VeriFido.Core BFF, RP FidoFlowService, IFidoFlowService (framework-agnostic)
VeriFido.Store.Redis Multi-instance BFF and RP hosts Redis GETDEL transaction store with server TTL and namespaced keys
VeriFido.Rp.AspNetCore Standalone RP host only DI extensions, Fido2Controller, internal HTTP client

VeriFido.Rp.AspNetCore pulls in Contracts, Abstractions, and Core automatically. BFF apps should not reference Rp.AspNetCore unless you intentionally want its controllers.

Monorepo project reference example:

<ProjectReference Include="..\..\verifido-dotnet\src\VeriFido.Core\VeriFido.Core.csproj" />

Configuration (all paths)

All settings bind under the VeriFido section. Set them in appsettings.json or environment variables (VeriFido__ApiKey, VeriFido__RpId, etc.).

Key Rule
ApiBaseUrl HiTRUST VeriFido API base URL — never the RP proxy URL on RP hosts
RpId Public RP domain / Passkey association domain
SystemId HiTRUST-provided system id
ApiKey Secret; required in Production; never expose via public /config
AllowedOrigins Explicit HTTPS browser CORS allowlist; empty denies cross-origin browser calls
RateLimitPermitLimit / RateLimitWindowSeconds Per-client-IP baseline limiter; defaults to 60 requests per 60 seconds
TransactionLifetimeSeconds / MaxPendingTransactions Server-enforced ceremony lifetime; MaxPendingTransactions bounds only the memory store
TransactionStore Explicitly select Memory (development/single instance) or Redis (shared multi-instance store)
Redis:ConnectionString Secret StackExchange.Redis configuration; required when TransactionStore is Redis
Redis:EnvironmentName / Redis:ApplicationName Required non-secret key namespace segments for deployment isolation

Full reference: docs/configuration.md.

Stateless ceremony: both rpTxId and txId from step 1 must be echoed by the client in step 2 (attestation and assertion). Missing ids cause RpTxId is required or TxId is required at runtime.


Standalone RP host

Use this when you want a dedicated RP that exposes /fido2/* with little boilerplate.

Install

dotnet add package VeriFido.Rp.AspNetCore

Wire up

builder.Services.AddVeriFidoRp(builder.Configuration);

var app = builder.Build();
app.UseVeriFidoRp();
app.UseVeriFidoRpStaticFiles(); // optional: AASA / assetlinks
app.MapVeriFidoRpEndpoints();

Public API entry points: AddVeriFidoRp, UseVeriFidoRp, MapVeriFidoRpEndpoints. For business logic, depend on IVeriFidoGateway (Abstractions), not internal HTTP types.

Production bind and remove operations fail closed through IFidoRpRequestAuthorizer. The default authorizer denies bind outside Development, so production hosts must replace it with an authenticated-account plus OTP policy. Remove always requires a matching authenticated RP session. Development permits bind for the sample UI only. RP ceremonies are single-use and expire after five minutes by default.

Transaction store for deployment

AddVeriFidoRp selects the store from VeriFido:TransactionStore. The default and sample Development override are Memory; MemoryFidoTransactionStore is only suitable for development or a single application instance. It cannot preserve single-use replay protection across Pods, rolling deployments, autoscaling, process restarts, or failover.

For those production scenarios, explicitly select the shipped shared atomic Redis store and provide its secret connection string through a secret provider:

{
  "VeriFido": {
    "TransactionStore": "Redis",
    "TransactionLifetimeSeconds": 300,
    "Redis": {
      "ConnectionString": "",
      "EnvironmentName": "production",
      "ApplicationName": "fido-rp"
    }
  }
}

Set the omitted secret at deployment time, for example with VeriFido__Redis__ConnectionString. The Redis deployment must support GETDEL (Redis 6.2 or newer), be shared by every RP instance, and be sized and operated for the pending-ceremony TTL workload. Redis errors fail closed; the package never falls back to process-local memory. See docs/configuration.md for HA, capacity, namespacing, expiry, and secret-handling requirements.

Try the sample locally

  1. Copy samples/RpHost/.env.example to .env (do not commit) and set VeriFido__ApiKey and related values, or edit samples/RpHost/appsettings.json.
  2. Run:
dotnet run --project samples/RpHost/RpHost.csproj
# or
cd samples/RpHost && just dev   # HTTP :5080
  1. Open http://localhost:5080 for the built-in test page.

Docker: docker compose -f deploy/docker/docker-compose.yml up --build (port 5080).

For real-device Passkey tests, expose the RP over HTTPS (e.g. Cloudflare Tunnel) and align mobile rpId with the public domain. See Platform checklist below.


Embedded BFF

Use this when FIDO lives inside an existing BFF: custom routes, OTP gates, and app token issuance stay in your app.

Install

dotnet add package VeriFido.Contracts
dotnet add package VeriFido.Abstractions
dotnet add package VeriFido.Core

Do not add VeriFido.Rp.AspNetCore unless you also want its /fido2 controllers in the same process.

Implement adapters

Interface Your implementation
IVeriFidoGateway HTTP to VeriFido API (or to an RP proxy in dev)
IFidoTransactionStore Session/Redis store, or noop if the client echoes rpTxId / txId
IAuthSessionIssuer Map a verified assertion to your app tokens

Register flow service

services.AddScoped<IVeriFidoGateway, YourVeriFidoGateway>();
services.AddScoped<IFidoTransactionStore, YourTransactionStore>();
services.AddScoped<IAuthSessionIssuer, YourAuthSessionIssuer>();
services.AddScoped(_ => new VeriFidoFlowSettings
{
    RpId = settings.RpId,
    SystemId = settings.SystemId,
    IsPaymentFromRp = settings.IsPaymentFromRp
});
services.AddScoped<IFidoFlowService, FidoFlowService>();

Your controllers call IFidoFlowService for bind (GetBindOptionsAsync / SubmitBindResultAsync) and login (GetLoginOptionsAsync / SubmitLoginResultAsync). Map client DTOs completely — result endpoints must forward rpTxId and txId from the client.

OTP verification, token issuance, and /app/auth/fido/* routes are your app's responsibility — implement them on top of IFidoFlowService.

Dev topology: BFF → RP proxy

Mobile App  →  BFF (ApiBaseUrl = RP URL)  →  RP Host (public rpId)
                                                  ↓
                                            VeriFido API
  • BFF ApiBaseUrl may point at the RP host during development.
  • RP host ApiBaseUrl must still point at the VeriFido API, never at itself.
  • Mobile rpId and BFF RpId must match the RP public domain.

Platform checklist

Real-device Passkey testing typically requires:


Repository layout

Path Description
src/VeriFido.Contracts API request/response and flow DTOs
src/VeriFido.Abstractions Gateway, atomic transaction store, auth session abstractions
src/VeriFido.Core Framework-agnostic flow logic
src/VeriFido.Store.Redis Reusable Redis atomic transaction store for BFF and RP deployments
src/VeriFido.Rp.AspNetCore HTTP services, session adapters, Fido2Controller, DI extensions
samples/RpHost Runnable RP sample host
tests/ Unit and integration tests
deploy/docker Docker build and compose

Build and test

dotnet build VeriFido.sln
dotnet test VeriFido.sln
dotnet pack VeriFido.sln -c Release -o artifacts

Agent Skills

This repository includes Cursor Agent Skills for AI-assisted VeriFido work:

  • verifido-integration — package selection, BFF vs RP host topology, FidoFlowService wiring, configuration, and stateless rpTxId/txId flows
  • verifido-verification-gate — security and correctness verification after implementing bind/login (token issuance gates, OTP, identity mismatch, ceremony echo, ApiKey exposure)

Documentation

License

MIT License — see LICENSE.

About

No description, website, or topics provided.

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages