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.
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.
| 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" />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.
Use this when you want a dedicated RP that exposes /fido2/* with little boilerplate.
dotnet add package VeriFido.Rp.AspNetCorebuilder.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.
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.
- Copy
samples/RpHost/.env.exampleto.env(do not commit) and setVeriFido__ApiKeyand related values, or editsamples/RpHost/appsettings.json. - Run:
dotnet run --project samples/RpHost/RpHost.csproj
# or
cd samples/RpHost && just dev # HTTP :5080- Open
http://localhost:5080for 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.
Use this when FIDO lives inside an existing BFF: custom routes, OTP gates, and app token issuance stay in your app.
dotnet add package VeriFido.Contracts
dotnet add package VeriFido.Abstractions
dotnet add package VeriFido.CoreDo not add VeriFido.Rp.AspNetCore unless you also want its /fido2 controllers in the same process.
| 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 |
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.
Mobile App → BFF (ApiBaseUrl = RP URL) → RP Host (public rpId)
↓
VeriFido API
- BFF
ApiBaseUrlmay point at the RP host during development. - RP host
ApiBaseUrlmust still point at the VeriFido API, never at itself. - Mobile
rpIdand BFFRpIdmust match the RP public domain.
Real-device Passkey testing typically requires:
- A publicly reachable HTTPS
rpIddomain (e.g. Cloudflare Tunnel) - Apple App Site Association (
/.well-known/apple-app-site-association) - Android Digital Asset Links (
/.well-known/assetlinks.json) - Mobile app asset links / Associated Domains aligned with
rpId
| 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 |
dotnet build VeriFido.sln
dotnet test VeriFido.sln
dotnet pack VeriFido.sln -c Release -o artifactsThis repository includes Cursor Agent Skills for AI-assisted VeriFido work:
- verifido-integration — package selection, BFF vs RP host topology,
FidoFlowServicewiring, configuration, and statelessrpTxId/txIdflows - verifido-verification-gate — security and correctness verification after implementing bind/login (token issuance gates, OTP, identity mismatch, ceremony echo, ApiKey exposure)
- CHANGELOG.md
- CONTRIBUTING.md
- SECURITY.md
- docs/integration.md — endpoints, tunnel setup, troubleshooting
- docs/configuration.md — settings, env vars, ApiKey header format
MIT License — see LICENSE.