npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@solidus-network/x401

v0.1.0

Published

Verifier side of x401, the HTTP Proof Requirement Protocol. Protocol only: credential validation is injected, so one verifier serves both the gated route and the token endpoint. Mirrored publicly as @solidus-network/x401.

Readme

@solidus-network/x401

Verifier side of x401, the HTTP Proof Requirement Protocol.

x402 answers "what does this agent owe". x401 answers "what does this agent have to prove". A server answers a request with a PROOF-REQUEST header describing the credential it needs, the agent satisfies it through a credential manager, and retries the same route with PROOF-RESPONSE.

Running against a live deployment: https://auth.solidus.network/v1/x401/demo. Open it in a browser and the requirement is rendered. Point an agent at it and the same requirement is in the header.

This package is protocol only. It never decides who to trust. Credential validation is injected, so the same verifier that guards your routes is the one your token endpoint uses, and the two cannot drift apart.

Status

x401 is an editor's draft at v0.2.0 and can change. This is an independent implementation and is not affiliated with its authors.

Implemented, against the specification's Verifier conformance list:

| item | what | |---|---| | 1, 12 | PROOF-REQUEST emission, and HTTP status kept independent of proof state | | 2 | openid4vp-v1-signed and openid4vp-v1-unsigned | | 3 | OAuth token endpoint advertised in the oauth member | | 5 | Result Artifact validation, delegated to your OpenID4VP verifier | | 6, 7 | Result Artifacts in PROOF-RESPONSE, inline and by reference | | 8, 9 | Verification Tokens, and caller binding when Authorization is also present | | 10 | PROOF-RESULT with an x401 Error Object | | Consumer Client Compatibility | the body-embedded <data> mirror for header-blind clients | | Agent side | satisfyProofRequest, the Digital Credentials API carrier |

Not implemented:

  • Item 4, trusted_authorities. See "A note on issuer trust" below.
  • The dc_api and dc_api.jwt response modes, and JWE response encryption. The agent-side carrier below is complete and the composed request is a valid DigitalCredentialRequestOptions, but a Verifier that wants the credential manager to return the result through the browser rather than post it back still needs those response modes. Until then the request this package composes carries whatever response mode your OpenID4VP verifier issues.
  • openid4vp-v1-multisigned. x401 v0.2.0's protocol member does not permit it, although the W3C Digital Credentials API requires user agents to support it. Raised as proof/x401#41.

Install

npm install @solidus-network/x401

fastify is an optional peer dependency, needed only for the route gate and the token endpoint.

Gate a route

import Fastify from 'fastify'
import { x401Gate, verifyCredentialResult } from '@solidus-network/x401'

const app = Fastify()

app.get(
  '/protected',
  {
    preHandler: x401Gate({
      enabled: true,
      tokenEndpoint: 'https://example.com/x401/token',
      challengeStatus: 401,
      buildRequest: async () => createOpenId4vpRequest(),
      verifier: {
        resultUriPrefix: 'https://example.com/.well-known/x401/results/',
        fetchCredentialResult: async (uri) => fetchWithSsrfGuard(uri),
      },
      verifyProof: (result) =>
        verifyCredentialResult(result, {
          submitResponse: (input) => yourOpenId4vpVerifier.submitResponse(input),
        }),
    }),
  },
  async () => ({ secret: 'only after proof' }),
)

buildRequest must mint a fresh nonce per challenge. Reusing one silently removes replay detection, and nothing else in the protocol will notice.

Satisfy a requirement (agent side)

import { satisfyProofRequest } from '@solidus-network/x401'

const challenge = await fetch(url)
const proofRequest = challenge.headers.get('proof-request')

const proofResponse = await satisfyProofRequest(proofRequest, {
  get: (credentialRequirements) => navigator.credentials.get(credentialRequirements),
  agentId: 'did:web:agent.example',
})

const retry = await fetch(url, { headers: { 'PROOF-RESPONSE': proofResponse } })

credential_requirements is passed to the credential manager verbatim. The specification requires it, and the result binds to the request the Verifier issued, so an agent that "helpfully" adjusts the request breaks the binding it depends on.

Two things worth knowing before you deploy this

The by-reference Result Artifact is a server-side request forgery surface. credential_result_uri is supplied by whoever retries the route. This package checks the URI against resultUriPrefix before any network call, so a URI you did not issue never becomes a request. The fetchCredentialResult you supply should still apply address-level protection, because that check only proves the URI looks like yours.

A failed verification is not an absent one. verifyProof is required rather than optional, because a gate that forgets to verify is worse than no gate: it looks like one. If it throws, the route does not run and the response carries an x401 error object.

A note on issuer trust

The specification says accepted issuers belong in the request's DCQL trusted_authorities. If your issuers are identified by DIDs, you cannot do this today. All three DCQL authority types assume X.509 or a federation: aki is an RFC 5280 AuthorityKeyIdentifier, etsi_tl requires an X.509 certificate in the credential's trust chain, and openid_federation requires a federation Entity Identifier.

This package therefore omits the member rather than synthesising a value. Omitting it is conformant, because expressing it is a SHOULD. Asserting an authority key that does not exist would not be, and a wallet doing real matching would fail or match wrongly.

Tracked upstream at openid/OpenID4VP#494.

Test vectors

The tests use the specification's own examples as fixtures rather than this implementation's output: Appendix A's minimal payload, both Result Artifact forms, the x401 Token Object, and the Error Object. A green test therefore means the code accepts what the specification publishes.

npm install
npm run build
npm test

License

Apache-2.0