Open-source project
line/line-fido2-server avatar
line/line-fido2-server

line-fido2-server: a certified FIDO2 server with the relying party examples attached

FIDO2(WebAuthn) server officially certified by FIDO Alliance and Relying Party examples.

586 stars112 forksJavaApache-2.0

At a glance

What is it?
The LINE FIDO2 Server is a Java implementation of a FIDO2 and WebAuthn server that the FIDO Alliance has certified, shipped with a relying party demo, a reusable core module and a Spring Boot persistence layer. It suits a team studying how a production FIDO2 server is put together, and it does not suit a team that needs a hosted authentication service.
Who is it for?
Adopt the modules from line-fido2-server if you are building a FIDO2 relying party and want a certified server implementation, a reusable domain core and a working relying party example to test against. Do not adopt it as a turnkey authentication service, since the Relying Party server is a demo and the shipped database is an embedded H2 that the documentation tells you to replace for staging or production.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 178 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A certified server, and a relying party to test against

The LINE FIDO2 Server is a FIDO2, or WebAuthn, server that is officially certified by the FIDO Alliance, and the repository also ships Relying Party examples.

That combination is the point of the project. A FIDO2 server is the part that stores credential public keys and verifies signatures, and a relying party is the application side that asks a user to register a key and later to authenticate with it. Most examples of this protocol are one of the two. This repository has both, which means you can run the two together locally and see a real registration and authentication exchange rather than reading about one.

The stack is visible in the badges. Spring Boot 2.7.12, Java 11, and storage in MySQL, H2 or Redis. The licence is Apache 2.0, and the repository is organised as a Gradle multi-project with a settings file, a build file, a gradlew wrapper, and directories for common/, fido2-core/, fido2-demo/ and rpserver/, plus docker-compose.yml, run-server.sh and run-rpserver.sh.

The release history is v2.2.0 on 2026-04-28, v2.1.0 on 2025-11-07 and v2.0.0 on 2024-11-01, so the 2.x line is the current one, and the last push was on 2026-04-28.

The FIDO standard itself is the background. FIDO is an open standard for online authentication that aims to eliminate the vulnerabilities of passwords by using public-key cryptography instead of symmetric credentials like passwords or PINs.

Registration and authentication are the same handshake twice

The mechanics are worth spelling out, because the server's responsibilities only make sense once you have them.

The user's device generates a key pair, stores the private key securely and shares the public key with the server. During both registration and authentication, the server challenges the device, and the device responds with a digital signature made with the private key. The server then verifies that signature with the stored public key. Because each attempt uses a fresh challenge, the protocol helps prevent replay attacks.

In registration, the user picks an authenticator that meets the service's acceptance policy and unlocks it with a fingerprint, a PIN or another method. The key pair is generated, the public key is sent to the service and associated with the user's account while the private key stays on the device, and the service then challenges the device, which responds with the private key to finish the registration.

Authentication is the same shape with the credentials already in place. The service challenges the user to log in with a previously registered device, the user unlocks the authenticator the same way, the device signs the challenge and sends it back, and the service verifies the signature against the stored public key before granting access.

FIDO2 is the enhancement of the FIDO standard for the web and other platforms, and it is supported by the major browsers and operating systems. The two operations above are its primary ones.

The module split tells you which part you actually need

The five modules are described in the README with their dependencies, and reading them as a dependency graph tells you where to start.

common holds the message classes that are commonly referenced by both the FIDO2 Server and the RP Server, so it sits underneath both. core contains the core domain logic of FIDO, depends on common, and carries a note that matters: if the FIDO2 server you are implementing does not interact with an RDB, this module alone should be used. base holds the classes that depend on Spring JPA, which is to say the service implementation classes, the repository interfaces and the entity classes, and it depends on core. demo is the FIDO2 server demo application, depending on base, and rp-server is the RP Server demo, depending on common.

The important consequence is that the persistence layer is optional. A relying party that keeps its credential records in something other than a relational database, or in a store that is not reached through Spring Data, can take core and common and skip base entirely, and with it the JPA entities, the repositories and the service implementations.

That is a better factoring than most protocol implementations manage, and it is the detail that makes the project interesting to read. The domain logic, which is where the WebAuthn rules live, is separated from the storage decisions, and the demo is a consumer of that separation rather than the definition of it.

Attestation types, formats and the metadata service

The feature list is where the protocol surface is visible, and it is split into three groups.

The supported attestation types are Basic, Self, Attestation CA, also called Privacy CA, None and Anonymization CA. These describe the trust relationship between the authenticator and the platform, and a relying party has to decide which of them its acceptance policy allows.

The supported attestation formats are a longer list: Packed, TPM, Android Key Attestation, Android SafetyNet, FIDO U2F, Apple Anonymous and None. The format is how the authenticator signs its own attestation statement, so a server that supports the right types but not the right formats will still reject a device.

The third item is the metadata service integration, listed as FIDO MDSv3, which is the FIDO Alliance metadata service that publishes statements about known authenticator models.

Taken together, those three lists define the compatibility surface of the server, and they are the first thing to check against the devices your users actually have. A server that supports only Packed attestation will reject a device that only offers a different format, and the error the user sees will look like a broken key rather than a policy mismatch.

Running the two processes, and the H2 you are meant to replace

There are two ways to start the demo, and both are short.

Manually, you start each process with the Gradle wrapper:

bash
# Start RP Server
cd rpserver
./gradlew bootRun

# Start FIDO2 Server
cd fido2-demo/demo
./gradlew bootRun

With Docker configured, the compose file brings both up at once, with the relying party on port 8080 and the FIDO2 demo on port 8081, each with a restart policy of always:

bash
# Start both RP Server and FIDO2 Server
docker-compose up

Once they are running, the test page is at http://localhost:8080/.

The storage story is where the demo boundary is. The FIDO2 Server uses H2 as an embedded database in a local environment, and the documentation says plainly that this should be replaced with a standalone database, such as MySQL, for staging, beta or production environments. The H2 web console is at http://localhost:8081/h2-console, which is convenient for looking at what a registration actually wrote.

There is also a specific IntelliJ note. If data.sql does not work well in an IntelliJ environment, the fix is to comment out part of the build file:

groovy
jar {
    processResources {
        exclude("**/*.sql")
    }
}

That is a small thing, but it is the kind of detail that separates a repository that has been used from one that has only been published.

The origin allowlist is where native and web clients differ

The checkOrigin method validates the origin of requests, and it handles two different kinds of origin with different rules.

The first kind is app facet origins for the LINE Android and iOS client SDKs, in the form android:... or ios:.... The second is web origins for passkeys or browser based WebAuthn, in the form https://example.com. Both are configured in the application.yml file, in the app.origins list:

yaml
app:
  origins:
    - android:aaa-bbb
    - ios:aaa-bbb
    # Optional: add one or more web origins to enforce an allowlist for web/passkey flows
    - https://example.com
    - https://staging.example.com

The values are placeholders to be replaced with the ones for your own application, and the documentation marks the two kinds as applying to different flows. Facet origins apply to native app flows using the LINE client SDKs, and web origins apply to browser and passkey flows.

The rule for web origins has a subtlety worth knowing. When web origins are listed, they are treated as an allowlist for web origin verification, and multi-origin is supported. If no web origins are configured, the server falls back to strict equality between the request-provided origin and the clientDataJSON.origin, which is the single origin behaviour that the WebAuthn specification describes.

So configuring an allowlist is strictly more permissive than not configuring one, in the sense that it allows several origins at once, and the absence of a configuration is not an oversight but a different mode. For a relying party that serves a staging and a production domain from the same code, that distinction decides whether you need two deployments or one.

Where the certified server is the wrong choice

Four limits are worth naming.

The first is that the relying party server is a demo. The repository describes it as an RP Server Demo, and the whole point of including it is to be a counterpart to the FIDO2 server so that a registration and an authentication can be exercised. A team that wants a production relying party will take the modules and the patterns, not the server.

The second is the default storage. H2 in a local environment is convenient and is explicitly not what you should run outside development.

The third is that the certificate covers the FIDO2 server, not the surrounding product. A certification tells you the protocol implementation conforms, and it says nothing about the policies, the recovery flows, the identity proofing at registration, or the operations around it. Those parts are yours, and the repository does not attempt them.

The fourth is the dependency on the LINE client SDK for native flows. The facet origin configuration exists for those SDKs, and the two client SDK repositories, webauthndemo-kotlin and webauthndemo-swift, are separate projects. A native app that is not on those SDKs can still use WebAuthn, but the configuration path documented here is written around them.

The realistic evaluation is therefore: read core and common for the protocol implementation, copy the relying party for the integration shape, and treat the certified server as the reference for how a conformance-tested FIDO2 server is put together.

Editorial conclusion

Adopt the modules from line-fido2-server if you are building a FIDO2 relying party and want a certified server implementation, a reusable domain core and a working relying party example to test against. Do not adopt it as a turnkey authentication service, since the Relying Party server is a demo and the shipped database is an embedded H2 that the documentation tells you to replace for staging or production. Verify first that your platform's origin model matches the checkOrigin configuration, since native facet origins and web origins are configured differently, and that the attestation and metadata service behaviour matches what your relying party policy expects.

Frequently asked questions

What is the LINE FIDO2 Server?

It is a FIDO2, or WebAuthn, server that is officially certified by the FIDO Alliance, shipped with Relying Party examples. The implementation is Java on Spring Boot 2.7.12 with Java 11, and storage can be MySQL, H2 or Redis.

How does the FIDO2 challenge-response protocol work?

The device generates a key pair and keeps the private key, the server stores the public key, and the server then sends a fresh challenge to the device during both registration and authentication. The device signs the challenge with the private key and the server verifies the signature with the stored public key, which is what prevents replay attacks.

Which modules does the line-fido2-server repository contain?

common holds the message classes shared by both servers, core holds the core domain logic of FIDO and is enough on its own if your server does not interact with an RDB, base holds the Spring JPA service implementations, repositories and entities, demo is the FIDO2 server demo application and rp-server is the Relying Party demo.

How do I run the line-fido2-server demo?

Start the Relying Party with cd rpserver and ./gradlew bootRun, and the FIDO2 server with cd fido2-demo/demo and ./gradlew bootRun, or run docker-compose up to start both. The test page is at http://localhost:8080/ and the H2 console is at http://localhost:8081/h2-console.

How are allowed origins configured in line-fido2-server?

In the app.origins list in application.yml. Facet origins such as android: and ios: cover native flows using the LINE client SDKs, while web origins listed as https:// or http:// act as an allowlist for browser and passkey flows. If no web origins are configured, the server falls back to strict equality between the request origin and clientDataJSON.origin.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. line/line-fido2-server on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/line-line-fido2-server.svg)](https://hysenlabs.com/projects/line-line-fido2-server)

Was this useful?