or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-security.mdauthorization-flows.mdclient-authentication.mdconfiguration.mdgrant-types.mdindex.mdpassport-integration.mdprotected-resources.mdtoken-management.md

client-authentication.mddocs/

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

```