OAuth 2.0 and OpenID Connect client library for JavaScript runtimes with comprehensive authentication flows and security features.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Client authentication methods for OAuth 2.0 token endpoint requests, supporting all standard authentication mechanisms including client secrets, private key JWT, and mutual TLS.
HTTP request body authentication using client_id and client_secret as form parameters.
/**
* Client Secret Post authentication method
* @param clientSecret - Client secret (optional, can be provided later)
* @returns ClientAuth function for configuration
*/
function ClientSecretPost(clientSecret?: string): ClientAuth;Usage Examples:
import * as client from "openid-client";
// With discovery
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
"client-secret", // uses ClientSecretPost by default
client.ClientSecretPost("client-secret") // explicit
);
// With Configuration constructor
const config = new client.Configuration(
serverMetadata,
"client-id",
"client-secret",
client.ClientSecretPost("client-secret")
);HTTP Basic authentication using client_id and client_secret in Authorization header.
/**
* Client Secret Basic authentication method
* @param clientSecret - Client secret (optional, can be provided later)
* @returns ClientAuth function for configuration
*/
function ClientSecretBasic(clientSecret?: string): ClientAuth;Usage Examples:
import * as client from "openid-client";
// Basic authentication
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
"client-secret",
client.ClientSecretBasic("client-secret")
);
// Without providing secret upfront (uses client metadata)
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
{ client_secret: "client-secret" },
client.ClientSecretBasic()
);JWT assertion authentication using HMAC with client secret.
/**
* Client Secret JWT authentication method
* @param clientSecret - Client secret for HMAC signing
* @param options - JWT modification options
* @returns ClientAuth function for configuration
*/
function ClientSecretJwt(
clientSecret?: string,
options?: ModifyAssertionOptions
): ClientAuth;Usage Examples:
import * as client from "openid-client";
// Basic client secret JWT
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
"client-secret",
client.ClientSecretJwt("client-secret")
);
// With custom JWT claims
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
"client-secret",
client.ClientSecretJwt("client-secret", {
[client.modifyAssertion]: (header, payload) => {
payload.custom_claim = "custom_value";
payload.iat = Math.floor(Date.now() / 1000) - 30; // 30 seconds ago
}
})
);JWT assertion authentication using digital signature with private key.
/**
* Private Key JWT authentication method
* @param clientPrivateKey - Private key for signing JWT assertions
* @param options - JWT modification options
* @returns ClientAuth function for configuration
*/
function PrivateKeyJwt(
clientPrivateKey: CryptoKey | PrivateKey,
options?: ModifyAssertionOptions
): ClientAuth;Usage Examples:
import * as client from "openid-client";
// Generate or import private key
const keyPair = await crypto.subtle.generateKey(
{ name: "ECDSA", namedCurve: "P-256" },
true,
["sign", "verify"]
);
// Private Key JWT authentication
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
undefined, // no client secret needed
client.PrivateKeyJwt(keyPair.privateKey)
);
// With RSA key and custom claims
const rsaKeyPair = await crypto.subtle.generateKey(
{
name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048,
publicExponent: new Uint8Array([1, 0, 1]),
hash: "SHA-256"
},
true,
["sign", "verify"]
);
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
undefined,
client.PrivateKeyJwt(rsaKeyPair.privateKey, {
[client.modifyAssertion]: (header, payload) => {
header.kid = "my-key-id";
payload.jti = crypto.randomUUID(); // unique JWT ID
}
})
);No authentication - sends only client_id for public clients.
/**
* None authentication method for public clients
* @returns ClientAuth function for configuration
*/
function None(): ClientAuth;Usage Examples:
import * as client from "openid-client";
// Public client (SPA, mobile app)
const config = await client.discovery(
new URL("https://example.com"),
"public-client-id",
undefined, // no client secret
client.None()
);
// Alternatively, no auth method defaults to None() when no client_secret
const config = await client.discovery(
new URL("https://example.com"),
"public-client-id"
// defaults to None() authentication
);Mutual TLS authentication using client certificates.
/**
* TLS Client Authentication method (mTLS)
* @returns ClientAuth function for configuration
*/
function TlsClientAuth(): ClientAuth;Usage Examples:
import * as client from "openid-client";
import * as undici from "undici";
// Create mTLS agent with client certificate
const agent = new undici.Agent({
connect: {
key: clientPrivateKey, // PEM-encoded private key
cert: clientCertificate // PEM-encoded certificate
}
});
// Configure for mTLS with endpoint aliases
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
{ use_mtls_endpoint_aliases: true }, // use mTLS endpoints
client.TlsClientAuth()
);
// Set custom fetch for mTLS
config[client.customFetch] = (...args) =>
// @ts-expect-error - undici types may not match exactly
undici.fetch(args[0], { ...args[1], dispatcher: agent });/**
* Client authentication function type
* Modifies request parameters and headers for authentication
*/
type ClientAuth = (
as: ServerMetadata,
client: ClientMetadata,
body: URLSearchParams,
headers: Headers
) => void;/**
* Options for modifying JWT assertions before signing
*/
interface ModifyAssertionOptions {
/** Function to modify JWT header and payload */
[modifyAssertion]?: ModifyAssertionFunction;
}
/**
* Function to modify JWT assertions
* @param header - JWT header to modify
* @param payload - JWT payload to modify
*/
type ModifyAssertionFunction = (
header: Record<string, any>,
payload: Record<string, any>
) => void;
/**
* Symbol for assertion modification
*/
declare const modifyAssertion: unique symbol;For mTLS and other advanced HTTP client needs:
/**
* Custom fetch function type
*/
type CustomFetch = (
url: string,
options: CustomFetchOptions
) => Promise<Response>;
interface CustomFetchOptions {
body: FetchBody;
headers: Record<string, string>;
method: string;
redirect: 'manual';
signal?: AbortSignal;
}
/**
* Symbol for custom fetch implementation
*/
declare const customFetch: unique symbol;Node.js mTLS Example:
import * as client from "openid-client";
import * as undici from "undici";
// Setup mTLS agent
const agent = new undici.Agent({
connect: {
key: fs.readFileSync('client-key.pem'),
cert: fs.readFileSync('client-cert.pem')
}
});
const config = await client.discovery(
new URL("https://example.com"),
"client-id",
{ use_mtls_endpoint_aliases: true },
client.TlsClientAuth()
);
// Apply custom fetch
config[client.customFetch] = (...args) =>
undici.fetch(args[0], { ...args[1], dispatcher: agent });Install with Tessl CLI
npx tessl i tessl/npm-openid-client