0
# Client Authentication
1
2
Client authentication methods for OAuth 2.0 token endpoint requests, supporting all standard authentication mechanisms including client secrets, private key JWT, and mutual TLS.
3
4
## Capabilities
5
6
### Client Secret Post
7
8
HTTP request body authentication using `client_id` and `client_secret` as form parameters.
9
10
```typescript { .api }
11
/**
12
* Client Secret Post authentication method
13
* @param clientSecret - Client secret (optional, can be provided later)
14
* @returns ClientAuth function for configuration
15
*/
16
function ClientSecretPost(clientSecret?: string): ClientAuth;
17
```
18
19
**Usage Examples:**
20
21
```typescript
22
import * as client from "openid-client";
23
24
// With discovery
25
const config = await client.discovery(
26
new URL("https://example.com"),
27
"client-id",
28
"client-secret", // uses ClientSecretPost by default
29
client.ClientSecretPost("client-secret") // explicit
30
);
31
32
// With Configuration constructor
33
const config = new client.Configuration(
34
serverMetadata,
35
"client-id",
36
"client-secret",
37
client.ClientSecretPost("client-secret")
38
);
39
```
40
41
### Client Secret Basic
42
43
HTTP Basic authentication using `client_id` and `client_secret` in Authorization header.
44
45
```typescript { .api }
46
/**
47
* Client Secret Basic authentication method
48
* @param clientSecret - Client secret (optional, can be provided later)
49
* @returns ClientAuth function for configuration
50
*/
51
function ClientSecretBasic(clientSecret?: string): ClientAuth;
52
```
53
54
**Usage Examples:**
55
56
```typescript
57
import * as client from "openid-client";
58
59
// Basic authentication
60
const config = await client.discovery(
61
new URL("https://example.com"),
62
"client-id",
63
"client-secret",
64
client.ClientSecretBasic("client-secret")
65
);
66
67
// Without providing secret upfront (uses client metadata)
68
const config = await client.discovery(
69
new URL("https://example.com"),
70
"client-id",
71
{ client_secret: "client-secret" },
72
client.ClientSecretBasic()
73
);
74
```
75
76
### Client Secret JWT
77
78
JWT assertion authentication using HMAC with client secret.
79
80
```typescript { .api }
81
/**
82
* Client Secret JWT authentication method
83
* @param clientSecret - Client secret for HMAC signing
84
* @param options - JWT modification options
85
* @returns ClientAuth function for configuration
86
*/
87
function ClientSecretJwt(
88
clientSecret?: string,
89
options?: ModifyAssertionOptions
90
): ClientAuth;
91
```
92
93
**Usage Examples:**
94
95
```typescript
96
import * as client from "openid-client";
97
98
// Basic client secret JWT
99
const config = await client.discovery(
100
new URL("https://example.com"),
101
"client-id",
102
"client-secret",
103
client.ClientSecretJwt("client-secret")
104
);
105
106
// With custom JWT claims
107
const config = await client.discovery(
108
new URL("https://example.com"),
109
"client-id",
110
"client-secret",
111
client.ClientSecretJwt("client-secret", {
112
[client.modifyAssertion]: (header, payload) => {
113
payload.custom_claim = "custom_value";
114
payload.iat = Math.floor(Date.now() / 1000) - 30; // 30 seconds ago
115
}
116
})
117
);
118
```
119
120
### Private Key JWT
121
122
JWT assertion authentication using digital signature with private key.
123
124
```typescript { .api }
125
/**
126
* Private Key JWT authentication method
127
* @param clientPrivateKey - Private key for signing JWT assertions
128
* @param options - JWT modification options
129
* @returns ClientAuth function for configuration
130
*/
131
function PrivateKeyJwt(
132
clientPrivateKey: CryptoKey | PrivateKey,
133
options?: ModifyAssertionOptions
134
): ClientAuth;
135
```
136
137
**Usage Examples:**
138
139
```typescript
140
import * as client from "openid-client";
141
142
// Generate or import private key
143
const keyPair = await crypto.subtle.generateKey(
144
{ name: "ECDSA", namedCurve: "P-256" },
145
true,
146
["sign", "verify"]
147
);
148
149
// Private Key JWT authentication
150
const config = await client.discovery(
151
new URL("https://example.com"),
152
"client-id",
153
undefined, // no client secret needed
154
client.PrivateKeyJwt(keyPair.privateKey)
155
);
156
157
// With RSA key and custom claims
158
const rsaKeyPair = await crypto.subtle.generateKey(
159
{
160
name: "RSASSA-PKCS1-v1_5",
161
modulusLength: 2048,
162
publicExponent: new Uint8Array([1, 0, 1]),
163
hash: "SHA-256"
164
},
165
true,
166
["sign", "verify"]
167
);
168
169
const config = await client.discovery(
170
new URL("https://example.com"),
171
"client-id",
172
undefined,
173
client.PrivateKeyJwt(rsaKeyPair.privateKey, {
174
[client.modifyAssertion]: (header, payload) => {
175
header.kid = "my-key-id";
176
payload.jti = crypto.randomUUID(); // unique JWT ID
177
}
178
})
179
);
180
```
181
182
### None (Public Client)
183
184
No authentication - sends only `client_id` for public clients.
185
186
```typescript { .api }
187
/**
188
* None authentication method for public clients
189
* @returns ClientAuth function for configuration
190
*/
191
function None(): ClientAuth;
192
```
193
194
**Usage Examples:**
195
196
```typescript
197
import * as client from "openid-client";
198
199
// Public client (SPA, mobile app)
200
const config = await client.discovery(
201
new URL("https://example.com"),
202
"public-client-id",
203
undefined, // no client secret
204
client.None()
205
);
206
207
// Alternatively, no auth method defaults to None() when no client_secret
208
const config = await client.discovery(
209
new URL("https://example.com"),
210
"public-client-id"
211
// defaults to None() authentication
212
);
213
```
214
215
### TLS Client Authentication
216
217
Mutual TLS authentication using client certificates.
218
219
```typescript { .api }
220
/**
221
* TLS Client Authentication method (mTLS)
222
* @returns ClientAuth function for configuration
223
*/
224
function TlsClientAuth(): ClientAuth;
225
```
226
227
**Usage Examples:**
228
229
```typescript
230
import * as client from "openid-client";
231
import * as undici from "undici";
232
233
// Create mTLS agent with client certificate
234
const agent = new undici.Agent({
235
connect: {
236
key: clientPrivateKey, // PEM-encoded private key
237
cert: clientCertificate // PEM-encoded certificate
238
}
239
});
240
241
// Configure for mTLS with endpoint aliases
242
const config = await client.discovery(
243
new URL("https://example.com"),
244
"client-id",
245
{ use_mtls_endpoint_aliases: true }, // use mTLS endpoints
246
client.TlsClientAuth()
247
);
248
249
// Set custom fetch for mTLS
250
config[client.customFetch] = (...args) =>
251
// @ts-expect-error - undici types may not match exactly
252
undici.fetch(args[0], { ...args[1], dispatcher: agent });
253
```
254
255
## Authentication Type
256
257
```typescript { .api }
258
/**
259
* Client authentication function type
260
* Modifies request parameters and headers for authentication
261
*/
262
type ClientAuth = (
263
as: ServerMetadata,
264
client: ClientMetadata,
265
body: URLSearchParams,
266
headers: Headers
267
) => void;
268
```
269
270
## JWT Modification Support
271
272
```typescript { .api }
273
/**
274
* Options for modifying JWT assertions before signing
275
*/
276
interface ModifyAssertionOptions {
277
/** Function to modify JWT header and payload */
278
[modifyAssertion]?: ModifyAssertionFunction;
279
}
280
281
/**
282
* Function to modify JWT assertions
283
* @param header - JWT header to modify
284
* @param payload - JWT payload to modify
285
*/
286
type ModifyAssertionFunction = (
287
header: Record<string, any>,
288
payload: Record<string, any>
289
) => void;
290
291
/**
292
* Symbol for assertion modification
293
*/
294
declare const modifyAssertion: unique symbol;
295
```
296
297
## Custom Fetch Integration
298
299
For mTLS and other advanced HTTP client needs:
300
301
```typescript { .api }
302
/**
303
* Custom fetch function type
304
*/
305
type CustomFetch = (
306
url: string,
307
options: CustomFetchOptions
308
) => Promise<Response>;
309
310
interface CustomFetchOptions {
311
body: FetchBody;
312
headers: Record<string, string>;
313
method: string;
314
redirect: 'manual';
315
signal?: AbortSignal;
316
}
317
318
/**
319
* Symbol for custom fetch implementation
320
*/
321
declare const customFetch: unique symbol;
322
```
323
324
**Node.js mTLS Example:**
325
326
```typescript
327
import * as client from "openid-client";
328
import * as undici from "undici";
329
330
// Setup mTLS agent
331
const agent = new undici.Agent({
332
connect: {
333
key: fs.readFileSync('client-key.pem'),
334
cert: fs.readFileSync('client-cert.pem')
335
}
336
});
337
338
const config = await client.discovery(
339
new URL("https://example.com"),
340
"client-id",
341
{ use_mtls_endpoint_aliases: true },
342
client.TlsClientAuth()
343
);
344
345
// Apply custom fetch
346
config[client.customFetch] = (...args) =>
347
undici.fetch(args[0], { ...args[1], dispatcher: agent });
348
```