authhero 6.0.0 → 7.1.0

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.
Files changed (33) hide show
  1. package/dist/assets/u/widget/index.esm.js +1 -1
  2. package/dist/authhero.cjs +105 -105
  3. package/dist/authhero.d.ts +120 -84
  4. package/dist/authhero.mjs +12763 -10099
  5. package/dist/stats.html +1 -1
  6. package/dist/tsconfig.types.tsbuildinfo +1 -1
  7. package/dist/types/authentication-flows/passwordless.d.ts +3 -3
  8. package/dist/types/helpers/dcr/metadata-mapping.d.ts +2 -2
  9. package/dist/types/index.d.ts +60 -77
  10. package/dist/types/routes/auth-api/index.d.ts +27 -27
  11. package/dist/types/routes/auth-api/passwordless.d.ts +8 -8
  12. package/dist/types/routes/auth-api/register/index.d.ts +2 -2
  13. package/dist/types/routes/auth-api/revoke.d.ts +6 -6
  14. package/dist/types/routes/auth-api/token.d.ts +10 -10
  15. package/dist/types/routes/auth-api/well-known.d.ts +1 -1
  16. package/dist/types/routes/management-api/action-executions.d.ts +1 -1
  17. package/dist/types/routes/management-api/actions.d.ts +1 -1
  18. package/dist/types/routes/management-api/authentication-methods.d.ts +1 -1
  19. package/dist/types/routes/management-api/clients.d.ts +7 -7
  20. package/dist/types/routes/management-api/custom-domains.d.ts +7 -25
  21. package/dist/types/routes/management-api/failed-events.d.ts +1 -1
  22. package/dist/types/routes/management-api/guardian.d.ts +5 -5
  23. package/dist/types/routes/management-api/index.d.ts +32 -50
  24. package/dist/types/routes/management-api/logs.d.ts +3 -3
  25. package/dist/types/routes/management-api/prompts.d.ts +4 -4
  26. package/dist/types/routes/management-api/users.d.ts +2 -2
  27. package/dist/types/routes/proxy-control-plane/index.d.ts +16 -7
  28. package/dist/types/routes/proxy-control-plane/verify.d.ts +44 -0
  29. package/dist/types/routes/universal-login/common.d.ts +2 -2
  30. package/dist/types/routes/universal-login/flow-api.d.ts +4 -4
  31. package/dist/types/types/AuthHeroConfig.d.ts +15 -5
  32. package/dist/types/utils/jwks.d.ts +2 -2
  33. package/package.json +5 -5
@@ -737,7 +737,7 @@ export declare const userRoutes: OpenAPIHono<{
737
737
  };
738
738
  };
739
739
  output: {
740
- type: "fc" | "fd" | "fn" | "i" | "sapi" | "acls_summary" | "actions_execution_failed" | "api_limit" | "api_limit_warning" | "appi" | "ciba_exchange_failed" | "ciba_exchange_succeeded" | "ciba_start_failed" | "ciba_start_succeeded" | "cls" | "cs" | "depnote" | "f" | "fce" | "fco" | "fcoa" | "fcp" | "fcph" | "fcpn" | "fcpr" | "fcpro" | "fcu" | "fdeac" | "fdeaz" | "fdecc" | "fdu" | "feacft" | "feccft" | "fecte" | "fede" | "federated_logout_failed" | "fens" | "feoobft" | "feotpft" | "fepft" | "fepotpft" | "fercft" | "ferrt" | "fertft" | "festft" | "fh" | "fimp" | "fi" | "flo" | "flows_execution_completed" | "flows_execution_failed" | "forms_submission_failed" | "forms_submission_succeeded" | "fp" | "fpar" | "fpurh" | "fs" | "fsa" | "fu" | "fui" | "fv" | "fvr" | "gd_auth_email_verification" | "gd_auth_fail_email_verification" | "gd_auth_failed" | "gd_auth_rejected" | "gd_auth_succeed" | "gd_enrollment_complete" | "gd_otp_rate_limit_exceed" | "gd_recovery_failed" | "gd_recovery_rate_limit_exceed" | "gd_recovery_succeed" | "gd_send_email" | "gd_send_email_verification" | "gd_send_email_verification_failure" | "gd_send_pn" | "gd_send_pn_failure" | "gd_send_sms" | "gd_send_sms_failure" | "gd_send_voice" | "gd_send_voice_failure" | "gd_start_auth" | "gd_start_enroll" | "gd_start_enroll_failed" | "gd_tenant_update" | "gd_unenroll" | "gd_update_device_account" | "gd_webauthn_challenge_failed" | "gd_webauthn_enrollment_failed" | "kms_key_management_failure" | "kms_key_management_success" | "kms_key_state_changed" | "limit_delegation" | "limit_mu" | "limit_sul" | "limit_wc" | "mfar" | "mgmt_api_read" | "my_account_authentication_method_failed" | "my_account_authentication_method_succeeded" | "oidc_backchannel_logout_failed" | "oidc_backchannel_logout_succeeded" | "organization_member_added" | "passkey_challenge_failed" | "passkey_challenge_started" | "pla" | "pwd_leak" | "reset_pwd_leak" | "resource_cleanup" | "rich_consents_access_error" | "s" | "fapi" | "sce" | "scoa" | "scp" | "scpn" | "scpr" | "scu" | "scv" | "sd" | "sdu" | "seacft" | "seccft" | "secte" | "sede" | "sens" | "seoobft" | "seotpft" | "sepotpft" | "sepft" | "sepkoobft" | "sepkotpft" | "sepkrcft" | "sercft" | "sertft" | "sestft" | "simp" | "si" | "signup_pwd_leak" | "slo" | "sh" | "spm" | "srrt" | "ss" | "ss_sso_failure" | "ss_sso_info" | "ss_sso_success" | "ssa" | "sscim" | "sui" | "sv" | "svr" | "too_many_records" | "ublkdu" | "universal_logout_failed" | "universal_logout_succeeded" | "w" | "wn" | "wum";
740
+ type: "fn" | "i" | "sapi" | "acls_summary" | "actions_execution_failed" | "api_limit" | "api_limit_warning" | "appi" | "ciba_exchange_failed" | "ciba_exchange_succeeded" | "ciba_start_failed" | "ciba_start_succeeded" | "cls" | "cs" | "depnote" | "f" | "fc" | "fce" | "fco" | "fcoa" | "fcp" | "fcph" | "fcpn" | "fcpr" | "fcpro" | "fcu" | "fd" | "fdeac" | "fdeaz" | "fdecc" | "fdu" | "feacft" | "feccft" | "fecte" | "fede" | "federated_logout_failed" | "fens" | "feoobft" | "feotpft" | "fepft" | "fepotpft" | "fercft" | "ferrt" | "fertft" | "festft" | "fh" | "fimp" | "fi" | "flo" | "flows_execution_completed" | "flows_execution_failed" | "forms_submission_failed" | "forms_submission_succeeded" | "fp" | "fpar" | "fpurh" | "fs" | "fsa" | "fu" | "fui" | "fv" | "fvr" | "gd_auth_email_verification" | "gd_auth_fail_email_verification" | "gd_auth_failed" | "gd_auth_rejected" | "gd_auth_succeed" | "gd_enrollment_complete" | "gd_otp_rate_limit_exceed" | "gd_recovery_failed" | "gd_recovery_rate_limit_exceed" | "gd_recovery_succeed" | "gd_send_email" | "gd_send_email_verification" | "gd_send_email_verification_failure" | "gd_send_pn" | "gd_send_pn_failure" | "gd_send_sms" | "gd_send_sms_failure" | "gd_send_voice" | "gd_send_voice_failure" | "gd_start_auth" | "gd_start_enroll" | "gd_start_enroll_failed" | "gd_tenant_update" | "gd_unenroll" | "gd_update_device_account" | "gd_webauthn_challenge_failed" | "gd_webauthn_enrollment_failed" | "kms_key_management_failure" | "kms_key_management_success" | "kms_key_state_changed" | "limit_delegation" | "limit_mu" | "limit_sul" | "limit_wc" | "mfar" | "mgmt_api_read" | "my_account_authentication_method_failed" | "my_account_authentication_method_succeeded" | "oidc_backchannel_logout_failed" | "oidc_backchannel_logout_succeeded" | "organization_member_added" | "passkey_challenge_failed" | "passkey_challenge_started" | "pla" | "pwd_leak" | "reset_pwd_leak" | "resource_cleanup" | "rich_consents_access_error" | "s" | "fapi" | "sce" | "scoa" | "scp" | "scpn" | "scpr" | "scu" | "scv" | "sd" | "sdu" | "seacft" | "seccft" | "secte" | "sede" | "sens" | "seoobft" | "seotpft" | "sepotpft" | "sepft" | "sepkoobft" | "sepkotpft" | "sepkrcft" | "sercft" | "sertft" | "sestft" | "simp" | "si" | "signup_pwd_leak" | "slo" | "sh" | "spm" | "srrt" | "ss" | "ss_sso_failure" | "ss_sso_info" | "ss_sso_success" | "ssa" | "sscim" | "sui" | "sv" | "svr" | "too_many_records" | "ublkdu" | "universal_logout_failed" | "universal_logout_succeeded" | "w" | "wn" | "wum";
741
741
  date: string;
742
742
  isMobile: boolean;
743
743
  log_id: string;
@@ -776,7 +776,7 @@ export declare const userRoutes: OpenAPIHono<{
776
776
  limit: number;
777
777
  length: number;
778
778
  logs: {
779
- type: "fc" | "fd" | "fn" | "i" | "sapi" | "acls_summary" | "actions_execution_failed" | "api_limit" | "api_limit_warning" | "appi" | "ciba_exchange_failed" | "ciba_exchange_succeeded" | "ciba_start_failed" | "ciba_start_succeeded" | "cls" | "cs" | "depnote" | "f" | "fce" | "fco" | "fcoa" | "fcp" | "fcph" | "fcpn" | "fcpr" | "fcpro" | "fcu" | "fdeac" | "fdeaz" | "fdecc" | "fdu" | "feacft" | "feccft" | "fecte" | "fede" | "federated_logout_failed" | "fens" | "feoobft" | "feotpft" | "fepft" | "fepotpft" | "fercft" | "ferrt" | "fertft" | "festft" | "fh" | "fimp" | "fi" | "flo" | "flows_execution_completed" | "flows_execution_failed" | "forms_submission_failed" | "forms_submission_succeeded" | "fp" | "fpar" | "fpurh" | "fs" | "fsa" | "fu" | "fui" | "fv" | "fvr" | "gd_auth_email_verification" | "gd_auth_fail_email_verification" | "gd_auth_failed" | "gd_auth_rejected" | "gd_auth_succeed" | "gd_enrollment_complete" | "gd_otp_rate_limit_exceed" | "gd_recovery_failed" | "gd_recovery_rate_limit_exceed" | "gd_recovery_succeed" | "gd_send_email" | "gd_send_email_verification" | "gd_send_email_verification_failure" | "gd_send_pn" | "gd_send_pn_failure" | "gd_send_sms" | "gd_send_sms_failure" | "gd_send_voice" | "gd_send_voice_failure" | "gd_start_auth" | "gd_start_enroll" | "gd_start_enroll_failed" | "gd_tenant_update" | "gd_unenroll" | "gd_update_device_account" | "gd_webauthn_challenge_failed" | "gd_webauthn_enrollment_failed" | "kms_key_management_failure" | "kms_key_management_success" | "kms_key_state_changed" | "limit_delegation" | "limit_mu" | "limit_sul" | "limit_wc" | "mfar" | "mgmt_api_read" | "my_account_authentication_method_failed" | "my_account_authentication_method_succeeded" | "oidc_backchannel_logout_failed" | "oidc_backchannel_logout_succeeded" | "organization_member_added" | "passkey_challenge_failed" | "passkey_challenge_started" | "pla" | "pwd_leak" | "reset_pwd_leak" | "resource_cleanup" | "rich_consents_access_error" | "s" | "fapi" | "sce" | "scoa" | "scp" | "scpn" | "scpr" | "scu" | "scv" | "sd" | "sdu" | "seacft" | "seccft" | "secte" | "sede" | "sens" | "seoobft" | "seotpft" | "sepotpft" | "sepft" | "sepkoobft" | "sepkotpft" | "sepkrcft" | "sercft" | "sertft" | "sestft" | "simp" | "si" | "signup_pwd_leak" | "slo" | "sh" | "spm" | "srrt" | "ss" | "ss_sso_failure" | "ss_sso_info" | "ss_sso_success" | "ssa" | "sscim" | "sui" | "sv" | "svr" | "too_many_records" | "ublkdu" | "universal_logout_failed" | "universal_logout_succeeded" | "w" | "wn" | "wum";
779
+ type: "fn" | "i" | "sapi" | "acls_summary" | "actions_execution_failed" | "api_limit" | "api_limit_warning" | "appi" | "ciba_exchange_failed" | "ciba_exchange_succeeded" | "ciba_start_failed" | "ciba_start_succeeded" | "cls" | "cs" | "depnote" | "f" | "fc" | "fce" | "fco" | "fcoa" | "fcp" | "fcph" | "fcpn" | "fcpr" | "fcpro" | "fcu" | "fd" | "fdeac" | "fdeaz" | "fdecc" | "fdu" | "feacft" | "feccft" | "fecte" | "fede" | "federated_logout_failed" | "fens" | "feoobft" | "feotpft" | "fepft" | "fepotpft" | "fercft" | "ferrt" | "fertft" | "festft" | "fh" | "fimp" | "fi" | "flo" | "flows_execution_completed" | "flows_execution_failed" | "forms_submission_failed" | "forms_submission_succeeded" | "fp" | "fpar" | "fpurh" | "fs" | "fsa" | "fu" | "fui" | "fv" | "fvr" | "gd_auth_email_verification" | "gd_auth_fail_email_verification" | "gd_auth_failed" | "gd_auth_rejected" | "gd_auth_succeed" | "gd_enrollment_complete" | "gd_otp_rate_limit_exceed" | "gd_recovery_failed" | "gd_recovery_rate_limit_exceed" | "gd_recovery_succeed" | "gd_send_email" | "gd_send_email_verification" | "gd_send_email_verification_failure" | "gd_send_pn" | "gd_send_pn_failure" | "gd_send_sms" | "gd_send_sms_failure" | "gd_send_voice" | "gd_send_voice_failure" | "gd_start_auth" | "gd_start_enroll" | "gd_start_enroll_failed" | "gd_tenant_update" | "gd_unenroll" | "gd_update_device_account" | "gd_webauthn_challenge_failed" | "gd_webauthn_enrollment_failed" | "kms_key_management_failure" | "kms_key_management_success" | "kms_key_state_changed" | "limit_delegation" | "limit_mu" | "limit_sul" | "limit_wc" | "mfar" | "mgmt_api_read" | "my_account_authentication_method_failed" | "my_account_authentication_method_succeeded" | "oidc_backchannel_logout_failed" | "oidc_backchannel_logout_succeeded" | "organization_member_added" | "passkey_challenge_failed" | "passkey_challenge_started" | "pla" | "pwd_leak" | "reset_pwd_leak" | "resource_cleanup" | "rich_consents_access_error" | "s" | "fapi" | "sce" | "scoa" | "scp" | "scpn" | "scpr" | "scu" | "scv" | "sd" | "sdu" | "seacft" | "seccft" | "secte" | "sede" | "sens" | "seoobft" | "seotpft" | "sepotpft" | "sepft" | "sepkoobft" | "sepkotpft" | "sepkrcft" | "sercft" | "sertft" | "sestft" | "simp" | "si" | "signup_pwd_leak" | "slo" | "sh" | "spm" | "srrt" | "ss" | "ss_sso_failure" | "ss_sso_info" | "ss_sso_success" | "ssa" | "sscim" | "sui" | "sv" | "svr" | "too_many_records" | "ublkdu" | "universal_logout_failed" | "universal_logout_succeeded" | "w" | "wn" | "wum";
780
780
  date: string;
781
781
  isMobile: boolean;
782
782
  log_id: string;
@@ -2,6 +2,7 @@ import { Hono } from "hono";
2
2
  import type { ResolvedHost } from "@authhero/proxy";
3
3
  import { CustomDomain, CustomDomainsAdapter, ProxyRoute, ProxyRoutesAdapter } from "@authhero/adapter-interfaces";
4
4
  import { SyncEvent } from "../../helpers/control-plane-sync-events";
5
+ import { Bindings } from "../../types";
5
6
  export interface ProxyControlPlaneOptions {
6
7
  /**
7
8
  * Cross-tenant host resolver. Typically delegated to a database adapter's
@@ -9,13 +10,12 @@ export interface ProxyControlPlaneOptions {
9
10
  */
10
11
  resolveHost: (host: string) => Promise<ResolvedHost | null>;
11
12
  /**
12
- * Authentication check for incoming requests. Return `true` to allow,
13
- * `false` to reject with 401. The control-plane endpoint is cross-tenant
14
- * and must not be exposed to regular tenant tokens use a dedicated
15
- * proxy-reader credential (shared secret, mTLS, JWT with `proxy:resolve_host`
16
- * scope, …).
13
+ * Optional fetch override for the per-issuer JWKS document. Called with
14
+ * the derived URL (`<iss>/.well-known/jwks.json`); defaults to global
15
+ * `fetch`. Hosts on Cloudflare Workers can route specific hosts through a
16
+ * service binding by inspecting the URL and dispatching accordingly.
17
17
  */
18
- authenticate: (request: Request) => Promise<boolean> | boolean;
18
+ jwksFetch?: (url: string) => Promise<Response>;
19
19
  /**
20
20
  * Optional handler for `POST /sync` — receives `controlplane.sync.*` events
21
21
  * emitted by tenant shards via `ControlPlaneSyncDestination` and replicates
@@ -34,8 +34,17 @@ export interface ProxyControlPlaneOptions {
34
34
  * `GET /hosts/:host`. When `applySyncEvents` is provided, also exposes
35
35
  * `POST /sync` for tenant shards to replicate custom_domains / proxy_routes
36
36
  * mutations. Mount under `/api/v2/proxy/control-plane`.
37
+ *
38
+ * Authentication is built in: requests must carry a `Bearer` JWT whose `iss`
39
+ * is either the runtime `env.ISSUER` or the host the request actually
40
+ * arrived on (`x-forwarded-host` or the request URL's host). The verifier
41
+ * then fetches `<iss>/.well-known/jwks.json` to validate the signature, so
42
+ * each accepted host must publish its own JWKS at that path. Tokens must
43
+ * also carry the `proxy:resolve_host` scope.
37
44
  */
38
- export declare function createProxyControlPlaneApp(options: ProxyControlPlaneOptions): Hono;
45
+ export declare function createProxyControlPlaneApp(options: ProxyControlPlaneOptions): Hono<{
46
+ Bindings: Bindings;
47
+ }>;
39
48
  export interface CreateApplySyncEventsOptions {
40
49
  customDomains: CustomDomainsAdapter;
41
50
  proxyRoutes?: ProxyRoutesAdapter;
@@ -0,0 +1,44 @@
1
+ import { PROXY_RESOLVE_HOST_SCOPE } from "@authhero/proxy";
2
+ /**
3
+ * Strict issuer equality: parse both `iss` and `expected` as URLs and compare
4
+ * the resulting hrefs after stripping any single trailing slash. No host-only
5
+ * match, no subdomain match — a token issued by `https://a.example.com/` and
6
+ * an expected `https://b.example.com/` (or `https://example.com/x/`) must NOT
7
+ * be treated as equivalent.
8
+ */
9
+ export declare function isAllowedIssuer(iss: string, expected: string): boolean;
10
+ export type VerifyControlPlaneTokenResult = {
11
+ ok: true;
12
+ } | {
13
+ ok: false;
14
+ reason: string;
15
+ };
16
+ export interface VerifyControlPlaneTokenOptions {
17
+ /** Compact JWS to verify. */
18
+ token: string;
19
+ /** Optional fetch override — defaults to global `fetch`. */
20
+ jwksFetch?: (url: string) => Promise<Response>;
21
+ /**
22
+ * Set of acceptable `iss` claim values. Comparison is strict URL equality
23
+ * (after trailing-slash normalization) via {@link isAllowedIssuer}. The
24
+ * verifier fetches the per-issuer JWKS from `<iss>/.well-known/jwks.json`,
25
+ * so any host you list here must publish its own JWKS at that path.
26
+ */
27
+ expectedIssuers: string[];
28
+ /** Required `scope` (space-separated). Defaults to `proxy:resolve_host`. */
29
+ requiredScope?: string;
30
+ }
31
+ /**
32
+ * Verify a bearer token for the proxy control plane. Returns `{ ok: true }`
33
+ * on success, `{ ok: false, reason }` on any failure — the reason is for
34
+ * logs only and must not be surfaced to the caller.
35
+ *
36
+ * Accepted algs: RS256/384/512, ES256/384/512. The JWK's `alg` must match
37
+ * the token header's `alg`. The token must carry the configured required
38
+ * scope (`proxy:resolve_host` by default) and an `iss` that strictly equals
39
+ * one of `expectedIssuers` after URL normalization. The JWKS document is
40
+ * fetched from `<iss>/.well-known/jwks.json` AFTER the `iss` is allow-listed,
41
+ * so an attacker cannot redirect the verifier to a JWKS they control.
42
+ */
43
+ export declare function verifyControlPlaneToken(options: VerifyControlPlaneTokenOptions): Promise<VerifyControlPlaneTokenResult>;
44
+ export { PROXY_RESOLVE_HOST_SCOPE };
@@ -447,7 +447,7 @@ export declare function initJSXRoute(ctx: Context<{
447
447
  custom_login_page_preview?: string | undefined;
448
448
  form_template?: string | undefined;
449
449
  addons?: Record<string, any> | undefined;
450
- token_endpoint_auth_method?: "none" | "private_key_jwt" | "client_secret_post" | "client_secret_basic" | "client_secret_jwt" | undefined;
450
+ token_endpoint_auth_method?: "client_secret_post" | "client_secret_basic" | "none" | "private_key_jwt" | "client_secret_jwt" | undefined;
451
451
  client_metadata?: Record<string, string> | undefined;
452
452
  hide_sign_up_disabled_error?: boolean | undefined;
453
453
  mobile?: Record<string, any> | undefined;
@@ -1166,7 +1166,7 @@ export declare function initJSXRouteWithSession(ctx: Context<{
1166
1166
  custom_login_page_preview?: string | undefined;
1167
1167
  form_template?: string | undefined;
1168
1168
  addons?: Record<string, any> | undefined;
1169
- token_endpoint_auth_method?: "none" | "private_key_jwt" | "client_secret_post" | "client_secret_basic" | "client_secret_jwt" | undefined;
1169
+ token_endpoint_auth_method?: "client_secret_post" | "client_secret_basic" | "none" | "private_key_jwt" | "client_secret_jwt" | undefined;
1170
1170
  client_metadata?: Record<string, string> | undefined;
1171
1171
  hide_sign_up_disabled_error?: boolean | undefined;
1172
1172
  mobile?: Record<string, any> | undefined;
@@ -27,7 +27,7 @@ export declare const flowApiRoutes: OpenAPIHono<{
27
27
  output: {
28
28
  screen: {
29
29
  action: string;
30
- method: "GET" | "POST";
30
+ method: "POST" | "GET";
31
31
  components: {
32
32
  id: string;
33
33
  type: string;
@@ -107,7 +107,7 @@ export declare const flowApiRoutes: OpenAPIHono<{
107
107
  output: {
108
108
  screen: {
109
109
  action: string;
110
- method: "GET" | "POST";
110
+ method: "POST" | "GET";
111
111
  components: {
112
112
  id: string;
113
113
  type: string;
@@ -204,7 +204,7 @@ export declare const flowApiRoutes: OpenAPIHono<{
204
204
  output: {
205
205
  screen: {
206
206
  action: string;
207
- method: "GET" | "POST";
207
+ method: "POST" | "GET";
208
208
  components: {
209
209
  id: string;
210
210
  type: string;
@@ -319,7 +319,7 @@ export declare const flowApiRoutes: OpenAPIHono<{
319
319
  output: {
320
320
  screen: {
321
321
  action: string;
322
- method: "GET" | "POST";
322
+ method: "POST" | "GET";
323
323
  components: {
324
324
  id: string;
325
325
  type: string;
@@ -283,14 +283,24 @@ export interface AuthHeroConfig {
283
283
  * data plane. When set, mounts `GET /api/v2/proxy/control-plane/hosts/:host`
284
284
  * which returns the cross-tenant `ResolvedHost` for the given hostname.
285
285
  *
286
- * This endpoint is read by remote proxy deployments via
287
- * `createHttpProxyAdapter`. It is **cross-tenant** gate it with a
288
- * dedicated credential (shared secret, mTLS, or a JWT scoped to
289
- * `proxy:resolve_host`), never with a tenant token.
286
+ * Authentication is opinionated and built in: incoming requests must
287
+ * carry a `Bearer` JWT whose `iss` is either the runtime `env.ISSUER`
288
+ * or the host the request landed on (tenant subdomain or registered
289
+ * custom domain). The verifier fetches `<iss>/.well-known/jwks.json` to
290
+ * validate the signature, so each accepted host must publish its own
291
+ * JWKS at that path. Tokens must also carry the `proxy:resolve_host`
292
+ * scope. The matching client-side helper is `createHttpProxyAdapter`
293
+ * in `@authhero/proxy`.
290
294
  */
291
295
  proxyControlPlane?: {
292
296
  resolveHost: (host: string) => Promise<import("@authhero/proxy").ResolvedHost | null>;
293
- authenticate: (request: Request) => Promise<boolean> | boolean;
297
+ /**
298
+ * Optional fetch override for the per-issuer JWKS document. Called
299
+ * with the derived URL (`<iss>/.well-known/jwks.json`); defaults to
300
+ * global `fetch`. Hosts on Cloudflare Workers can route specific
301
+ * hosts through a service binding by inspecting the URL.
302
+ */
303
+ jwksFetch?: (url: string) => Promise<Response>;
294
304
  /**
295
305
  * Optional receiver for `POST /sync` events emitted by tenant shards via
296
306
  * the `ControlPlaneSyncDestination`. Mount on the control-plane authhero
@@ -9,7 +9,7 @@ import { SigningKeyModeOption } from "../types/AuthHeroConfig";
9
9
  */
10
10
  export declare function getJwksFromDatabase(data: DataAdapters): Promise<{
11
11
  alg: "RS256" | "RS384" | "RS512" | "ES256" | "ES384" | "ES512" | "HS256" | "HS384" | "HS512";
12
- kty: "EC" | "RSA" | "oct";
12
+ kty: "RSA" | "EC" | "oct";
13
13
  kid?: string | undefined;
14
14
  use?: "sig" | "enc" | undefined;
15
15
  n?: string | undefined;
@@ -28,7 +28,7 @@ export declare function getJwksFromDatabase(data: DataAdapters): Promise<{
28
28
  */
29
29
  export declare function getJwksForPublication(data: DataAdapters, tenantId: string, modeOption: SigningKeyModeOption | undefined): Promise<{
30
30
  alg: "RS256" | "RS384" | "RS512" | "ES256" | "ES384" | "ES512" | "HS256" | "HS384" | "HS512";
31
- kty: "EC" | "RSA" | "oct";
31
+ kty: "RSA" | "EC" | "oct";
32
32
  kid?: string | undefined;
33
33
  use?: "sig" | "enc" | undefined;
34
34
  n?: string | undefined;
package/package.json CHANGED
@@ -11,7 +11,7 @@
11
11
  "type": "git",
12
12
  "url": "https://github.com/markusahlstrand/authhero"
13
13
  },
14
- "version": "6.0.0",
14
+ "version": "7.1.0",
15
15
  "files": [
16
16
  "dist"
17
17
  ],
@@ -62,8 +62,8 @@
62
62
  "vite": "^8.0.14",
63
63
  "vite-plugin-dts": "^4.5.4",
64
64
  "vitest": "^4.1.7",
65
- "@authhero/kysely-adapter": "11.8.2",
66
- "@authhero/widget": "0.32.39"
65
+ "@authhero/kysely-adapter": "11.8.5",
66
+ "@authhero/widget": "0.32.40"
67
67
  },
68
68
  "dependencies": {
69
69
  "@peculiar/x509": "^1.14.0",
@@ -81,8 +81,8 @@
81
81
  "qrcode": "^1.5.4",
82
82
  "sanitize-html": "^2.17.4",
83
83
  "xstate": "^5.31.1",
84
- "@authhero/adapter-interfaces": "3.0.0",
85
- "@authhero/proxy": "0.4.5",
84
+ "@authhero/adapter-interfaces": "3.1.0",
85
+ "@authhero/proxy": "0.5.1",
86
86
  "@authhero/saml": "0.4.1"
87
87
  },
88
88
  "peerDependencies": {