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

@oidfed/oidc

v0.4.0

Published

OpenID Connect and OAuth 2.0 federation flows — automatic and explicit client registration, Request Object validation, and RP/OP metadata processing as defined in OpenID Federation 1.0.

Readme

@oidfed/oidc

OpenID Connect and OAuth 2.0 federation flows — automatic and explicit client registration, Request Object validation, and RP/OP metadata processing as defined in OpenID Federation 1.0.

Status: prerelease — API may change before the upcoming stable 1.0.0 release.

Install

npm install @oidfed/core @oidfed/oidc

Quick Start

RP — Automatic Registration

import { automaticRegistration } from "@oidfed/oidc";
import { discoverEntity } from "@oidfed/leaf";

const opDiscovery = await discoverEntity(opEntityId, trustAnchors);

const result = await automaticRegistration(
  opDiscovery,
  rpConfig, // defaults to form_post delivery
  { scope: "openid profile", state: "xyz" },
  trustAnchors,
);

switch (result.delivery) {
  case "form_post":
    // Render an HTML form posting result.formParams to result.authorizationEndpoint
    break;
  case "query":
  case "request_uri":
  case "par":
    // 302 the user-agent to result.authorizationUrl
    break;
}

OP — Processing Registration

import { processAutomaticRegistration } from "@oidfed/oidc";

const result = await processAutomaticRegistration(requestObjectJwt, trustAnchors, {
  opEntityId: entityId("https://op.example.com"),
  jtiStore,
});
// Result<ProcessedRegistration, FederationError> — never throws

Request Object delivery modes

The Authorization Request can carry the signed Request Object in four ways. Select one via rpConfig.requestDelivery. The default is "form_post" — the safest choice when the Request Object embeds a trust_chain header (the JWT often exceeds 8 KB, hitting URL and header-length ceilings in HTTP intermediaries).

form_post (default)

Posts the Request Object as an application/x-www-form-urlencoded body. The RP renders an auto-submit HTML form whose action is the OP authorization endpoint.

const result = await automaticRegistration(
  opDiscovery,
  { ...rpConfig, requestDelivery: "form_post" },
  authzParams,
  trustAnchors,
);
if (result.delivery === "form_post") {
  // Serve an HTML form to the user-agent:
  //   <form method="post" action={result.authorizationEndpoint}>
  //     <input type="hidden" name="request" value={result.formParams.request}>
  //     <input type="hidden" name="client_id" value={result.formParams.client_id}>
  //   </form>
}

query

Places the Request Object value in a ?request= query parameter of a GET to the OP authorization endpoint. Compact but constrained by URL/header length limits when the Request Object carries an embedded trust_chain.

const result = await automaticRegistration(
  opDiscovery,
  { ...rpConfig, requestDelivery: "query" },
  authzParams,
  trustAnchors,
);
if (result.delivery === "query") {
  // 302 the user-agent to result.authorizationUrl (contains ?request=&client_id=)
}

request_uri (by reference)

The RP hosts the signed Request Object at a publicly-reachable URL it provides. The OP fetches that URL when it receives ?request_uri=<URL>&client_id=<RP>. The library does NOT host the JWT — the caller must serve result.requestObjectJwt at the supplied requestUri with Content-Type: application/oauth-authz-req+jwt, typically with a short TTL and single-use semantics.

const result = await automaticRegistration(
  opDiscovery,
  {
    ...rpConfig,
    requestDelivery: "request_uri",
    requestUri: "https://rp.example.com/request-object/abc123",
  },
  authzParams,
  trustAnchors,
);
if (result.delivery === "request_uri") {
  // 1. Cache result.requestObjectJwt under the URL path you provided
  // 2. 302 the user-agent to result.authorizationUrl
}

par (Pushed Authorization Request)

The library POSTs the Request Object directly to the OP's pushed_authorization_request_endpoint (advertised in the OP openid_provider metadata), receives a short-lived urn:ietf:params:oauth:request_uri:<id>, and returns an authorization URL embedding that urn. The PAR request includes a private_key_jwt client_assertion whose audience is the OP's Entity Identifier.

const result = await automaticRegistration(
  opDiscovery,
  { ...rpConfig, requestDelivery: "par" },
  authzParams,
  trustAnchors,
);
if (result.delivery === "par") {
  // 302 the user-agent to result.authorizationUrl (contains ?request_uri=urn:...)
  // result.parExpiresAt tells you when the urn becomes unusable
}

Migration from 0.3.x

The 0.4.0 release introduces a breaking change to automaticRegistration's return type and default behavior:

  • AutomaticRegistrationResult is now a discriminated union on result.delivery. Code that reads result.authorizationUrl must first narrow on the delivery mode, OR opt back into the historical shape by passing requestDelivery: "query":

    // 0.3.x ergonomics, preserved in 0.4.0 with one extra config field:
    const result = await automaticRegistration(
      opDiscovery,
      { ...rpConfig, requestDelivery: "query" },
      authzParams,
      trustAnchors,
    );
    if (result.delivery === "query") {
      redirectTo(result.authorizationUrl);
    }
  • The default delivery mode is "form_post". Existing callers that did not specify a delivery mode previously received GET-query URLs; in 0.4.0 they now receive form-post result shapes (result.authorizationEndpoint + result.formParams) and must render an HTML form instead of issuing a 302.

What's Included

  • RP-side automatic registration (Request Object + trust chain embedding)
  • RP-side explicit registration (Entity Configuration POST)
  • OP-side processing for both registration types (returns Result, never throws)
  • Typed OP/RP metadata schemas (extends core's loose z.record())
  • Request Object validation
  • Client assertion creation (private_key_jwt)
  • OIDCRegistrationAdapter for plugging into @oidfed/authority

Documentation

Full API reference: docs/packages/oidc.md

Part of @oidfed

| Package | Role | |---------|------| | @oidfed/core | Federation primitives | | @oidfed/authority | Trust Anchor & Intermediate operations | | @oidfed/leaf | Leaf Entity toolkit | | @oidfed/oidc | OIDC/OAuth 2.0 federation flows (this package) | | @oidfed/cli | CLI for federation debugging |

License

Apache-2.0 — see NOTICE for attribution.