kavachos 0.0.6 → 0.1.1

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 (47) hide show
  1. package/README.md +170 -37
  2. package/dist/a2a/index.d.ts +2 -1
  3. package/dist/a2a/index.js +7 -2
  4. package/dist/a2a/index.js.map +1 -1
  5. package/dist/agent/index.d.ts +3 -2
  6. package/dist/agent/index.js +789 -4
  7. package/dist/agent/index.js.map +1 -1
  8. package/dist/audit/index.d.ts +2 -1
  9. package/dist/audit/index.js +635 -3
  10. package/dist/audit/index.js.map +1 -1
  11. package/dist/auth/index.d.ts +600 -3
  12. package/dist/auth/index.js +14668 -4
  13. package/dist/auth/index.js.map +1 -1
  14. package/dist/crypto/index.d.ts +55 -0
  15. package/dist/{chunk-QCRHJMDX.js → crypto/index.js} +2 -2
  16. package/dist/crypto/index.js.map +1 -0
  17. package/dist/index.d.ts +251 -58
  18. package/dist/index.js +16369 -233
  19. package/dist/index.js.map +1 -1
  20. package/dist/mcp/index.js +19 -2
  21. package/dist/mcp/index.js.map +1 -1
  22. package/dist/permission/index.d.ts +3 -2
  23. package/dist/permission/index.js +790 -4
  24. package/dist/permission/index.js.map +1 -1
  25. package/dist/redirect/index.d.ts +118 -0
  26. package/dist/redirect/index.js +292 -0
  27. package/dist/redirect/index.js.map +1 -0
  28. package/dist/{types-W8X0PXE7.d.ts → types-5Ua5KlPc.d.ts} +222 -124
  29. package/dist/vc/index.js +542 -3
  30. package/dist/vc/index.js.map +1 -1
  31. package/package.json +39 -22
  32. package/LICENSE +0 -21
  33. package/dist/chunk-FKVAXCNJ.js +0 -12516
  34. package/dist/chunk-FKVAXCNJ.js.map +0 -1
  35. package/dist/chunk-IKTOSJ4O.js +0 -214
  36. package/dist/chunk-IKTOSJ4O.js.map +0 -1
  37. package/dist/chunk-KDL6A76K.js +0 -569
  38. package/dist/chunk-KDL6A76K.js.map +0 -1
  39. package/dist/chunk-NSBPE2FW.js +0 -15
  40. package/dist/chunk-NSBPE2FW.js.map +0 -1
  41. package/dist/chunk-NSTER7KE.js +0 -538
  42. package/dist/chunk-NSTER7KE.js.map +0 -1
  43. package/dist/chunk-QCRHJMDX.js.map +0 -1
  44. package/dist/chunk-VHKZARMM.js +0 -251
  45. package/dist/chunk-VHKZARMM.js.map +0 -1
  46. package/dist/chunk-Y3OWAJHK.js +0 -101
  47. package/dist/chunk-Y3OWAJHK.js.map +0 -1
@@ -1,9 +1,10 @@
1
1
  import { z } from 'zod';
2
- import { a2 as AuthAdapter, o as ResolvedUser, L as KavachPlugin, D as Database, X as AdminConfig, p as SessionManager, $ as ApiKeyManagerConfig, a7 as EmailOtpConfig, P as Permission, ab as MagicLinkConfig, ag as OrgConfig, al as PasskeyConfig, I as PluginEndpoint, aF as TotpConfig } from '../types-W8X0PXE7.js';
3
- export { u as AdminModule, Y as AdminUser, _ as ApiKey, v as ApiKeyManagerModule, a3 as CaptchaConfig, G as CaptchaModule, a4 as CaptchaVerifyResult, a5 as CreateTokenInput, E as EmailOtpModule, a8 as EmailVerificationConfig, y as EmailVerificationModule, r as MagicLinkModule, ad as OidcProvider, ae as OneTimeTokenConfig, z as OneTimeTokenModule, af as OneTimeTokenPurpose, ah as OrgInvitation, ai as OrgMember, O as OrgModule, aj as OrgRole, ak as Organization, am as PasskeyCredential, s as PasskeyModule, an as PasswordResetConfig, x as PasswordResetModule, ap as PhoneAuthConfig, F as PhoneAuthModule, av as RevokeTokensResult, aw as SSO_ERROR, ax as SamlProvider, aA as SsoAuditEvent, aB as SsoConfig, aC as SsoConnection, aD as SsoError, t as SsoModule, T as TotpModule, aG as TotpSetup, aH as UsernameAuthConfig, w as UsernameAuthModule, aI as ValidateTokenResult, bv as WebhookConfig, bw as WebhookEvent, W as WebhookModule, aS as createAdminModule, aT as createApiKeyManagerModule, aV as createCaptchaModule, aY as createEmailOtpModule, aZ as createEmailVerificationModule, a_ as createMagicLinkModule, a$ as createOneTimeTokenModule, b0 as createOrgModule, b1 as createPasskeyModule, b2 as createPasswordResetModule, b3 as createPhoneAuthModule, b7 as createSsoModule, b8 as createTotpModule, b9 as createUsernameAuthModule, bx as createWebhookModule } from '../types-W8X0PXE7.js';
2
+ import { a1 as AuthAdapter, o as ResolvedUser, J as KavachPlugin, D as Database, Q as AdminConfig, p as SessionManager, _ as ApiKeyManagerConfig, a6 as EmailOtpConfig, P as Permission, aa as MagicLinkConfig, af as OrgConfig, ak as PasskeyConfig, H as PluginEndpoint, aB as TotpConfig } from '../types-5Ua5KlPc.js';
3
+ export { u as AdminModule, X as AdminUser, Z as ApiKey, v as ApiKeyManagerModule, a2 as CaptchaConfig, G as CaptchaModule, a3 as CaptchaVerifyResult, a4 as CreateTokenInput, E as EmailOtpModule, a7 as EmailVerificationConfig, y as EmailVerificationModule, r as MagicLinkModule, ac as OidcProvider, ad as OneTimeTokenConfig, z as OneTimeTokenModule, ae as OneTimeTokenPurpose, ag as OrgInvitation, ah as OrgMember, O as OrgModule, ai as OrgRole, aj as Organization, al as PasskeyCredential, s as PasskeyModule, am as PasswordResetConfig, x as PasswordResetModule, ao as PhoneAuthConfig, F as PhoneAuthModule, ar as RevokeTokensResult, as as SSO_ERROR, at as SamlProvider, aw as SsoAuditEvent, ax as SsoConfig, ay as SsoConnection, az as SsoError, t as SsoModule, T as TotpModule, aC as TotpSetup, aD as UsernameAuthConfig, w as UsernameAuthModule, aE as ValidateTokenResult, bq as WebhookConfig, br as WebhookEvent, W as WebhookModule, aO as createAdminModule, aP as createApiKeyManagerModule, aR as createCaptchaModule, aU as createEmailOtpModule, aV as createEmailVerificationModule, aW as createMagicLinkModule, aX as createOneTimeTokenModule, aY as createOrgModule, aZ as createPasskeyModule, a_ as createPasswordResetModule, a$ as createPhoneAuthModule, b2 as createSsoModule, b3 as createTotpModule, b4 as createUsernameAuthModule, bs as createWebhookModule } from '../types-5Ua5KlPc.js';
4
4
  import { R as Result } from '../types-BuHrZcjE.js';
5
5
  import * as jose from 'jose';
6
6
  import 'drizzle-orm/sqlite-core';
7
+ import '../redirect/index.js';
7
8
 
8
9
  /**
9
10
  * JWT bearer-token auth adapter.
@@ -1188,6 +1189,29 @@ declare function createLastLoginModule(config: LastLoginConfig, db: Database): L
1188
1189
 
1189
1190
  declare function magicLink(config: MagicLinkConfig): KavachPlugin;
1190
1191
 
1192
+ /**
1193
+ * Types for the OAuth 2.0 / OIDC provider system.
1194
+ *
1195
+ * KavachOS uses PKCE (S256) for all provider flows regardless of whether
1196
+ * the provider strictly requires it. This prevents authorization code
1197
+ * interception attacks on both public and confidential clients.
1198
+ */
1199
+ interface OAuthProviderConfig {
1200
+ /** OAuth application client ID. */
1201
+ clientId: string;
1202
+ /** OAuth application client secret. */
1203
+ clientSecret: string;
1204
+ /**
1205
+ * Additional scopes to request on top of the provider defaults.
1206
+ * The provider's default scopes are always included.
1207
+ */
1208
+ scopes?: string[];
1209
+ /**
1210
+ * Override the redirect URI registered with the provider.
1211
+ * When omitted the module uses the `redirectUri` passed at call time.
1212
+ */
1213
+ redirectUri?: string;
1214
+ }
1191
1215
  interface OAuthProvider {
1192
1216
  /** Machine-readable provider ID, e.g. `'google'`, `'github'`. */
1193
1217
  id: string;
@@ -1252,6 +1276,446 @@ interface OAuthUserInfo {
1252
1276
  /** Full raw response from the provider's user info endpoint. */
1253
1277
  raw: Record<string, unknown>;
1254
1278
  }
1279
+ interface OAuthModuleConfig {
1280
+ /**
1281
+ * Map of provider ID to provider instance.
1282
+ *
1283
+ * @example
1284
+ * ```typescript
1285
+ * import { createGoogleProvider } from 'kavachos/auth/oauth/providers/google';
1286
+ * import { createGithubProvider } from 'kavachos/auth/oauth/providers/github';
1287
+ *
1288
+ * providers: {
1289
+ * google: createGoogleProvider({ clientId: '...', clientSecret: '...' }),
1290
+ * github: createGithubProvider({ clientId: '...', clientSecret: '...' }),
1291
+ * }
1292
+ * ```
1293
+ */
1294
+ providers: Record<string, OAuthProvider>;
1295
+ /**
1296
+ * How long an OAuth state entry lives before it is considered expired.
1297
+ * Defaults to 600 seconds (10 minutes).
1298
+ */
1299
+ stateTtlSeconds?: number;
1300
+ }
1301
+ interface OAuthModule {
1302
+ /**
1303
+ * Generate a PKCE-protected authorization URL and persist the state.
1304
+ *
1305
+ * Call this on your `/auth/:provider` route and redirect the user to the
1306
+ * returned URL.
1307
+ *
1308
+ * @returns `{ url, state }` — redirect to `url`; `state` is stored in the DB.
1309
+ */
1310
+ getAuthorizationUrl(providerId: string, redirectUri: string): Promise<{
1311
+ url: string;
1312
+ state: string;
1313
+ }>;
1314
+ /**
1315
+ * Handle the provider callback and resolve (or create) a linked account.
1316
+ *
1317
+ * Call this on your `/auth/:provider/callback` route.
1318
+ *
1319
+ * @param providerId The provider that issued the callback.
1320
+ * @param code The authorization code from the query string.
1321
+ * @param state The state value from the query string (validated against DB).
1322
+ * @param redirectUri Must match the URI used in `getAuthorizationUrl`.
1323
+ * @returns The linked account row and normalized user info.
1324
+ */
1325
+ handleCallback(providerId: string, code: string, state: string, redirectUri: string): Promise<OAuthCallbackResult>;
1326
+ /**
1327
+ * Manually link an OAuth provider account to an existing KavachOS user.
1328
+ *
1329
+ * Useful when you want to add a second provider to a user who already
1330
+ * authenticated via a different method.
1331
+ */
1332
+ linkAccount(userId: string, providerId: string, userInfo: OAuthUserInfo, tokens: OAuthTokens): Promise<OAuthAccount>;
1333
+ /**
1334
+ * Look up the KavachOS user linked to a given provider account.
1335
+ *
1336
+ * Returns `null` when no link exists yet.
1337
+ */
1338
+ findLinkedUser(providerId: string, providerAccountId: string): Promise<{
1339
+ userId: string;
1340
+ } | null>;
1341
+ }
1342
+ interface OAuthCallbackResult {
1343
+ /** Whether this callback created a new linked account (vs. found an existing one). */
1344
+ isNewAccount: boolean;
1345
+ account: OAuthAccount;
1346
+ userInfo: OAuthUserInfo;
1347
+ tokens: OAuthTokens;
1348
+ }
1349
+ interface OAuthAccount {
1350
+ id: string;
1351
+ userId: string;
1352
+ provider: string;
1353
+ providerAccountId: string;
1354
+ accessToken: string;
1355
+ refreshToken: string | null;
1356
+ expiresAt: Date | null;
1357
+ createdAt: Date;
1358
+ updatedAt: Date;
1359
+ }
1360
+
1361
+ /**
1362
+ * OAuth module factory.
1363
+ *
1364
+ * Provides three operations on top of any configured set of providers:
1365
+ *
1366
+ * 1. `getAuthorizationUrl` — generate a PKCE-protected authorization URL and
1367
+ * persist the state + code verifier to the database.
1368
+ * 2. `handleCallback` — validate state, exchange the code, fetch user info,
1369
+ * and create or return an existing linked account.
1370
+ * 3. `linkAccount` — manually link provider tokens to an existing user.
1371
+ * 4. `findLinkedUser` — look up which user owns a provider account.
1372
+ *
1373
+ * All state operations use the `kavach_oauth_states` table; all account links
1374
+ * use the `kavach_oauth_accounts` table — both defined in `./schema.ts`.
1375
+ */
1376
+
1377
+ /**
1378
+ * Create an OAuth module bound to a database instance.
1379
+ *
1380
+ * @example
1381
+ * ```typescript
1382
+ * import { createOAuthModule } from 'kavachos/auth/oauth';
1383
+ * import { createGoogleProvider } from 'kavachos/auth/oauth/providers/google';
1384
+ *
1385
+ * const oauth = createOAuthModule(db, {
1386
+ * providers: {
1387
+ * google: createGoogleProvider({ clientId: '...', clientSecret: '...' }),
1388
+ * },
1389
+ * });
1390
+ *
1391
+ * // On /auth/google
1392
+ * const { url } = await oauth.getAuthorizationUrl('google', 'https://my.app/callback');
1393
+ * return redirect(url);
1394
+ *
1395
+ * // On /auth/google/callback
1396
+ * const { account, userInfo } = await oauth.handleCallback(
1397
+ * 'google', req.query.code, req.query.state, 'https://my.app/callback',
1398
+ * );
1399
+ * ```
1400
+ */
1401
+ declare function createOAuthModule(db: Database, config: OAuthModuleConfig): OAuthModule;
1402
+
1403
+ interface OAuthPluginConfig extends OAuthModuleConfig {
1404
+ /**
1405
+ * Build the redirect URI for a given provider.
1406
+ *
1407
+ * When omitted the plugin constructs the URI from `ctx.config.baseUrl`
1408
+ * using the pattern `{baseUrl}/auth/oauth/callback/{provider}`.
1409
+ */
1410
+ buildRedirectUri?: (provider: string, baseUrl: string) => string;
1411
+ }
1412
+ declare function oauth(config: OAuthPluginConfig): KavachPlugin;
1413
+
1414
+ /**
1415
+ * Apple Sign In provider (OAuth 2.0 / OIDC).
1416
+ *
1417
+ * Endpoints:
1418
+ * - Authorization: https://appleid.apple.com/auth/authorize
1419
+ * - Token: https://appleid.apple.com/auth/token
1420
+ *
1421
+ * Notes:
1422
+ * - Apple does not expose a dedicated UserInfo endpoint. Instead, it embeds
1423
+ * user claims (email, name) in the `id_token` JWT on first authorization.
1424
+ * On subsequent authorizations the `user` form-post field is absent — only
1425
+ * the `id_token` carries the `sub` and `email` claims.
1426
+ * - PKCE S256 is supported and recommended.
1427
+ * - `response_mode` must be `form_post` when requesting the `name` scope,
1428
+ * because Apple POSTs back a `user` JSON field alongside the code.
1429
+ * - The `name` scope only delivers user data on the *first* authorization.
1430
+ * Store it immediately; subsequent logins will not include it.
1431
+ *
1432
+ * Docs: https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/incorporating_sign_in_with_apple_into_other_platforms
1433
+ */
1434
+
1435
+ /**
1436
+ * Create an Apple Sign In provider instance.
1437
+ *
1438
+ * Apple requires a JWT client secret (signed with your private key) rather
1439
+ * than a static secret. Generate the client secret JWT before passing it in
1440
+ * as `clientSecret`.
1441
+ *
1442
+ * @example
1443
+ * ```typescript
1444
+ * const apple = createAppleProvider({
1445
+ * clientId: process.env.APPLE_CLIENT_ID, // Services ID, e.g. com.example.app
1446
+ * clientSecret: appleClientSecretJwt, // ES256 JWT generated from private key
1447
+ * });
1448
+ * ```
1449
+ */
1450
+ declare function createAppleProvider(config: OAuthProviderConfig): OAuthProvider;
1451
+
1452
+ /**
1453
+ * Discord OAuth 2.0 provider.
1454
+ *
1455
+ * Endpoints:
1456
+ * - Authorization: https://discord.com/api/oauth2/authorize
1457
+ * - Token: https://discord.com/api/oauth2/token
1458
+ * - UserInfo: https://discord.com/api/users/@me
1459
+ *
1460
+ * Notes:
1461
+ * - PKCE S256 is supported as of the Discord OAuth 2.0 implementation.
1462
+ * - The `identify` scope grants access to the user object (ID, username,
1463
+ * avatar). The `email` scope is required separately to receive the email.
1464
+ * - Avatar URLs are constructed from the user ID and avatar hash. When the
1465
+ * user has no custom avatar, `avatar` is null and Discord serves a default
1466
+ * based on the discriminator (or username for the new username system).
1467
+ * - Discord user IDs are Snowflakes (64-bit integers serialized as strings).
1468
+ *
1469
+ * Docs: https://discord.com/developers/docs/topics/oauth2
1470
+ */
1471
+
1472
+ /**
1473
+ * Create a Discord OAuth provider instance.
1474
+ *
1475
+ * @example
1476
+ * ```typescript
1477
+ * const discord = createDiscordProvider({
1478
+ * clientId: process.env.DISCORD_CLIENT_ID,
1479
+ * clientSecret: process.env.DISCORD_CLIENT_SECRET,
1480
+ * });
1481
+ * ```
1482
+ */
1483
+ declare function createDiscordProvider(config: OAuthProviderConfig): OAuthProvider;
1484
+
1485
+ /**
1486
+ * GitHub OAuth 2.0 provider.
1487
+ *
1488
+ * Endpoints:
1489
+ * - Authorization: https://github.com/login/oauth/authorize
1490
+ * - Token: https://github.com/login/oauth/access_token
1491
+ * - UserInfo: https://api.github.com/user
1492
+ * - Emails: https://api.github.com/user/emails (for primary verified email)
1493
+ *
1494
+ * Notes:
1495
+ * - GitHub does not natively support PKCE in its OAuth flow, but we send the
1496
+ * `code_challenge` parameter anyway — it is silently ignored, which is safe.
1497
+ * The code verifier is still validated server-side within KavachOS state
1498
+ * storage so the CSRF protection guarantee holds.
1499
+ * - The `user:email` scope is required to read the primary email when it is
1500
+ * set to private on the GitHub profile.
1501
+ * - GitHub tokens do not carry an `expires_in` field for classic tokens.
1502
+ *
1503
+ * Docs: https://docs.github.com/en/apps/oauth-apps/building-oauth-apps
1504
+ */
1505
+
1506
+ /**
1507
+ * Create a GitHub OAuth provider instance.
1508
+ *
1509
+ * @example
1510
+ * ```typescript
1511
+ * const github = createGithubProvider({
1512
+ * clientId: process.env.GITHUB_CLIENT_ID,
1513
+ * clientSecret: process.env.GITHUB_CLIENT_SECRET,
1514
+ * });
1515
+ * ```
1516
+ */
1517
+ declare function createGithubProvider(config: OAuthProviderConfig): OAuthProvider;
1518
+
1519
+ /**
1520
+ * GitLab OAuth 2.0 provider.
1521
+ *
1522
+ * Endpoints (gitlab.com — self-managed instances replace the base URL):
1523
+ * - Authorization: https://gitlab.com/oauth/authorize
1524
+ * - Token: https://gitlab.com/oauth/token
1525
+ * - UserInfo: https://gitlab.com/api/v4/user
1526
+ *
1527
+ * Notes:
1528
+ * - PKCE S256 is supported.
1529
+ * - The `read_user` scope grants access to the `/api/v4/user` endpoint which
1530
+ * returns the authenticated user's profile including email.
1531
+ * - GitLab user IDs are integers; they are converted to strings for the
1532
+ * KavachOS normalized format.
1533
+ * - For self-managed GitLab instances, override the URLs by providing a
1534
+ * custom base URL and constructing the provider accordingly.
1535
+ *
1536
+ * Docs: https://docs.gitlab.com/ee/api/oauth2.html
1537
+ */
1538
+
1539
+ /**
1540
+ * Create a GitLab OAuth provider instance.
1541
+ *
1542
+ * @example
1543
+ * ```typescript
1544
+ * const gitlab = createGitlabProvider({
1545
+ * clientId: process.env.GITLAB_CLIENT_ID,
1546
+ * clientSecret: process.env.GITLAB_CLIENT_SECRET,
1547
+ * });
1548
+ * ```
1549
+ */
1550
+ declare function createGitlabProvider(config: OAuthProviderConfig): OAuthProvider;
1551
+
1552
+ /**
1553
+ * Google OAuth 2.0 / OIDC provider.
1554
+ *
1555
+ * Endpoints:
1556
+ * - Authorization: https://accounts.google.com/o/oauth2/v2/auth
1557
+ * - Token: https://oauth2.googleapis.com/token
1558
+ * - UserInfo: https://www.googleapis.com/oauth2/v3/userinfo
1559
+ *
1560
+ * PKCE S256 is always enforced. Google supports it for all client types
1561
+ * and the spec mandates it for public clients.
1562
+ *
1563
+ * Docs: https://developers.google.com/identity/protocols/oauth2
1564
+ */
1565
+
1566
+ /**
1567
+ * Create a Google OAuth provider instance.
1568
+ *
1569
+ * @example
1570
+ * ```typescript
1571
+ * const google = createGoogleProvider({
1572
+ * clientId: process.env.GOOGLE_CLIENT_ID,
1573
+ * clientSecret: process.env.GOOGLE_CLIENT_SECRET,
1574
+ * });
1575
+ * ```
1576
+ */
1577
+ declare function createGoogleProvider(config: OAuthProviderConfig): OAuthProvider;
1578
+
1579
+ /**
1580
+ * LinkedIn OAuth 2.0 / OIDC provider.
1581
+ *
1582
+ * Endpoints:
1583
+ * - Authorization: https://www.linkedin.com/oauth/v2/authorization
1584
+ * - Token: https://www.linkedin.com/oauth/v2/accessToken
1585
+ * - UserInfo: https://api.linkedin.com/v2/userinfo (OIDC endpoint)
1586
+ *
1587
+ * Notes:
1588
+ * - LinkedIn's OIDC userinfo endpoint (`/v2/userinfo`) is available when the
1589
+ * `openid` scope is requested. It returns standard OIDC claims including
1590
+ * `sub`, `name`, `email`, and `picture`.
1591
+ * - PKCE is not supported by LinkedIn's OAuth server. The code challenge is
1592
+ * sent for symmetry but silently ignored. CSRF protection via `state` still
1593
+ * applies within KavachOS.
1594
+ * - The `sub` claim is the LinkedIn member ID and is stable across sessions.
1595
+ *
1596
+ * Docs: https://learn.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/sign-in-with-linkedin-v2
1597
+ */
1598
+
1599
+ /**
1600
+ * Create a LinkedIn OAuth provider instance.
1601
+ *
1602
+ * @example
1603
+ * ```typescript
1604
+ * const linkedin = createLinkedInProvider({
1605
+ * clientId: process.env.LINKEDIN_CLIENT_ID,
1606
+ * clientSecret: process.env.LINKEDIN_CLIENT_SECRET,
1607
+ * });
1608
+ * ```
1609
+ */
1610
+ declare function createLinkedInProvider(config: OAuthProviderConfig): OAuthProvider;
1611
+
1612
+ /**
1613
+ * Microsoft identity platform (Entra ID / Azure AD) OAuth 2.0 / OIDC provider.
1614
+ *
1615
+ * Endpoints (common tenant — works for personal accounts and work/school):
1616
+ * - Authorization: https://login.microsoftonline.com/common/oauth2/v2.0/authorize
1617
+ * - Token: https://login.microsoftonline.com/common/oauth2/v2.0/token
1618
+ * - UserInfo: https://graph.microsoft.com/v1.0/me
1619
+ *
1620
+ * Notes:
1621
+ * - PKCE S256 is supported and required for public clients.
1622
+ * - `User.Read` is a Microsoft Graph permission, not a standard OIDC scope.
1623
+ * It grants access to the `/me` endpoint.
1624
+ * - The `id` field on the Graph `/me` response is the Entra object ID, which
1625
+ * is stable across tenant changes and is safe to use as a primary key.
1626
+ * - For single-tenant apps, replace `common` with the tenant ID or domain.
1627
+ *
1628
+ * Docs: https://learn.microsoft.com/en-us/entra/identity-platform/v2-oauth2-auth-code-flow
1629
+ */
1630
+
1631
+ /**
1632
+ * Create a Microsoft identity platform OAuth provider instance.
1633
+ *
1634
+ * @example
1635
+ * ```typescript
1636
+ * const microsoft = createMicrosoftProvider({
1637
+ * clientId: process.env.MICROSOFT_CLIENT_ID,
1638
+ * clientSecret: process.env.MICROSOFT_CLIENT_SECRET,
1639
+ * });
1640
+ * ```
1641
+ */
1642
+ declare function createMicrosoftProvider(config: OAuthProviderConfig): OAuthProvider;
1643
+
1644
+ /**
1645
+ * Slack OAuth 2.0 / OIDC provider.
1646
+ *
1647
+ * Endpoints:
1648
+ * - Authorization: https://slack.com/oauth/v2/authorize
1649
+ * - Token: https://slack.com/api/oauth.v2.access
1650
+ * - UserInfo: https://slack.com/api/openid.connect.userInfo
1651
+ *
1652
+ * Notes:
1653
+ * - Slack's v2 OAuth uses OpenID Connect for user sign-in. The
1654
+ * `openid.connect.userInfo` endpoint returns OIDC-standard claims.
1655
+ * - The token exchange response has a nested structure: `authed_user.access_token`
1656
+ * for the user token and a bot token at the top level when bot scopes are
1657
+ * included. For sign-in we want the user token.
1658
+ * - PKCE is not natively supported by Slack's OAuth v2 server. The code
1659
+ * challenge is sent but silently ignored — CSRF protection via `state` still
1660
+ * applies within KavachOS.
1661
+ * - Slack user IDs are workspace-scoped, not global. The `sub` claim from the
1662
+ * OIDC userinfo endpoint is the globally unique identifier across workspaces.
1663
+ *
1664
+ * Docs: https://api.slack.com/authentication/sign-in-with-slack
1665
+ */
1666
+
1667
+ /**
1668
+ * Create a Slack OAuth provider instance.
1669
+ *
1670
+ * @example
1671
+ * ```typescript
1672
+ * const slack = createSlackProvider({
1673
+ * clientId: process.env.SLACK_CLIENT_ID,
1674
+ * clientSecret: process.env.SLACK_CLIENT_SECRET,
1675
+ * });
1676
+ * ```
1677
+ */
1678
+ declare function createSlackProvider(config: OAuthProviderConfig): OAuthProvider;
1679
+
1680
+ /**
1681
+ * Twitter / X OAuth 2.0 provider.
1682
+ *
1683
+ * Endpoints:
1684
+ * - Authorization: https://twitter.com/i/oauth2/authorize
1685
+ * - Token: https://api.twitter.com/2/oauth2/token
1686
+ * - UserInfo: https://api.twitter.com/2/users/me
1687
+ *
1688
+ * Notes:
1689
+ * - Twitter OAuth 2.0 (the v2 API) mandates PKCE S256 for all public clients.
1690
+ * Confidential clients may omit PKCE but it is always safer to include it.
1691
+ * - The token exchange requires HTTP Basic auth (`client_id:client_secret`)
1692
+ * rather than including credentials in the request body.
1693
+ * - The `/2/users/me` endpoint returns a minimal set of fields by default.
1694
+ * Additional fields (profile_image_url, name) must be requested via the
1695
+ * `user.fields` query parameter.
1696
+ * - Twitter does not return an email address through the standard OAuth 2.0
1697
+ * flow. Email access requires a separate elevated API access application
1698
+ * and the `tweet.read` scope alone does not grant it.
1699
+ * - User IDs are numeric strings and stable across username changes.
1700
+ *
1701
+ * Docs: https://developer.twitter.com/en/docs/authentication/oauth-2-0/authorization-code
1702
+ */
1703
+
1704
+ /**
1705
+ * Create a Twitter / X OAuth provider instance.
1706
+ *
1707
+ * Twitter requires PKCE for all flows. The `clientSecret` is still needed for
1708
+ * the token exchange (sent as HTTP Basic auth).
1709
+ *
1710
+ * @example
1711
+ * ```typescript
1712
+ * const twitter = createTwitterProvider({
1713
+ * clientId: process.env.TWITTER_CLIENT_ID,
1714
+ * clientSecret: process.env.TWITTER_CLIENT_SECRET,
1715
+ * });
1716
+ * ```
1717
+ */
1718
+ declare function createTwitterProvider(config: OAuthProviderConfig): OAuthProvider;
1255
1719
 
1256
1720
  /**
1257
1721
  * OAuth proxy module for mobile apps.
@@ -1812,6 +2276,90 @@ declare function createPolarModule(config: PolarConfig, db: Database): PolarModu
1812
2276
 
1813
2277
  declare function polar(config: PolarConfig): KavachPlugin;
1814
2278
 
2279
+ /**
2280
+ * Shared store interface for the rateLimit() plugin.
2281
+ * Kept in a separate file to avoid circular imports between
2282
+ * rate-limit.ts and the individual store implementations.
2283
+ */
2284
+ /** Store backend interface for the rateLimit() plugin. */
2285
+ interface RateLimitStore {
2286
+ /**
2287
+ * Increment the hit count for `key` within a `windowMs`-millisecond window.
2288
+ * Returns the updated count and the unix timestamp (ms) when the window resets.
2289
+ */
2290
+ increment(key: string, windowMs: number): Promise<{
2291
+ count: number;
2292
+ resetAt: number;
2293
+ }>;
2294
+ /** Clear all recorded hits for a key. */
2295
+ reset(key: string): Promise<void>;
2296
+ }
2297
+
2298
+ /**
2299
+ * rateLimit() plugin for KavachOS.
2300
+ *
2301
+ * Wraps auth endpoints with configurable per-IP (and per-agent) throttling.
2302
+ * Intercepts requests via the onRequest lifecycle hook before any handler
2303
+ * runs, keeping the limiting logic decoupled from individual endpoints.
2304
+ *
2305
+ * @example
2306
+ * ```typescript
2307
+ * import { createKavach } from 'kavachos';
2308
+ * import { rateLimit } from 'kavachos/auth';
2309
+ * import { kvStore } from 'kavachos/auth/stores/kv';
2310
+ *
2311
+ * const kavach = createKavach({
2312
+ * plugins: [
2313
+ * rateLimit({
2314
+ * signIn: { window: '15m', max: 10 },
2315
+ * signUp: { window: '1h', max: 5 },
2316
+ * passwordReset: { window: '1h', max: 3 },
2317
+ * agentAuthorize:{ window: '1m', max: 100 },
2318
+ * default: { window: '1m', max: 60 },
2319
+ * store: kvStore(env.CACHE_KV),
2320
+ * }),
2321
+ * ],
2322
+ * });
2323
+ * ```
2324
+ */
2325
+
2326
+ /** Per-endpoint rate limit configuration */
2327
+ interface EndpointLimit {
2328
+ /** Duration string: "15m", "1h", "30s", "1d" */
2329
+ window: string;
2330
+ /** Maximum number of requests allowed within the window */
2331
+ max: number;
2332
+ }
2333
+ interface RateLimitConfig$1 {
2334
+ /** Limit for POST /auth/sign-in */
2335
+ signIn?: EndpointLimit;
2336
+ /** Limit for POST /auth/sign-up */
2337
+ signUp?: EndpointLimit;
2338
+ /** Limit for POST /auth/password-reset */
2339
+ passwordReset?: EndpointLimit;
2340
+ /** Limit for POST /auth/agent/authorize */
2341
+ agentAuthorize?: EndpointLimit;
2342
+ /** Fallback limit applied to all other /auth/* paths */
2343
+ default?: EndpointLimit;
2344
+ /**
2345
+ * Storage backend.
2346
+ * Pass "memory" or omit to use the built-in in-memory store.
2347
+ * Pass a KVStore (or any RateLimitStore) for edge deployments.
2348
+ */
2349
+ store?: "memory" | RateLimitStore;
2350
+ /**
2351
+ * Extract a rate-limit key from the request.
2352
+ * Defaults to reading x-forwarded-for → x-real-ip → "unknown".
2353
+ */
2354
+ keyExtractor?: (request: Request) => string;
2355
+ /**
2356
+ * Custom response factory called when a limit is exceeded.
2357
+ * Defaults to a JSON 429 response with Retry-After header.
2358
+ */
2359
+ onLimit?: (request: Request, retryAfter: number) => Response;
2360
+ }
2361
+ declare function rateLimit(config?: RateLimitConfig$1): KavachPlugin;
2362
+
1815
2363
  /**
1816
2364
  * In-memory sliding window rate limiter for auth endpoints.
1817
2365
  *
@@ -2118,6 +2666,55 @@ declare function createSiweModule(config: SiweConfig): SiweModule;
2118
2666
 
2119
2667
  declare function siwe(config: SiweConfig): KavachPlugin;
2120
2668
 
2669
+ /**
2670
+ * Cloudflare KV rate limit store.
2671
+ *
2672
+ * Each key stores a JSON object { count, resetAt } with a TTL so Cloudflare
2673
+ * automatically evicts expired windows without any extra cleanup logic.
2674
+ *
2675
+ * The KV namespace is passed in at construction time so this module remains
2676
+ * free of any Cloudflare-specific imports (it only uses the KV interface that
2677
+ * Workers expose at runtime).
2678
+ */
2679
+
2680
+ /** Minimal KV namespace interface — compatible with Cloudflare Workers KVNamespace */
2681
+ interface KVNamespace {
2682
+ get(key: string): Promise<string | null>;
2683
+ put(key: string, value: string, options?: {
2684
+ expirationTtl?: number;
2685
+ }): Promise<void>;
2686
+ delete(key: string): Promise<void>;
2687
+ }
2688
+ declare class KVStore implements RateLimitStore {
2689
+ private readonly kv;
2690
+ constructor(kv: KVNamespace);
2691
+ increment(key: string, windowMs: number): Promise<{
2692
+ count: number;
2693
+ resetAt: number;
2694
+ }>;
2695
+ reset(key: string): Promise<void>;
2696
+ }
2697
+ /** Factory function to create a KVStore from a KV namespace binding */
2698
+ declare function kvStore(kv: KVNamespace): KVStore;
2699
+
2700
+ /**
2701
+ * In-memory rate limit store.
2702
+ *
2703
+ * Uses a Map keyed by a caller-supplied string. Each entry tracks the current
2704
+ * hit count and the unix timestamp (ms) at which the window resets. Expired
2705
+ * windows are reset on the next increment so memory stays bounded without
2706
+ * needing a background sweep.
2707
+ */
2708
+
2709
+ declare class MemoryStore implements RateLimitStore {
2710
+ private readonly entries;
2711
+ increment(key: string, windowMs: number): Promise<{
2712
+ count: number;
2713
+ resetAt: number;
2714
+ }>;
2715
+ reset(key: string): Promise<void>;
2716
+ }
2717
+
2121
2718
  /**
2122
2719
  * Stripe payment integration for KavachOS.
2123
2720
  *
@@ -2254,4 +2851,4 @@ declare function createTrustedDeviceModule(config: TrustedDeviceConfig, db: Data
2254
2851
  */
2255
2852
  declare function deviceLabelFromRequest(request: Request): string;
2256
2853
 
2257
- export { type AccessTokenClaims, type AdditionalFieldsConfig, type AdditionalFieldsModule, AdminConfig, type AnonymousAuthConfig, type AnonymousAuthModule, ApiKeyManagerConfig, AuthAdapter, type AuthorizeParams, type BearerAuthOptions, type BudgetCheckResult, type CheckParams, type CheckResult, type CheckoutOptions, type CostAlert, type CostAttributionConfig, type CostAttributionModule, type CostReport, type CreateEphemeralSessionInput, type CustomSessionConfig, type CustomSessionModule, type DeleteOptions, type DeleteResult, type DeviceAuthConfig, type DeviceAuthModule, type DeviceAuthStatus, type DeviceCodeResponse, EVENT_TYPES, EmailOtpConfig, type EndpointGroup, type EphemeralSession, type EphemeralSessionConfig, type EphemeralSessionModule, type EphemeralSessionValidateResult, type EventStreamConfig, type EventStreamModule, type EventType, type ExpandParams, type FederatedAgent, type FederationConfig, type FederationModule, type FederationToken, type FederationWellKnown, type FieldDefinition, type GdprModule, type GetUserClaimsFn, type GoogleUser, type HeaderAuthOptions, HibpApiError, HibpBreachedError, type HibpConfig, type HibpModule, type InstanceIdentity, type IssueFederationTokenInput, type JsonWebKeySet, type JwtSessionConfig, type JwtSessionModule, type LastLoginConfig, type LastLoginModule, type ListObjectsParams, type ListSubjectsParams, type LoginEvent, type LoginMethod, MagicLinkConfig, type OAuthProxyConfig, OAuthProxyError, type OAuthProxyModule, type OAuthProxyPluginConfig, type OidcClient, type OidcDiscoveryDocument, type OidcProviderConfig, type OidcProviderModule, type OneTapConfig, type OneTapModule, OneTapVerifyError, type OpenApiComponents, type OpenApiConfig, type OpenApiDocument, type OpenApiInfo, type OpenApiMediaType, type OpenApiModule, type OpenApiOperation, type OpenApiParameter, type OpenApiPathItem, type OpenApiRequestBody, type OpenApiResponse, type OpenApiSchema, type OpenApiSecurityRequirement, type OpenApiSecurityScheme, type OpenApiServer, OrgConfig, PasskeyConfig, type PermissionRuleSet, type PolarConfig, type PolarModule, type PolarSubscription, type ProxyTokens, type RateLimitConfig, type RateLimitMiddlewareOptions, type RateLimitResult, type RateLimiter, type ReBACConfig, type ReBACModule, type RecordCostInput, type RecordLoginInput, type RegisterClientInput, type Relationship, ResolvedUser, type ResourceNode, type ScimConfig, type ScimGroup, type ScimModule, type ScimUser, type SessionTokens, type SessionUser, type SiweConfig, type SiweModule, type SiweVerifyResult, type StreamEvent, type StripeConfig, type StripeModule, type SubscriptionInfo, type TokenParams, type TokenResponse, TotpConfig, type TrustLevel, type TrustedDevice, type TrustedDeviceConfig, type TrustedDeviceModule, type TrustedInstance, type TwoFactorConfig, type UserDataExport, type UserInfoClaims, type ValidationResult, type VerifiedSession, additionalFields, admin, anonymousAuth, apiKeys, bearerAuth, createAdditionalFieldsModule, createAnonymousAuthModule, createCostAttributionModule, createCustomSessionModule, createDeviceAuthModule, createEphemeralSessionModule, createEventStreamModule, createFederationModule, createGdprModule, createHibpModule, createJwtSessionModule, createLastLoginModule, createOAuthProxyModule, createOidcProviderModule, createOneTapModule, createOpenApiModule, createPolarModule, createRateLimiter, createReBACModule, createScimModule, createSiweModule, createStripeModule, createTrustedDeviceModule, customAuth, customSession, deviceAuth, deviceLabelFromRequest, emailOtp, gdpr, headerAuth, magicLink, oauthProxy, oneTap, organization, passkey, polar, scim, siwe, stripe, twoFactor, withRateLimit };
2854
+ export { type AccessTokenClaims, type AdditionalFieldsConfig, type AdditionalFieldsModule, AdminConfig, type AnonymousAuthConfig, type AnonymousAuthModule, ApiKeyManagerConfig, AuthAdapter, type AuthorizeParams, type BearerAuthOptions, type BudgetCheckResult, type CheckParams, type CheckResult, type CheckoutOptions, type CostAlert, type CostAttributionConfig, type CostAttributionModule, type CostReport, type CreateEphemeralSessionInput, type CustomSessionConfig, type CustomSessionModule, type DeleteOptions, type DeleteResult, type DeviceAuthConfig, type DeviceAuthModule, type DeviceAuthStatus, type DeviceCodeResponse, EVENT_TYPES, EmailOtpConfig, type EndpointGroup, type EndpointLimit, type EphemeralSession, type EphemeralSessionConfig, type EphemeralSessionModule, type EphemeralSessionValidateResult, type EventStreamConfig, type EventStreamModule, type EventType, type ExpandParams, type FederatedAgent, type FederationConfig, type FederationModule, type FederationToken, type FederationWellKnown, type FieldDefinition, type GdprModule, type GetUserClaimsFn, type GoogleUser, type HeaderAuthOptions, HibpApiError, HibpBreachedError, type HibpConfig, type HibpModule, type InstanceIdentity, type IssueFederationTokenInput, type JsonWebKeySet, type JwtSessionConfig, type JwtSessionModule, type KVNamespace, KVStore, type LastLoginConfig, type LastLoginModule, type ListObjectsParams, type ListSubjectsParams, type LoginEvent, type LoginMethod, MagicLinkConfig, MemoryStore, type OAuthAccount, type OAuthCallbackResult, type OAuthModule, type OAuthModuleConfig, type OAuthPluginConfig, type OAuthProvider, type OAuthProviderConfig, type OAuthProxyConfig, OAuthProxyError, type OAuthProxyModule, type OAuthProxyPluginConfig, type OAuthTokens, type OAuthUserInfo, type OidcClient, type OidcDiscoveryDocument, type OidcProviderConfig, type OidcProviderModule, type OneTapConfig, type OneTapModule, OneTapVerifyError, type OpenApiComponents, type OpenApiConfig, type OpenApiDocument, type OpenApiInfo, type OpenApiMediaType, type OpenApiModule, type OpenApiOperation, type OpenApiParameter, type OpenApiPathItem, type OpenApiRequestBody, type OpenApiResponse, type OpenApiSchema, type OpenApiSecurityRequirement, type OpenApiSecurityScheme, type OpenApiServer, OrgConfig, PasskeyConfig, type PermissionRuleSet, type PolarConfig, type PolarModule, type PolarSubscription, type ProxyTokens, type RateLimitConfig, type RateLimitMiddlewareOptions, type RateLimitConfig$1 as RateLimitPluginConfig, type RateLimitResult, type RateLimitStore, type RateLimiter, type ReBACConfig, type ReBACModule, type RecordCostInput, type RecordLoginInput, type RegisterClientInput, type Relationship, ResolvedUser, type ResourceNode, type ScimConfig, type ScimGroup, type ScimModule, type ScimUser, type SessionTokens, type SessionUser, type SiweConfig, type SiweModule, type SiweVerifyResult, type StreamEvent, type StripeConfig, type StripeModule, type SubscriptionInfo, type TokenParams, type TokenResponse, TotpConfig, type TrustLevel, type TrustedDevice, type TrustedDeviceConfig, type TrustedDeviceModule, type TrustedInstance, type TwoFactorConfig, type UserDataExport, type UserInfoClaims, type ValidationResult, type VerifiedSession, additionalFields, admin, anonymousAuth, apiKeys, bearerAuth, createAdditionalFieldsModule, createAnonymousAuthModule, createAppleProvider, createCostAttributionModule, createCustomSessionModule, createDeviceAuthModule, createDiscordProvider, createEphemeralSessionModule, createEventStreamModule, createFederationModule, createGdprModule, createGithubProvider, createGitlabProvider, createGoogleProvider, createHibpModule, createJwtSessionModule, createLastLoginModule, createLinkedInProvider, createMicrosoftProvider, createOAuthModule, createOAuthProxyModule, createOidcProviderModule, createOneTapModule, createOpenApiModule, createPolarModule, createRateLimiter, createReBACModule, createScimModule, createSiweModule, createSlackProvider, createStripeModule, createTrustedDeviceModule, createTwitterProvider, customAuth, customSession, deviceAuth, deviceLabelFromRequest, emailOtp, gdpr, headerAuth, kvStore, magicLink, oauth, oauthProxy, oneTap, organization, passkey, polar, rateLimit, scim, siwe, stripe, twoFactor, withRateLimit };