@openid4vc/oauth2 0.5.2-alpha-20260701132441 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -9,6 +9,7 @@ declare const zAuthorizationServerMetadata: z.ZodObject<{
9
9
  client_secret_basic: "client_secret_basic";
10
10
  client_secret_post: "client_secret_post";
11
11
  attest_jwt_client_auth: "attest_jwt_client_auth";
12
+ attest_jwt_client_auth_dpop: "attest_jwt_client_auth_dpop";
12
13
  client_secret_jwt: "client_secret_jwt";
13
14
  private_key_jwt: "private_key_jwt";
14
15
  }>, z.ZodString]>>>;
@@ -24,6 +25,7 @@ declare const zAuthorizationServerMetadata: z.ZodObject<{
24
25
  client_secret_basic: "client_secret_basic";
25
26
  client_secret_post: "client_secret_post";
26
27
  attest_jwt_client_auth: "attest_jwt_client_auth";
28
+ attest_jwt_client_auth_dpop: "attest_jwt_client_auth_dpop";
27
29
  client_secret_jwt: "client_secret_jwt";
28
30
  private_key_jwt: "private_key_jwt";
29
31
  }>, z.ZodString]>>>;
@@ -32,6 +34,9 @@ declare const zAuthorizationServerMetadata: z.ZodObject<{
32
34
  interactive_authorization_endpoint: z.ZodOptional<z.ZodURL>;
33
35
  require_interactive_authorization_request: z.ZodOptional<z.ZodBoolean>;
34
36
  'pre-authorized_grant_anonymous_access_supported': z.ZodOptional<z.ZodBoolean>;
37
+ client_attestation_signing_alg_values_supported: z.ZodOptional<z.ZodArray<z.ZodString>>;
38
+ client_attestation_pop_signing_alg_values_supported: z.ZodOptional<z.ZodArray<z.ZodString>>;
39
+ challenge_endpoint: z.ZodOptional<z.ZodURL>;
35
40
  client_attestation_pop_nonce_required: z.ZodOptional<z.ZodBoolean>;
36
41
  authorization_response_iss_parameter_supported: z.ZodOptional<z.ZodBoolean>;
37
42
  }, z.core.$loose>;
@@ -42,6 +47,7 @@ declare enum SupportedClientAuthenticationMethod {
42
47
  ClientSecretBasic = "client_secret_basic",
43
48
  ClientSecretPost = "client_secret_post",
44
49
  ClientAttestationJwt = "attest_jwt_client_auth",
50
+ ClientAttestationJwtDpop = "attest_jwt_client_auth_dpop",
45
51
  None = "none"
46
52
  }
47
53
  interface ClientAuthenticationDynamicOptions {
@@ -119,6 +125,11 @@ declare function clientAuthenticationAnonymous(): ClientAuthenticationCallback;
119
125
  interface ClientAuthenticationClientAttestationJwtOptions {
120
126
  clientAttestationJwt: string;
121
127
  callbacks: Pick<CallbackContext, 'signJwt' | 'generateRandom'>;
128
+ /**
129
+ * Challenge provided by the authorization server (e.g. obtained from its `challenge_endpoint`)
130
+ * to include in the Client Attestation PoP JWT.
131
+ */
132
+ challenge?: string;
122
133
  }
123
134
  /**
124
135
  * Client authentication using `attest_jwt_client_auth` option.
@@ -667,7 +678,6 @@ declare enum SupportedAuthenticationScheme {
667
678
  //#endregion
668
679
  //#region src/client-attestation/z-client-attestation.d.ts
669
680
  declare const zClientAttestationJwtPayload: z.ZodObject<{
670
- iss: z.ZodString;
671
681
  sub: z.ZodString;
672
682
  exp: z.ZodNumber;
673
683
  cnf: z.ZodObject<{
@@ -703,6 +713,7 @@ declare const zClientAttestationJwtPayload: z.ZodObject<{
703
713
  }, z.core.$loose>;
704
714
  wallet_name: z.ZodOptional<z.ZodString>;
705
715
  wallet_link: z.ZodOptional<z.ZodURL>;
716
+ iss: z.ZodOptional<z.ZodString>;
706
717
  aud: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>>;
707
718
  iat: z.ZodOptional<z.ZodNumber>;
708
719
  nbf: z.ZodOptional<z.ZodNumber>;
@@ -750,10 +761,11 @@ declare const zClientAttestationJwtHeader: z.ZodObject<{
750
761
  }, z.core.$loose>;
751
762
  type ClientAttestationJwtHeader = z.infer<typeof zClientAttestationJwtHeader>;
752
763
  declare const zClientAttestationPopJwtPayload: z.ZodObject<{
753
- iss: z.ZodString;
754
764
  aud: z.ZodUnion<readonly [z.ZodURL, z.ZodArray<z.ZodURL>]>;
755
765
  jti: z.ZodString;
766
+ challenge: z.ZodOptional<z.ZodString>;
756
767
  nonce: z.ZodOptional<z.ZodString>;
768
+ iss: z.ZodOptional<z.ZodString>;
757
769
  iat: z.ZodOptional<z.ZodNumber>;
758
770
  exp: z.ZodOptional<z.ZodNumber>;
759
771
  nbf: z.ZodOptional<z.ZodNumber>;
@@ -897,7 +909,6 @@ declare function verifyClientAttestationJwt(options: VerifyClientAttestationJwtO
897
909
  };
898
910
  payload: {
899
911
  [x: string]: unknown;
900
- iss: string;
901
912
  sub: string;
902
913
  exp: number;
903
914
  cnf: {
@@ -936,6 +947,7 @@ declare function verifyClientAttestationJwt(options: VerifyClientAttestationJwtO
936
947
  };
937
948
  wallet_name?: string | undefined;
938
949
  wallet_link?: string | undefined;
950
+ iss?: string | undefined;
939
951
  aud?: string | string[] | undefined;
940
952
  iat?: number | undefined;
941
953
  nbf?: number | undefined;
@@ -956,9 +968,13 @@ interface CreateClientAttestationJwtOptions {
956
968
  */
957
969
  expiresAt: Date;
958
970
  /**
959
- * Issuer of the client attestation, usually identifier of the client backend
971
+ * Issuer of the client attestation, usually the identifier of the client backend (attester).
972
+ *
973
+ * The `iss` claim was removed from the Client Attestation JWT in draft 08, so it is only
974
+ * included in the payload when this option is provided. It is also useful for interoperability
975
+ * with <= draft 07 verifiers and when the KID is a relative DID URL to the issuer.
960
976
  */
961
- issuer: string;
977
+ issuer?: string;
962
978
  /**
963
979
  * The client id of the client instance.
964
980
  */
@@ -1003,15 +1019,13 @@ interface VerifyClientAttestationOptions {
1003
1019
  //#region src/client-attestation/client-attestation-pop.d.ts
1004
1020
  interface RequestClientAttestationOptions {
1005
1021
  /**
1006
- * Dpop nonce to use for constructing the client attestation pop jwt
1022
+ * The challenge provided by the authorization server to include in the client attestation pop jwt.
1007
1023
  */
1008
- nonce?: string;
1024
+ challenge?: string;
1009
1025
  /**
1010
- * Expiration time of the client attestation pop jwt.
1011
- *
1012
- * @default 5 minutes after issuance date
1026
+ * @deprecated Renamed to `challenge` in draft 06. If `challenge` is not set, this value is used.
1013
1027
  */
1014
- expiresAt?: Date;
1028
+ nonce?: string;
1015
1029
  /**
1016
1030
  * The client attestation jwt to create the pop for.
1017
1031
  */
@@ -1029,11 +1043,26 @@ interface VerifyClientAttestationPopJwtOptions {
1029
1043
  */
1030
1044
  clientAttestationPopJwt: string;
1031
1045
  /**
1032
- * The issuer identifier of the authorization server handling the client attestation
1046
+ * The issuer identifier of the authorization server handling the client attestation.
1033
1047
  */
1034
1048
  authorizationServer: string;
1035
1049
  /**
1036
- * Expected nonce in the payload. If not provided the nonce won't be validated.
1050
+ * The expected value of the `aud` claim. Defaults to `authorizationServer`.
1051
+ *
1052
+ * draft 09 allows the audience to be a Resource Server identifier URL in addition to the
1053
+ * authorization server issuer URL; set this when verifying a PoP JWT at a resource server.
1054
+ */
1055
+ expectedAudience?: string;
1056
+ /**
1057
+ * Expected challenge in the payload. If not provided the challenge won't be validated.
1058
+ *
1059
+ * Matched against the `challenge` claim (draft 06+) and, for backwards compatibility,
1060
+ * the legacy `nonce` claim.
1061
+ */
1062
+ expectedChallenge?: string;
1063
+ /**
1064
+ * @deprecated Renamed to `expectedChallenge` in draft 06. If `expectedChallenge` is not set,
1065
+ * this value is used.
1037
1066
  */
1038
1067
  expectedNonce?: string;
1039
1068
  /**
@@ -1102,10 +1131,11 @@ declare function verifyClientAttestationPopJwt(options: VerifyClientAttestationP
1102
1131
  };
1103
1132
  payload: {
1104
1133
  [x: string]: unknown;
1105
- iss: string;
1106
1134
  aud: string | string[];
1107
1135
  jti: string;
1136
+ challenge?: string | undefined;
1108
1137
  nonce?: string | undefined;
1138
+ iss?: string | undefined;
1109
1139
  iat?: number | undefined;
1110
1140
  exp?: number | undefined;
1111
1141
  nbf?: number | undefined;
@@ -2773,6 +2803,9 @@ declare function getAuthorizationServerMetadataFromList(authorizationServersMeta
2773
2803
  interactive_authorization_endpoint?: string | undefined;
2774
2804
  require_interactive_authorization_request?: boolean | undefined;
2775
2805
  'pre-authorized_grant_anonymous_access_supported'?: boolean | undefined;
2806
+ client_attestation_signing_alg_values_supported?: string[] | undefined;
2807
+ client_attestation_pop_signing_alg_values_supported?: string[] | undefined;
2808
+ challenge_endpoint?: string | undefined;
2776
2809
  client_attestation_pop_nonce_required?: boolean | undefined;
2777
2810
  authorization_response_iss_parameter_supported?: boolean | undefined;
2778
2811
  };
@@ -2981,6 +3014,9 @@ declare class Oauth2AuthorizationServer {
2981
3014
  interactive_authorization_endpoint?: string | undefined;
2982
3015
  require_interactive_authorization_request?: boolean | undefined;
2983
3016
  'pre-authorized_grant_anonymous_access_supported'?: boolean | undefined;
3017
+ client_attestation_signing_alg_values_supported?: string[] | undefined;
3018
+ client_attestation_pop_signing_alg_values_supported?: string[] | undefined;
3019
+ challenge_endpoint?: string | undefined;
2984
3020
  client_attestation_pop_nonce_required?: boolean | undefined;
2985
3021
  authorization_response_iss_parameter_supported?: boolean | undefined;
2986
3022
  };
@@ -3220,7 +3256,6 @@ declare class Oauth2AuthorizationServer {
3220
3256
  };
3221
3257
  payload: {
3222
3258
  [x: string]: unknown;
3223
- iss: string;
3224
3259
  sub: string;
3225
3260
  exp: number;
3226
3261
  cnf: {
@@ -3259,6 +3294,7 @@ declare class Oauth2AuthorizationServer {
3259
3294
  };
3260
3295
  wallet_name?: string | undefined;
3261
3296
  wallet_link?: string | undefined;
3297
+ iss?: string | undefined;
3262
3298
  aud?: string | string[] | undefined;
3263
3299
  iat?: number | undefined;
3264
3300
  nbf?: number | undefined;
@@ -3311,10 +3347,11 @@ declare class Oauth2AuthorizationServer {
3311
3347
  };
3312
3348
  payload: {
3313
3349
  [x: string]: unknown;
3314
- iss: string;
3315
3350
  aud: string | string[];
3316
3351
  jti: string;
3352
+ challenge?: string | undefined;
3317
3353
  nonce?: string | undefined;
3354
+ iss?: string | undefined;
3318
3355
  iat?: number | undefined;
3319
3356
  exp?: number | undefined;
3320
3357
  nbf?: number | undefined;
@@ -3507,6 +3544,9 @@ declare class Oauth2Client {
3507
3544
  interactive_authorization_endpoint?: string | undefined;
3508
3545
  require_interactive_authorization_request?: boolean | undefined;
3509
3546
  'pre-authorized_grant_anonymous_access_supported'?: boolean | undefined;
3547
+ client_attestation_signing_alg_values_supported?: string[] | undefined;
3548
+ client_attestation_pop_signing_alg_values_supported?: string[] | undefined;
3549
+ challenge_endpoint?: string | undefined;
3510
3550
  client_attestation_pop_nonce_required?: boolean | undefined;
3511
3551
  authorization_response_iss_parameter_supported?: boolean | undefined;
3512
3552
  } | null>;
package/dist/index.mjs CHANGED
@@ -1021,7 +1021,6 @@ var Oauth2ServerErrorResponseError = class extends Oauth2Error {
1021
1021
  const oauthClientAttestationHeader = z.literal("OAuth-Client-Attestation").value;
1022
1022
  const zClientAttestationJwtPayload = z.object({
1023
1023
  ...zJwtPayload.shape,
1024
- iss: z.string(),
1025
1024
  sub: z.string(),
1026
1025
  exp: zNumericDate,
1027
1026
  cnf: z.object({ jwk: zJwk }).loose(),
@@ -1033,11 +1032,12 @@ const zClientAttestationJwtHeader = z.object({
1033
1032
  typ: z.literal("oauth-client-attestation+jwt")
1034
1033
  }).loose();
1035
1034
  const oauthClientAttestationPopHeader = z.literal("OAuth-Client-Attestation-PoP").value;
1035
+ z.literal("OAuth-Client-Attestation-Challenge").value;
1036
1036
  const zClientAttestationPopJwtPayload = z.object({
1037
1037
  ...zJwtPayload.shape,
1038
- iss: z.string(),
1039
1038
  aud: z.union([zHttpsUrl, z.array(zHttpsUrl)]),
1040
1039
  jti: z.string(),
1040
+ challenge: z.optional(z.string()),
1041
1041
  nonce: z.optional(z.string())
1042
1042
  }).loose();
1043
1043
  const zClientAttestationPopJwtHeader = z.object({
@@ -1052,7 +1052,9 @@ async function verifyClientAttestationPopJwt(options) {
1052
1052
  headerSchema: zClientAttestationPopJwtHeader,
1053
1053
  payloadSchema: zClientAttestationPopJwtPayload
1054
1054
  });
1055
- if (payload.iss !== options.clientAttestation.payload.sub) throw new Oauth2Error(`Client Attestation Pop jwt contains 'iss' (client_id) value '${payload.iss}', but expected 'sub' value from client attestation '${options.clientAttestation.payload.sub}'`);
1055
+ if (payload.iss !== void 0 && payload.iss !== options.clientAttestation.payload.sub) throw new Oauth2Error(`Client Attestation Pop jwt contains 'iss' (client_id) value '${payload.iss}', but expected 'sub' value from client attestation '${options.clientAttestation.payload.sub}'`);
1056
+ const expectedChallenge = options.expectedChallenge ?? options.expectedNonce;
1057
+ if (expectedChallenge !== void 0 && expectedChallenge !== (payload.challenge ?? payload.nonce)) throw new Oauth2Error("Client Attestation Pop jwt 'challenge' does not match expected value.");
1056
1058
  const { signer } = await verifyJwt({
1057
1059
  signer: {
1058
1060
  alg: header.alg,
@@ -1061,9 +1063,8 @@ async function verifyClientAttestationPopJwt(options) {
1061
1063
  },
1062
1064
  now: options.now,
1063
1065
  header,
1064
- expectedNonce: options.expectedNonce,
1065
1066
  payload,
1066
- expectedAudience: options.authorizationServer,
1067
+ expectedAudience: options.expectedAudience ?? options.authorizationServer,
1067
1068
  compact: options.clientAttestationPopJwt,
1068
1069
  verifyJwtCallback: options.callbacks.verifyJwt,
1069
1070
  errorMessage: "client attestation pop jwt verification failed",
@@ -1090,14 +1091,11 @@ async function createClientAttestationPopJwt(options) {
1090
1091
  typ: "oauth-client-attestation-pop+jwt",
1091
1092
  alg: signer.alg
1092
1093
  });
1093
- const expiresAt = options.expiresAt ?? addSecondsToDate(options.issuedAt ?? /* @__PURE__ */ new Date(), 60);
1094
1094
  const payload = parseWithErrorHandling(zClientAttestationPopJwtPayload, {
1095
1095
  aud: options.authorizationServer,
1096
- iss: clientAttestation.payload.sub,
1097
- iat: dateToSeconds(options.issuedAt),
1098
- exp: dateToSeconds(expiresAt),
1096
+ iat: dateToSeconds(options.issuedAt ?? /* @__PURE__ */ new Date()),
1099
1097
  jti: encodeToBase64Url(await options.callbacks.generateRandom(32)),
1100
- nonce: options.nonce,
1098
+ challenge: options.challenge ?? options.nonce,
1101
1099
  ...options.additionalPayload
1102
1100
  });
1103
1101
  const { jwt } = await options.callbacks.signJwt(signer, {
@@ -1138,7 +1136,7 @@ async function createClientAttestationJwt(options) {
1138
1136
  ...jwtHeaderFromJwtSigner(options.signer)
1139
1137
  });
1140
1138
  const payload = parseWithErrorHandling(zClientAttestationJwtPayload, {
1141
- iss: options.issuer,
1139
+ ...options.issuer ? { iss: options.issuer } : {},
1142
1140
  iat: dateToSeconds(options.issuedAt),
1143
1141
  exp: dateToSeconds(options.expiresAt),
1144
1142
  sub: options.clientId,
@@ -1706,6 +1704,7 @@ let SupportedClientAuthenticationMethod = /* @__PURE__ */ function(SupportedClie
1706
1704
  SupportedClientAuthenticationMethod["ClientSecretBasic"] = "client_secret_basic";
1707
1705
  SupportedClientAuthenticationMethod["ClientSecretPost"] = "client_secret_post";
1708
1706
  SupportedClientAuthenticationMethod["ClientAttestationJwt"] = "attest_jwt_client_auth";
1707
+ SupportedClientAuthenticationMethod["ClientAttestationJwtDpop"] = "attest_jwt_client_auth_dpop";
1709
1708
  SupportedClientAuthenticationMethod["None"] = "none";
1710
1709
  return SupportedClientAuthenticationMethod;
1711
1710
  }({});
@@ -1785,7 +1784,8 @@ function clientAuthenticationClientAttestationJwt(options) {
1785
1784
  const clientAttestationPop = await createClientAttestationPopJwt({
1786
1785
  authorizationServer: authorizationServerMetadata.issuer,
1787
1786
  callbacks: options.callbacks,
1788
- clientAttestation: options.clientAttestationJwt
1787
+ clientAttestation: options.clientAttestationJwt,
1788
+ challenge: options.challenge
1789
1789
  });
1790
1790
  headers.set(oauthClientAttestationHeader, options.clientAttestationJwt);
1791
1791
  headers.set(oauthClientAttestationPopHeader, clientAttestationPop);
@@ -2169,6 +2169,7 @@ const knownClientAuthenticationMethod = z.enum([
2169
2169
  "client_secret_basic",
2170
2170
  "client_secret_post",
2171
2171
  "attest_jwt_client_auth",
2172
+ "attest_jwt_client_auth_dpop",
2172
2173
  "client_secret_jwt",
2173
2174
  "private_key_jwt"
2174
2175
  ]);
@@ -2190,6 +2191,9 @@ const zAuthorizationServerMetadata = z.object({
2190
2191
  interactive_authorization_endpoint: z.optional(zHttpsUrl),
2191
2192
  require_interactive_authorization_request: z.optional(z.boolean()),
2192
2193
  "pre-authorized_grant_anonymous_access_supported": z.optional(z.boolean()),
2194
+ client_attestation_signing_alg_values_supported: z.optional(z.array(zAlgValueNotNone)),
2195
+ client_attestation_pop_signing_alg_values_supported: z.optional(z.array(zAlgValueNotNone)),
2196
+ challenge_endpoint: z.optional(zHttpsUrl),
2193
2197
  client_attestation_pop_nonce_required: z.boolean().optional(),
2194
2198
  authorization_response_iss_parameter_supported: z.boolean().optional()
2195
2199
  }).loose().refine(({ introspection_endpoint_auth_methods_supported: methodsSupported, introspection_endpoint_auth_signing_alg_values_supported: algValuesSupported }) => {