kavachos 0.2.1 → 0.4.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.
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { eq, like, sql, and, lt, gte, lte, desc, asc, gt, inArray, or, notInArra
2
2
  export { and, eq, like } from 'drizzle-orm';
3
3
  import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
4
4
  import * as jose2 from 'jose';
5
- import { jwtVerify, generateKeyPair, exportJWK, importJWK, SignJWT, decodeJwt, createRemoteJWKSet, errors, compactVerify } from 'jose';
5
+ import { jwtVerify, generateKeyPair, exportJWK, importJWK, SignJWT, decodeJwt, createRemoteJWKSet, CompactSign, errors, compactVerify } from 'jose';
6
6
  import { z } from 'zod';
7
7
  import { deflateRaw } from 'zlib';
8
8
 
@@ -319,6 +319,8 @@ var permissions = sqliteTable("kavach_permissions", {
319
319
  actions: text("actions", { mode: "json" }).notNull().$type(),
320
320
  // ["read", "write", "execute"]
321
321
  constraints: text("constraints", { mode: "json" }).$type(),
322
+ // When set, the policy engine consults the ReBAC graph for this permission.
323
+ relation: text("relation"),
322
324
  createdAt: integer("created_at", { mode: "timestamp" }).notNull()
323
325
  });
324
326
  var delegationChains = sqliteTable("kavach_delegation_chains", {
@@ -348,6 +350,8 @@ var auditLogs = sqliteTable("kavach_audit_logs", {
348
350
  tokensCost: integer("tokens_cost"),
349
351
  ip: text("ip"),
350
352
  userAgent: text("user_agent"),
353
+ // True when this audit row corresponds to a policy-engine cache-hit evaluation.
354
+ cacheHit: integer("cache_hit", { mode: "boolean" }).notNull().default(false),
351
355
  timestamp: integer("timestamp", { mode: "timestamp" }).notNull()
352
356
  });
353
357
  var rateLimits = sqliteTable("kavach_rate_limits", {
@@ -4844,6 +4848,77 @@ var HibpApiError = class extends Error {
4844
4848
  this.name = "HibpApiError";
4845
4849
  }
4846
4850
  };
4851
+
4852
+ // src/standards/claims.ts
4853
+ var AGENTIC_JWT_CLAIMS = {
4854
+ /**
4855
+ * Stable identifier of the agent making the call.
4856
+ *
4857
+ * @see draft-goswami-agentic-jwt-00 §3.1
4858
+ */
4859
+ AGENT_ID: "agent_id",
4860
+ /**
4861
+ * Operational mode of the agent: `autonomous`, `delegated`, or `supervised`.
4862
+ *
4863
+ * @see draft-goswami-agentic-jwt-00 §3.2
4864
+ */
4865
+ AGENT_TYPE: "agent_type",
4866
+ /**
4867
+ * Subject principal the agent is acting on behalf of (human user or upstream agent).
4868
+ *
4869
+ * @see draft-goswami-agentic-jwt-00 §3.3
4870
+ */
4871
+ ON_BEHALF_OF: "on_behalf_of",
4872
+ /**
4873
+ * Actor claim per RFC 8693. Identifies the current actor in an
4874
+ * impersonation or delegation chain.
4875
+ *
4876
+ * @see draft-goswami-agentic-jwt-00 §3.4
4877
+ * @see RFC 8693
4878
+ */
4879
+ ACT: "act",
4880
+ /**
4881
+ * Authorized future actors for delegation chains (RFC 8693 `may_act`).
4882
+ *
4883
+ * @see draft-goswami-agentic-jwt-00 §3.5
4884
+ * @see RFC 8693
4885
+ */
4886
+ MAY_ACT: "may_act",
4887
+ /**
4888
+ * Trust score band at token issuance (e.g. `standard`, `elevated`).
4889
+ *
4890
+ * @see draft-goswami-agentic-jwt-00 §3.6
4891
+ */
4892
+ TRUST_TIER: "trust_tier",
4893
+ /**
4894
+ * Correlation id for tracing this token back to an entry in the audit log.
4895
+ *
4896
+ * @see draft-goswami-agentic-jwt-00 §3.7
4897
+ */
4898
+ AUDIT_REF: "audit_ref",
4899
+ /**
4900
+ * Per-tool budget or rate constraints encoded as a structured object.
4901
+ *
4902
+ * @see draft-goswami-agentic-jwt-00 §3.8
4903
+ */
4904
+ TOOL_CONSTRAINTS: "tool_constraints",
4905
+ /**
4906
+ * Workload Identity Token (WIT). Present only when three-layer cryptographic
4907
+ * binding is active (draft-liu §4.2). Absent in standard issuance paths.
4908
+ *
4909
+ * @see draft-liu-agent-operation-authorization-01 §4.2
4910
+ * TODO(v3): populate from WIT issuance when three-layer binding is implemented.
4911
+ */
4912
+ WORKLOAD_BINDING: "wit",
4913
+ /**
4914
+ * The scoped operation this token authorizes (e.g. `read:documents`).
4915
+ *
4916
+ * @see draft-liu-agent-operation-authorization-01 §4.3
4917
+ */
4918
+ OPERATION: "operation"
4919
+ };
4920
+
4921
+ // src/auth/jwt-session.ts
4847
4922
  var configSchema = z.object({
4848
4923
  secret: z.union([z.string().min(1), z.instanceof(Object)]),
4849
4924
  algorithm: z.string().optional(),
@@ -4924,6 +4999,18 @@ function createJwtSessionModule(config, db) {
4924
4999
  });
4925
5000
  Object.assign(claimsFromUser, extra);
4926
5001
  }
5002
+ if (config.emitAgenticJwtClaims === true && user.agenticContext !== void 0) {
5003
+ const ac = user.agenticContext;
5004
+ if (ac.agentId !== void 0) {
5005
+ claimsFromUser[AGENTIC_JWT_CLAIMS.AGENT_ID] = ac.agentId;
5006
+ }
5007
+ if (ac.agentType !== void 0) {
5008
+ claimsFromUser[AGENTIC_JWT_CLAIMS.AGENT_TYPE] = ac.agentType;
5009
+ }
5010
+ if (ac.trustTier !== void 0) {
5011
+ claimsFromUser[AGENTIC_JWT_CLAIMS.TRUST_TIER] = ac.trustTier;
5012
+ }
5013
+ }
4927
5014
  let builder = new SignJWT({
4928
5015
  sub: user.id,
4929
5016
  ...user.email !== void 0 ? { email: user.email } : {},
@@ -5954,7 +6041,8 @@ var AUTHORIZATION_URL2 = "https://discord.com/api/oauth2/authorize";
5954
6041
  var TOKEN_URL2 = "https://discord.com/api/oauth2/token";
5955
6042
  var USER_INFO_URL = "https://discord.com/api/users/@me";
5956
6043
  var CDN_BASE = "https://cdn.discordapp.com";
5957
- var DEFAULT_SCOPES2 = ["identify", "email"];
6044
+ var DEFAULT_DISCORD_SCOPES = ["identify", "email"];
6045
+ var DEFAULT_SCOPES2 = DEFAULT_DISCORD_SCOPES;
5958
6046
  function createDiscordProvider(config) {
5959
6047
  const scopes = mergeScopes2(DEFAULT_SCOPES2, config.scopes);
5960
6048
  async function getAuthorizationUrl(state, codeVerifier, redirectUri) {
@@ -6555,7 +6643,8 @@ function mergeScopes7(defaults, extras) {
6555
6643
  var AUTHORIZATION_URL8 = "https://slack.com/oauth/v2/authorize";
6556
6644
  var TOKEN_URL8 = "https://slack.com/api/oauth.v2.access";
6557
6645
  var USER_INFO_URL6 = "https://slack.com/api/openid.connect.userInfo";
6558
- var DEFAULT_SCOPES8 = ["openid", "profile", "email"];
6646
+ var DEFAULT_SLACK_SCOPES = ["openid", "profile", "email"];
6647
+ var DEFAULT_SCOPES8 = DEFAULT_SLACK_SCOPES;
6559
6648
  function createSlackProvider(config) {
6560
6649
  const scopes = mergeScopes8(DEFAULT_SCOPES8, config.scopes);
6561
6650
  async function getAuthorizationUrl(state, codeVerifier, redirectUri) {
@@ -15430,6 +15519,70 @@ function createDatabaseSync(config) {
15430
15519
  }
15431
15520
 
15432
15521
  // src/db/migrations.ts
15522
+ var ALL_FEATURES_ENABLED = {
15523
+ core: true,
15524
+ session: true,
15525
+ agent: true,
15526
+ audit: true,
15527
+ oauth: true,
15528
+ tenant: true,
15529
+ mcp: true,
15530
+ org: true,
15531
+ rateLimit: true,
15532
+ budget: true,
15533
+ magicLink: true,
15534
+ emailOtp: true,
15535
+ totp: true,
15536
+ passkey: true,
15537
+ sso: true,
15538
+ apiKey: true,
15539
+ username: true,
15540
+ phone: true,
15541
+ device: true,
15542
+ oneTimeToken: true,
15543
+ loginHistory: true,
15544
+ oidcProvider: true,
15545
+ jwt: true,
15546
+ rebac: true,
15547
+ federation: true
15548
+ };
15549
+ function resolveEnabledFeatures(config) {
15550
+ if (!config) {
15551
+ return ALL_FEATURES_ENABLED;
15552
+ }
15553
+ const hasAgents = !!config.agents || !!config.did;
15554
+ const hasSession = !!config.auth?.session;
15555
+ const hasOAuth = config.plugins?.some((p2) => p2.id === "kavach-oauth") ?? false;
15556
+ const hasOidc = config.plugins?.some((p2) => p2.id === "kavach-oidc-provider") ?? false;
15557
+ return {
15558
+ core: true,
15559
+ session: hasSession,
15560
+ agent: hasAgents,
15561
+ audit: hasAgents,
15562
+ oauth: hasOAuth,
15563
+ tenant: hasAgents,
15564
+ mcp: !!config.mcp,
15565
+ org: !!config.org,
15566
+ rateLimit: hasAgents,
15567
+ budget: hasAgents,
15568
+ magicLink: !!config.magicLink,
15569
+ emailOtp: !!config.emailOtp,
15570
+ totp: !!config.totp,
15571
+ passkey: !!config.passkey,
15572
+ sso: !!config.sso,
15573
+ apiKey: !!config.apiKeys,
15574
+ username: !!config.username,
15575
+ phone: !!config.phone,
15576
+ device: hasSession,
15577
+ oneTimeToken: !!config.magicLink || !!config.emailOtp || !!config.passwordReset,
15578
+ loginHistory: hasSession,
15579
+ oidcProvider: hasOidc,
15580
+ jwt: hasSession,
15581
+ rebac: hasAgents,
15582
+ federation: false
15583
+ // only when explicitly configured (no config key yet)
15584
+ };
15585
+ }
15433
15586
  function buildStatements(provider) {
15434
15587
  const isPostgres = provider === "postgres";
15435
15588
  const isMysql = provider === "mysql";
@@ -15442,7 +15595,9 @@ function buildStatements(provider) {
15442
15595
  // ------------------------------------------------------------------
15443
15596
  // kavach_users
15444
15597
  // ------------------------------------------------------------------
15445
- `CREATE TABLE ${ifne} kavach_users (
15598
+ {
15599
+ feature: "core",
15600
+ sql: `CREATE TABLE ${ifne} kavach_users (
15446
15601
  id TEXT NOT NULL PRIMARY KEY,
15447
15602
  email TEXT NOT NULL UNIQUE,
15448
15603
  username TEXT UNIQUE,
@@ -15469,11 +15624,14 @@ function buildStatements(provider) {
15469
15624
  polar_cancel_at_period_end ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
15470
15625
  created_at ${ts} NOT NULL,
15471
15626
  updated_at ${ts} NOT NULL
15472
- )`,
15627
+ )`
15628
+ },
15473
15629
  // ------------------------------------------------------------------
15474
15630
  // kavach_tenants (must come before kavach_agents – agents FK to tenants)
15475
15631
  // ------------------------------------------------------------------
15476
- `CREATE TABLE ${ifne} kavach_tenants (
15632
+ {
15633
+ feature: "tenant",
15634
+ sql: `CREATE TABLE ${ifne} kavach_tenants (
15477
15635
  id TEXT NOT NULL PRIMARY KEY,
15478
15636
  name TEXT NOT NULL,
15479
15637
  slug TEXT NOT NULL UNIQUE,
@@ -15481,11 +15639,14 @@ function buildStatements(provider) {
15481
15639
  status TEXT NOT NULL DEFAULT 'active',
15482
15640
  created_at ${ts} NOT NULL,
15483
15641
  updated_at ${ts} NOT NULL
15484
- )`,
15642
+ )`
15643
+ },
15485
15644
  // ------------------------------------------------------------------
15486
15645
  // kavach_agents
15487
15646
  // ------------------------------------------------------------------
15488
- `CREATE TABLE ${ifne} kavach_agents (
15647
+ {
15648
+ feature: "agent",
15649
+ sql: `CREATE TABLE ${ifne} kavach_agents (
15489
15650
  id TEXT NOT NULL PRIMARY KEY,
15490
15651
  owner_id TEXT NOT NULL REFERENCES kavach_users(id),
15491
15652
  tenant_id TEXT REFERENCES kavach_tenants(id),
@@ -15499,22 +15660,29 @@ function buildStatements(provider) {
15499
15660
  metadata ${json2},
15500
15661
  created_at ${ts} NOT NULL,
15501
15662
  updated_at ${ts} NOT NULL
15502
- )`,
15663
+ )`
15664
+ },
15503
15665
  // ------------------------------------------------------------------
15504
15666
  // kavach_permissions
15505
15667
  // ------------------------------------------------------------------
15506
- `CREATE TABLE ${ifne} kavach_permissions (
15668
+ {
15669
+ feature: "agent",
15670
+ sql: `CREATE TABLE ${ifne} kavach_permissions (
15507
15671
  id TEXT NOT NULL PRIMARY KEY,
15508
15672
  agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
15509
15673
  resource TEXT NOT NULL,
15510
15674
  actions ${json2} NOT NULL,
15511
15675
  constraints ${json2},
15676
+ relation TEXT,
15512
15677
  created_at ${ts} NOT NULL
15513
- )`,
15678
+ )`
15679
+ },
15514
15680
  // ------------------------------------------------------------------
15515
15681
  // kavach_delegation_chains
15516
15682
  // ------------------------------------------------------------------
15517
- `CREATE TABLE ${ifne} kavach_delegation_chains (
15683
+ {
15684
+ feature: "agent",
15685
+ sql: `CREATE TABLE ${ifne} kavach_delegation_chains (
15518
15686
  id TEXT NOT NULL PRIMARY KEY,
15519
15687
  from_agent_id TEXT NOT NULL REFERENCES kavach_agents(id),
15520
15688
  to_agent_id TEXT NOT NULL REFERENCES kavach_agents(id),
@@ -15524,11 +15692,14 @@ function buildStatements(provider) {
15524
15692
  status TEXT NOT NULL DEFAULT 'active',
15525
15693
  expires_at ${ts} NOT NULL,
15526
15694
  created_at ${ts} NOT NULL
15527
- )`,
15695
+ )`
15696
+ },
15528
15697
  // ------------------------------------------------------------------
15529
15698
  // kavach_audit_logs
15530
15699
  // ------------------------------------------------------------------
15531
- `CREATE TABLE ${ifne} kavach_audit_logs (
15700
+ {
15701
+ feature: "audit",
15702
+ sql: `CREATE TABLE ${ifne} kavach_audit_logs (
15532
15703
  id TEXT NOT NULL PRIMARY KEY,
15533
15704
  agent_id TEXT NOT NULL REFERENCES kavach_agents(id),
15534
15705
  user_id TEXT NOT NULL REFERENCES kavach_users(id),
@@ -15541,22 +15712,29 @@ function buildStatements(provider) {
15541
15712
  tokens_cost INTEGER,
15542
15713
  ip TEXT,
15543
15714
  user_agent TEXT,
15715
+ cache_hit ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
15544
15716
  timestamp ${ts} NOT NULL
15545
- )`,
15717
+ )`
15718
+ },
15546
15719
  // ------------------------------------------------------------------
15547
15720
  // kavach_rate_limits
15548
15721
  // ------------------------------------------------------------------
15549
- `CREATE TABLE ${ifne} kavach_rate_limits (
15722
+ {
15723
+ feature: "rateLimit",
15724
+ sql: `CREATE TABLE ${ifne} kavach_rate_limits (
15550
15725
  id TEXT NOT NULL PRIMARY KEY,
15551
15726
  agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
15552
15727
  resource TEXT NOT NULL,
15553
15728
  window_start ${ts} NOT NULL,
15554
15729
  count INTEGER NOT NULL DEFAULT 0
15555
- )`,
15730
+ )`
15731
+ },
15556
15732
  // ------------------------------------------------------------------
15557
15733
  // kavach_mcp_servers
15558
15734
  // ------------------------------------------------------------------
15559
- `CREATE TABLE ${ifne} kavach_mcp_servers (
15735
+ {
15736
+ feature: "mcp",
15737
+ sql: `CREATE TABLE ${ifne} kavach_mcp_servers (
15560
15738
  id TEXT NOT NULL PRIMARY KEY,
15561
15739
  name TEXT NOT NULL,
15562
15740
  endpoint TEXT NOT NULL UNIQUE,
@@ -15566,21 +15744,27 @@ function buildStatements(provider) {
15566
15744
  status TEXT NOT NULL DEFAULT 'active',
15567
15745
  created_at ${ts} NOT NULL,
15568
15746
  updated_at ${ts} NOT NULL
15569
- )`,
15747
+ )`
15748
+ },
15570
15749
  // ------------------------------------------------------------------
15571
15750
  // kavach_sessions
15572
15751
  // ------------------------------------------------------------------
15573
- `CREATE TABLE ${ifne} kavach_sessions (
15752
+ {
15753
+ feature: "session",
15754
+ sql: `CREATE TABLE ${ifne} kavach_sessions (
15574
15755
  id TEXT NOT NULL PRIMARY KEY,
15575
15756
  user_id TEXT NOT NULL REFERENCES kavach_users(id),
15576
15757
  expires_at ${ts} NOT NULL,
15577
15758
  metadata ${json2},
15578
15759
  created_at ${ts} NOT NULL
15579
- )`,
15760
+ )`
15761
+ },
15580
15762
  // ------------------------------------------------------------------
15581
15763
  // kavach_oauth_clients
15582
15764
  // ------------------------------------------------------------------
15583
- `CREATE TABLE ${ifne} kavach_oauth_clients (
15765
+ {
15766
+ feature: "oauth",
15767
+ sql: `CREATE TABLE ${ifne} kavach_oauth_clients (
15584
15768
  id TEXT NOT NULL PRIMARY KEY,
15585
15769
  client_id TEXT NOT NULL UNIQUE,
15586
15770
  client_secret TEXT,
@@ -15595,11 +15779,14 @@ function buildStatements(provider) {
15595
15779
  metadata ${json2},
15596
15780
  created_at ${ts} NOT NULL,
15597
15781
  updated_at ${ts} NOT NULL
15598
- )`,
15782
+ )`
15783
+ },
15599
15784
  // ------------------------------------------------------------------
15600
15785
  // kavach_oauth_access_tokens
15601
15786
  // ------------------------------------------------------------------
15602
- `CREATE TABLE ${ifne} kavach_oauth_access_tokens (
15787
+ {
15788
+ feature: "oauth",
15789
+ sql: `CREATE TABLE ${ifne} kavach_oauth_access_tokens (
15603
15790
  id TEXT NOT NULL PRIMARY KEY,
15604
15791
  access_token TEXT NOT NULL UNIQUE,
15605
15792
  refresh_token TEXT UNIQUE,
@@ -15610,11 +15797,14 @@ function buildStatements(provider) {
15610
15797
  access_token_expires_at ${ts} NOT NULL,
15611
15798
  refresh_token_expires_at ${tsNull},
15612
15799
  created_at ${ts} NOT NULL
15613
- )`,
15800
+ )`
15801
+ },
15614
15802
  // ------------------------------------------------------------------
15615
15803
  // kavach_oauth_authorization_codes
15616
15804
  // ------------------------------------------------------------------
15617
- `CREATE TABLE ${ifne} kavach_oauth_authorization_codes (
15805
+ {
15806
+ feature: "oauth",
15807
+ sql: `CREATE TABLE ${ifne} kavach_oauth_authorization_codes (
15618
15808
  id TEXT NOT NULL PRIMARY KEY,
15619
15809
  code TEXT NOT NULL UNIQUE,
15620
15810
  client_id TEXT NOT NULL REFERENCES kavach_oauth_clients(client_id),
@@ -15626,11 +15816,14 @@ function buildStatements(provider) {
15626
15816
  resource TEXT,
15627
15817
  expires_at ${ts} NOT NULL,
15628
15818
  created_at ${ts} NOT NULL
15629
- )`,
15819
+ )`
15820
+ },
15630
15821
  // ------------------------------------------------------------------
15631
15822
  // kavach_oauth_accounts (provider account linking)
15632
15823
  // ------------------------------------------------------------------
15633
- `CREATE TABLE ${ifne} kavach_oauth_accounts (
15824
+ {
15825
+ feature: "oauth",
15826
+ sql: `CREATE TABLE ${ifne} kavach_oauth_accounts (
15634
15827
  id TEXT NOT NULL PRIMARY KEY,
15635
15828
  user_id TEXT NOT NULL,
15636
15829
  provider TEXT NOT NULL,
@@ -15640,22 +15833,28 @@ function buildStatements(provider) {
15640
15833
  expires_at ${tsNull},
15641
15834
  created_at ${ts} NOT NULL,
15642
15835
  updated_at ${ts} NOT NULL
15643
- )`,
15836
+ )`
15837
+ },
15644
15838
  // ------------------------------------------------------------------
15645
15839
  // kavach_oauth_states (PKCE state for CSRF protection)
15646
15840
  // ------------------------------------------------------------------
15647
- `CREATE TABLE ${ifne} kavach_oauth_states (
15841
+ {
15842
+ feature: "oauth",
15843
+ sql: `CREATE TABLE ${ifne} kavach_oauth_states (
15648
15844
  state TEXT NOT NULL PRIMARY KEY,
15649
15845
  code_verifier TEXT NOT NULL,
15650
15846
  redirect_uri TEXT NOT NULL,
15651
15847
  provider TEXT NOT NULL,
15652
15848
  expires_at ${ts} NOT NULL,
15653
15849
  created_at ${ts} NOT NULL
15654
- )`,
15850
+ )`
15851
+ },
15655
15852
  // ------------------------------------------------------------------
15656
15853
  // kavach_budget_policies
15657
15854
  // ------------------------------------------------------------------
15658
- `CREATE TABLE ${ifne} kavach_budget_policies (
15855
+ {
15856
+ feature: "budget",
15857
+ sql: `CREATE TABLE ${ifne} kavach_budget_policies (
15659
15858
  id TEXT NOT NULL PRIMARY KEY,
15660
15859
  agent_id TEXT REFERENCES kavach_agents(id) ON DELETE CASCADE,
15661
15860
  user_id TEXT REFERENCES kavach_users(id),
@@ -15665,11 +15864,14 @@ function buildStatements(provider) {
15665
15864
  action TEXT NOT NULL DEFAULT 'warn',
15666
15865
  status TEXT NOT NULL DEFAULT 'active',
15667
15866
  created_at ${ts} NOT NULL
15668
- )`,
15867
+ )`
15868
+ },
15669
15869
  // ------------------------------------------------------------------
15670
15870
  // kavach_agent_cards (A2A discovery)
15671
15871
  // ------------------------------------------------------------------
15672
- `CREATE TABLE ${ifne} kavach_agent_cards (
15872
+ {
15873
+ feature: "agent",
15874
+ sql: `CREATE TABLE ${ifne} kavach_agent_cards (
15673
15875
  id TEXT NOT NULL PRIMARY KEY,
15674
15876
  agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
15675
15877
  name TEXT NOT NULL,
@@ -15682,11 +15884,14 @@ function buildStatements(provider) {
15682
15884
  metadata ${json2},
15683
15885
  created_at ${ts} NOT NULL,
15684
15886
  updated_at ${ts} NOT NULL
15685
- )`,
15887
+ )`
15888
+ },
15686
15889
  // ------------------------------------------------------------------
15687
15890
  // kavach_approval_requests (CIBA async approval flows)
15688
15891
  // ------------------------------------------------------------------
15689
- `CREATE TABLE ${ifne} kavach_approval_requests (
15892
+ {
15893
+ feature: "agent",
15894
+ sql: `CREATE TABLE ${ifne} kavach_approval_requests (
15690
15895
  id TEXT NOT NULL PRIMARY KEY,
15691
15896
  agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
15692
15897
  user_id TEXT NOT NULL REFERENCES kavach_users(id),
@@ -15698,21 +15903,27 @@ function buildStatements(provider) {
15698
15903
  responded_at ${tsNull},
15699
15904
  responded_by TEXT,
15700
15905
  created_at ${ts} NOT NULL
15701
- )`,
15906
+ )`
15907
+ },
15702
15908
  // ------------------------------------------------------------------
15703
15909
  // kavach_trust_scores (graduated autonomy scoring)
15704
15910
  // ------------------------------------------------------------------
15705
- `CREATE TABLE ${ifne} kavach_trust_scores (
15911
+ {
15912
+ feature: "agent",
15913
+ sql: `CREATE TABLE ${ifne} kavach_trust_scores (
15706
15914
  agent_id TEXT NOT NULL PRIMARY KEY REFERENCES kavach_agents(id) ON DELETE CASCADE,
15707
15915
  score INTEGER NOT NULL,
15708
15916
  level TEXT NOT NULL,
15709
15917
  factors ${json2} NOT NULL,
15710
15918
  computed_at ${ts} NOT NULL
15711
- )`,
15919
+ )`
15920
+ },
15712
15921
  // ------------------------------------------------------------------
15713
15922
  // kavach_organizations
15714
15923
  // ------------------------------------------------------------------
15715
- `CREATE TABLE ${ifne} kavach_organizations (
15924
+ {
15925
+ feature: "org",
15926
+ sql: `CREATE TABLE ${ifne} kavach_organizations (
15716
15927
  id TEXT NOT NULL PRIMARY KEY,
15717
15928
  name TEXT NOT NULL,
15718
15929
  slug TEXT NOT NULL UNIQUE,
@@ -15720,22 +15931,28 @@ function buildStatements(provider) {
15720
15931
  metadata ${json2},
15721
15932
  created_at ${ts} NOT NULL,
15722
15933
  updated_at ${ts} NOT NULL
15723
- )`,
15934
+ )`
15935
+ },
15724
15936
  // ------------------------------------------------------------------
15725
15937
  // kavach_org_members
15726
15938
  // ------------------------------------------------------------------
15727
- `CREATE TABLE ${ifne} kavach_org_members (
15939
+ {
15940
+ feature: "org",
15941
+ sql: `CREATE TABLE ${ifne} kavach_org_members (
15728
15942
  id TEXT NOT NULL PRIMARY KEY,
15729
15943
  org_id TEXT NOT NULL REFERENCES kavach_organizations(id) ON DELETE CASCADE,
15730
15944
  user_id TEXT NOT NULL REFERENCES kavach_users(id),
15731
15945
  role TEXT NOT NULL DEFAULT 'member',
15732
15946
  joined_at ${ts} NOT NULL,
15733
15947
  UNIQUE(org_id, user_id)
15734
- )`,
15948
+ )`
15949
+ },
15735
15950
  // ------------------------------------------------------------------
15736
15951
  // kavach_org_invitations
15737
15952
  // ------------------------------------------------------------------
15738
- `CREATE TABLE ${ifne} kavach_org_invitations (
15953
+ {
15954
+ feature: "org",
15955
+ sql: `CREATE TABLE ${ifne} kavach_org_invitations (
15739
15956
  id TEXT NOT NULL PRIMARY KEY,
15740
15957
  org_id TEXT NOT NULL REFERENCES kavach_organizations(id) ON DELETE CASCADE,
15741
15958
  email TEXT NOT NULL,
@@ -15744,21 +15961,27 @@ function buildStatements(provider) {
15744
15961
  status TEXT NOT NULL DEFAULT 'pending',
15745
15962
  expires_at ${ts} NOT NULL,
15746
15963
  created_at ${ts} NOT NULL
15747
- )`,
15964
+ )`
15965
+ },
15748
15966
  // ------------------------------------------------------------------
15749
15967
  // kavach_org_roles
15750
15968
  // ------------------------------------------------------------------
15751
- `CREATE TABLE ${ifne} kavach_org_roles (
15969
+ {
15970
+ feature: "org",
15971
+ sql: `CREATE TABLE ${ifne} kavach_org_roles (
15752
15972
  id TEXT NOT NULL PRIMARY KEY,
15753
15973
  org_id TEXT NOT NULL REFERENCES kavach_organizations(id) ON DELETE CASCADE,
15754
15974
  name TEXT NOT NULL,
15755
15975
  permissions ${json2} NOT NULL,
15756
15976
  UNIQUE(org_id, name)
15757
- )`,
15977
+ )`
15978
+ },
15758
15979
  // ------------------------------------------------------------------
15759
15980
  // kavach_passkey_credentials (WebAuthn / FIDO2 passkeys)
15760
15981
  // ------------------------------------------------------------------
15761
- `CREATE TABLE ${ifne} kavach_passkey_credentials (
15982
+ {
15983
+ feature: "passkey",
15984
+ sql: `CREATE TABLE ${ifne} kavach_passkey_credentials (
15762
15985
  id TEXT NOT NULL PRIMARY KEY,
15763
15986
  user_id TEXT NOT NULL REFERENCES kavach_users(id),
15764
15987
  credential_id TEXT NOT NULL UNIQUE,
@@ -15768,22 +15991,28 @@ function buildStatements(provider) {
15768
15991
  transports TEXT,
15769
15992
  created_at ${ts} NOT NULL,
15770
15993
  last_used_at ${ts} NOT NULL
15771
- )`,
15994
+ )`
15995
+ },
15772
15996
  // ------------------------------------------------------------------
15773
15997
  // kavach_passkey_challenges (short-lived WebAuthn challenges)
15774
15998
  // ------------------------------------------------------------------
15775
- `CREATE TABLE ${ifne} kavach_passkey_challenges (
15999
+ {
16000
+ feature: "passkey",
16001
+ sql: `CREATE TABLE ${ifne} kavach_passkey_challenges (
15776
16002
  id TEXT NOT NULL PRIMARY KEY,
15777
16003
  challenge TEXT NOT NULL UNIQUE,
15778
16004
  user_id TEXT,
15779
16005
  type TEXT NOT NULL,
15780
16006
  expires_at ${ts} NOT NULL,
15781
16007
  created_at ${ts} NOT NULL
15782
- )`,
16008
+ )`
16009
+ },
15783
16010
  // ------------------------------------------------------------------
15784
16011
  // kavach_one_time_tokens (email verify, password reset, invitation)
15785
16012
  // ------------------------------------------------------------------
15786
- `CREATE TABLE ${ifne} kavach_one_time_tokens (
16013
+ {
16014
+ feature: "oneTimeToken",
16015
+ sql: `CREATE TABLE ${ifne} kavach_one_time_tokens (
15787
16016
  id TEXT NOT NULL PRIMARY KEY,
15788
16017
  token_hash TEXT NOT NULL UNIQUE,
15789
16018
  purpose TEXT NOT NULL,
@@ -15792,55 +16021,70 @@ function buildStatements(provider) {
15792
16021
  used ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
15793
16022
  expires_at ${ts} NOT NULL,
15794
16023
  created_at ${ts} NOT NULL
15795
- )`,
16024
+ )`
16025
+ },
15796
16026
  // ------------------------------------------------------------------
15797
16027
  // kavach_agent_dids (W3C Decentralized Identifiers per agent)
15798
16028
  // ------------------------------------------------------------------
15799
- `CREATE TABLE ${ifne} kavach_agent_dids (
16029
+ {
16030
+ feature: "agent",
16031
+ sql: `CREATE TABLE ${ifne} kavach_agent_dids (
15800
16032
  agent_id TEXT NOT NULL PRIMARY KEY REFERENCES kavach_agents(id) ON DELETE CASCADE,
15801
16033
  did TEXT NOT NULL UNIQUE,
15802
16034
  method TEXT NOT NULL,
15803
16035
  public_key_jwk TEXT NOT NULL,
15804
16036
  did_document TEXT NOT NULL,
15805
16037
  created_at ${ts} NOT NULL
15806
- )`,
16038
+ )`
16039
+ },
15807
16040
  // ------------------------------------------------------------------
15808
16041
  // kavach_magic_links (passwordless email login)
15809
16042
  // ------------------------------------------------------------------
15810
- `CREATE TABLE ${ifne} kavach_magic_links (
16043
+ {
16044
+ feature: "magicLink",
16045
+ sql: `CREATE TABLE ${ifne} kavach_magic_links (
15811
16046
  id TEXT NOT NULL PRIMARY KEY,
15812
16047
  email TEXT NOT NULL,
15813
16048
  token TEXT NOT NULL UNIQUE,
15814
16049
  expires_at ${ts} NOT NULL,
15815
16050
  used ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
15816
16051
  created_at ${ts} NOT NULL
15817
- )`,
16052
+ )`
16053
+ },
15818
16054
  // ------------------------------------------------------------------
15819
16055
  // kavach_email_otps (one-time password login)
15820
16056
  // ------------------------------------------------------------------
15821
- `CREATE TABLE ${ifne} kavach_email_otps (
16057
+ {
16058
+ feature: "emailOtp",
16059
+ sql: `CREATE TABLE ${ifne} kavach_email_otps (
15822
16060
  id TEXT NOT NULL PRIMARY KEY,
15823
16061
  email TEXT NOT NULL,
15824
16062
  code_hash TEXT NOT NULL,
15825
16063
  expires_at ${ts} NOT NULL,
15826
16064
  attempts INTEGER NOT NULL DEFAULT 0,
15827
16065
  created_at ${ts} NOT NULL
15828
- )`,
16066
+ )`
16067
+ },
15829
16068
  // ------------------------------------------------------------------
15830
16069
  // kavach_totp (TOTP two-factor authentication)
15831
16070
  // ------------------------------------------------------------------
15832
- `CREATE TABLE ${ifne} kavach_totp (
16071
+ {
16072
+ feature: "totp",
16073
+ sql: `CREATE TABLE ${ifne} kavach_totp (
15833
16074
  user_id TEXT NOT NULL PRIMARY KEY REFERENCES kavach_users(id),
15834
16075
  secret TEXT NOT NULL,
15835
16076
  enabled ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
15836
16077
  backup_codes ${json2} NOT NULL,
15837
16078
  created_at ${ts} NOT NULL,
15838
16079
  updated_at ${ts} NOT NULL
15839
- )`,
16080
+ )`
16081
+ },
15840
16082
  // ------------------------------------------------------------------
15841
16083
  // kavach_sso_connections (SAML 2.0 / OIDC enterprise SSO)
15842
16084
  // ------------------------------------------------------------------
15843
- `CREATE TABLE ${ifne} kavach_sso_connections (
16085
+ {
16086
+ feature: "sso",
16087
+ sql: `CREATE TABLE ${ifne} kavach_sso_connections (
15844
16088
  id TEXT NOT NULL PRIMARY KEY,
15845
16089
  org_id TEXT NOT NULL,
15846
16090
  provider_id TEXT NOT NULL,
@@ -15848,11 +16092,14 @@ function buildStatements(provider) {
15848
16092
  domain TEXT NOT NULL UNIQUE,
15849
16093
  enabled INTEGER NOT NULL DEFAULT 1,
15850
16094
  created_at ${ts} NOT NULL
15851
- )`,
16095
+ )`
16096
+ },
15852
16097
  // ------------------------------------------------------------------
15853
16098
  // kavach_api_keys (static bearer tokens with permission scopes)
15854
16099
  // ------------------------------------------------------------------
15855
- `CREATE TABLE ${ifne} kavach_api_keys (
16100
+ {
16101
+ feature: "apiKey",
16102
+ sql: `CREATE TABLE ${ifne} kavach_api_keys (
15856
16103
  id TEXT NOT NULL PRIMARY KEY,
15857
16104
  user_id TEXT NOT NULL REFERENCES kavach_users(id),
15858
16105
  name TEXT NOT NULL,
@@ -15862,57 +16109,75 @@ function buildStatements(provider) {
15862
16109
  expires_at ${tsNull},
15863
16110
  last_used_at ${tsNull},
15864
16111
  created_at ${ts} NOT NULL
15865
- )`,
16112
+ )`
16113
+ },
15866
16114
  // ------------------------------------------------------------------
15867
16115
  // kavach_username_accounts (username + password auth)
15868
16116
  // ------------------------------------------------------------------
15869
- `CREATE TABLE ${ifne} kavach_username_accounts (
16117
+ {
16118
+ feature: "username",
16119
+ sql: `CREATE TABLE ${ifne} kavach_username_accounts (
15870
16120
  id TEXT NOT NULL PRIMARY KEY,
15871
16121
  user_id TEXT NOT NULL REFERENCES kavach_users(id) ON DELETE CASCADE,
15872
16122
  username TEXT NOT NULL UNIQUE,
15873
16123
  password_hash TEXT NOT NULL,
15874
16124
  created_at ${ts} NOT NULL,
15875
16125
  updated_at ${ts} NOT NULL
15876
- )`,
16126
+ )`
16127
+ },
15877
16128
  // ------------------------------------------------------------------
15878
16129
  // kavach_phone_verifications (SMS OTP)
15879
16130
  // ------------------------------------------------------------------
15880
- `CREATE TABLE ${ifne} kavach_phone_verifications (
16131
+ {
16132
+ feature: "phone",
16133
+ sql: `CREATE TABLE ${ifne} kavach_phone_verifications (
15881
16134
  id TEXT NOT NULL PRIMARY KEY,
15882
16135
  phone_number TEXT NOT NULL,
15883
16136
  code_hash TEXT NOT NULL,
15884
16137
  attempts INTEGER NOT NULL DEFAULT 0,
15885
16138
  expires_at ${ts} NOT NULL,
15886
16139
  created_at ${ts} NOT NULL
15887
- )`,
16140
+ )`
16141
+ },
15888
16142
  // ------------------------------------------------------------------
15889
16143
  // kavach_trusted_devices (skip 2FA on trusted devices for a window)
15890
16144
  // ------------------------------------------------------------------
15891
- `CREATE TABLE ${ifne} kavach_trusted_devices (
16145
+ {
16146
+ feature: "device",
16147
+ sql: `CREATE TABLE ${ifne} kavach_trusted_devices (
15892
16148
  id TEXT NOT NULL PRIMARY KEY,
15893
16149
  user_id TEXT NOT NULL REFERENCES kavach_users(id) ON DELETE CASCADE,
15894
16150
  fingerprint TEXT NOT NULL,
15895
16151
  label TEXT NOT NULL,
15896
16152
  trusted_at ${ts} NOT NULL,
15897
16153
  expires_at ${ts} NOT NULL
15898
- )`,
16154
+ )`
16155
+ },
15899
16156
  // ------------------------------------------------------------------
15900
16157
  // kavach_login_history (last-login method tracking per user)
15901
16158
  // ------------------------------------------------------------------
15902
- `CREATE TABLE ${ifne} kavach_login_history (
16159
+ {
16160
+ feature: "loginHistory",
16161
+ sql: `CREATE TABLE ${ifne} kavach_login_history (
15903
16162
  id TEXT NOT NULL PRIMARY KEY,
15904
16163
  user_id TEXT NOT NULL REFERENCES kavach_users(id) ON DELETE CASCADE,
15905
16164
  method TEXT NOT NULL,
15906
16165
  ip TEXT,
15907
16166
  user_agent TEXT,
15908
16167
  timestamp ${ts} NOT NULL
15909
- )`,
15910
- `CREATE INDEX ${ifne} kavach_login_history_user_ts
15911
- ON kavach_login_history (user_id, timestamp DESC)`,
16168
+ )`
16169
+ },
16170
+ {
16171
+ feature: "loginHistory",
16172
+ sql: `CREATE INDEX ${ifne} kavach_login_history_user_ts
16173
+ ON kavach_login_history (user_id, timestamp DESC)`
16174
+ },
15912
16175
  // ------------------------------------------------------------------
15913
16176
  // kavach_oidc_clients (OIDC Provider — registered relying parties)
15914
16177
  // ------------------------------------------------------------------
15915
- `CREATE TABLE ${ifne} kavach_oidc_clients (
16178
+ {
16179
+ feature: "oidcProvider",
16180
+ sql: `CREATE TABLE ${ifne} kavach_oidc_clients (
15916
16181
  id TEXT NOT NULL PRIMARY KEY,
15917
16182
  client_id TEXT NOT NULL UNIQUE,
15918
16183
  client_secret_hash TEXT NOT NULL,
@@ -15924,11 +16189,14 @@ function buildStatements(provider) {
15924
16189
  token_endpoint_auth_method TEXT NOT NULL DEFAULT 'client_secret_post',
15925
16190
  created_at ${ts} NOT NULL,
15926
16191
  updated_at ${ts} NOT NULL
15927
- )`,
16192
+ )`
16193
+ },
15928
16194
  // ------------------------------------------------------------------
15929
16195
  // kavach_oidc_auth_codes (OIDC Provider — authorization codes)
15930
16196
  // ------------------------------------------------------------------
15931
- `CREATE TABLE ${ifne} kavach_oidc_auth_codes (
16197
+ {
16198
+ feature: "oidcProvider",
16199
+ sql: `CREATE TABLE ${ifne} kavach_oidc_auth_codes (
15932
16200
  id TEXT NOT NULL PRIMARY KEY,
15933
16201
  code_hash TEXT NOT NULL UNIQUE,
15934
16202
  client_id TEXT NOT NULL,
@@ -15941,11 +16209,14 @@ function buildStatements(provider) {
15941
16209
  used ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
15942
16210
  expires_at ${ts} NOT NULL,
15943
16211
  created_at ${ts} NOT NULL
15944
- )`,
16212
+ )`
16213
+ },
15945
16214
  // ------------------------------------------------------------------
15946
16215
  // kavach_oidc_refresh_tokens (OIDC Provider — refresh tokens)
15947
16216
  // ------------------------------------------------------------------
15948
- `CREATE TABLE ${ifne} kavach_oidc_refresh_tokens (
16217
+ {
16218
+ feature: "oidcProvider",
16219
+ sql: `CREATE TABLE ${ifne} kavach_oidc_refresh_tokens (
15949
16220
  id TEXT NOT NULL PRIMARY KEY,
15950
16221
  token_hash TEXT NOT NULL UNIQUE,
15951
16222
  client_id TEXT NOT NULL,
@@ -15954,11 +16225,14 @@ function buildStatements(provider) {
15954
16225
  revoked ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
15955
16226
  expires_at ${ts} NOT NULL,
15956
16227
  created_at ${ts} NOT NULL
15957
- )`,
16228
+ )`
16229
+ },
15958
16230
  // ------------------------------------------------------------------
15959
16231
  // kavach_cost_events (per-agent cost attribution)
15960
16232
  // ------------------------------------------------------------------
15961
- `CREATE TABLE ${ifne} kavach_cost_events (
16233
+ {
16234
+ feature: "audit",
16235
+ sql: `CREATE TABLE ${ifne} kavach_cost_events (
15962
16236
  id TEXT NOT NULL PRIMARY KEY,
15963
16237
  agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
15964
16238
  tool TEXT NOT NULL,
@@ -15969,15 +16243,24 @@ function buildStatements(provider) {
15969
16243
  metadata ${json2},
15970
16244
  delegation_chain_id TEXT,
15971
16245
  recorded_at ${ts} NOT NULL
15972
- )`,
15973
- `CREATE INDEX ${ifne} kavach_cost_events_agent_recorded
15974
- ON kavach_cost_events (agent_id, recorded_at DESC)`,
15975
- `CREATE INDEX ${ifne} kavach_cost_events_chain_id
15976
- ON kavach_cost_events (delegation_chain_id)`,
16246
+ )`
16247
+ },
16248
+ {
16249
+ feature: "audit",
16250
+ sql: `CREATE INDEX ${ifne} kavach_cost_events_agent_recorded
16251
+ ON kavach_cost_events (agent_id, recorded_at DESC)`
16252
+ },
16253
+ {
16254
+ feature: "audit",
16255
+ sql: `CREATE INDEX ${ifne} kavach_cost_events_chain_id
16256
+ ON kavach_cost_events (delegation_chain_id)`
16257
+ },
15977
16258
  // ------------------------------------------------------------------
15978
16259
  // kavach_ephemeral_sessions (short-lived agent credentials)
15979
16260
  // ------------------------------------------------------------------
15980
- `CREATE TABLE ${ifne} kavach_ephemeral_sessions (
16261
+ {
16262
+ feature: "agent",
16263
+ sql: `CREATE TABLE ${ifne} kavach_ephemeral_sessions (
15981
16264
  id TEXT NOT NULL PRIMARY KEY,
15982
16265
  agent_id TEXT NOT NULL REFERENCES kavach_agents(id) ON DELETE CASCADE,
15983
16266
  owner_id TEXT NOT NULL REFERENCES kavach_users(id),
@@ -15989,55 +16272,85 @@ function buildStatements(provider) {
15989
16272
  audit_group_id TEXT NOT NULL,
15990
16273
  created_at ${ts} NOT NULL,
15991
16274
  updated_at ${ts} NOT NULL
15992
- )`,
15993
- `CREATE INDEX ${ifne} kavach_ephemeral_sessions_owner_status
15994
- ON kavach_ephemeral_sessions (owner_id, status)`,
15995
- `CREATE INDEX ${ifne} kavach_ephemeral_sessions_expires_at
15996
- ON kavach_ephemeral_sessions (expires_at)`,
16275
+ )`
16276
+ },
16277
+ {
16278
+ feature: "agent",
16279
+ sql: `CREATE INDEX ${ifne} kavach_ephemeral_sessions_owner_status
16280
+ ON kavach_ephemeral_sessions (owner_id, status)`
16281
+ },
16282
+ {
16283
+ feature: "agent",
16284
+ sql: `CREATE INDEX ${ifne} kavach_ephemeral_sessions_expires_at
16285
+ ON kavach_ephemeral_sessions (expires_at)`
16286
+ },
15997
16287
  // ------------------------------------------------------------------
15998
16288
  // kavach_jwt_refresh_tokens (JWT session plugin — general purpose)
15999
16289
  // ------------------------------------------------------------------
16000
- `CREATE TABLE ${ifne} kavach_jwt_refresh_tokens (
16290
+ {
16291
+ feature: "jwt",
16292
+ sql: `CREATE TABLE ${ifne} kavach_jwt_refresh_tokens (
16001
16293
  id TEXT NOT NULL PRIMARY KEY,
16002
16294
  token_hash TEXT NOT NULL UNIQUE,
16003
16295
  user_id TEXT NOT NULL REFERENCES kavach_users(id) ON DELETE CASCADE,
16004
16296
  used ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
16005
16297
  expires_at ${ts} NOT NULL,
16006
16298
  created_at ${ts} NOT NULL
16007
- )`,
16008
- `CREATE INDEX ${ifne} kavach_jwt_refresh_tokens_user_id
16009
- ON kavach_jwt_refresh_tokens (user_id)`,
16299
+ )`
16300
+ },
16301
+ {
16302
+ feature: "jwt",
16303
+ sql: `CREATE INDEX ${ifne} kavach_jwt_refresh_tokens_user_id
16304
+ ON kavach_jwt_refresh_tokens (user_id)`
16305
+ },
16010
16306
  // ------------------------------------------------------------------
16011
16307
  // kavach_stream_events (persisted SSE events for replay)
16012
16308
  // ------------------------------------------------------------------
16013
- `CREATE TABLE ${ifne} kavach_stream_events (
16309
+ {
16310
+ feature: "audit",
16311
+ sql: `CREATE TABLE ${ifne} kavach_stream_events (
16014
16312
  id TEXT NOT NULL PRIMARY KEY,
16015
16313
  type TEXT NOT NULL,
16016
16314
  timestamp ${ts} NOT NULL,
16017
16315
  data ${json2} NOT NULL,
16018
16316
  agent_id TEXT,
16019
16317
  user_id TEXT
16020
- )`,
16021
- `CREATE INDEX ${ifne} kavach_stream_events_timestamp
16022
- ON kavach_stream_events (timestamp DESC)`,
16023
- `CREATE INDEX ${ifne} kavach_stream_events_type_timestamp
16024
- ON kavach_stream_events (type, timestamp DESC)`,
16318
+ )`
16319
+ },
16320
+ {
16321
+ feature: "audit",
16322
+ sql: `CREATE INDEX ${ifne} kavach_stream_events_timestamp
16323
+ ON kavach_stream_events (timestamp DESC)`
16324
+ },
16325
+ {
16326
+ feature: "audit",
16327
+ sql: `CREATE INDEX ${ifne} kavach_stream_events_type_timestamp
16328
+ ON kavach_stream_events (type, timestamp DESC)`
16329
+ },
16025
16330
  // ------------------------------------------------------------------
16026
16331
  // kavach_rebac_resources (ReBAC resource hierarchy)
16027
16332
  // ------------------------------------------------------------------
16028
- `CREATE TABLE ${ifne} kavach_rebac_resources (
16333
+ {
16334
+ feature: "rebac",
16335
+ sql: `CREATE TABLE ${ifne} kavach_rebac_resources (
16029
16336
  id TEXT NOT NULL PRIMARY KEY,
16030
16337
  type TEXT NOT NULL,
16031
16338
  parent_id TEXT,
16032
16339
  parent_type TEXT,
16033
16340
  created_at ${ts} NOT NULL
16034
- )`,
16035
- `CREATE INDEX ${ifne} kavach_rebac_resources_parent
16036
- ON kavach_rebac_resources (parent_id, parent_type)`,
16341
+ )`
16342
+ },
16343
+ {
16344
+ feature: "rebac",
16345
+ sql: `CREATE INDEX ${ifne} kavach_rebac_resources_parent
16346
+ ON kavach_rebac_resources (parent_id, parent_type)`
16347
+ },
16037
16348
  // ------------------------------------------------------------------
16038
16349
  // kavach_rebac_relationships (Zanzibar-style subject-relation-object tuples)
16039
16350
  // ------------------------------------------------------------------
16040
- `CREATE TABLE ${ifne} kavach_rebac_relationships (
16351
+ {
16352
+ feature: "rebac",
16353
+ sql: `CREATE TABLE ${ifne} kavach_rebac_relationships (
16041
16354
  id TEXT NOT NULL PRIMARY KEY,
16042
16355
  subject_type TEXT NOT NULL,
16043
16356
  subject_id TEXT NOT NULL,
@@ -16045,17 +16358,29 @@ function buildStatements(provider) {
16045
16358
  object_type TEXT NOT NULL,
16046
16359
  object_id TEXT NOT NULL,
16047
16360
  created_at ${ts} NOT NULL
16048
- )`,
16049
- `CREATE INDEX ${ifne} kavach_rebac_relationships_subject
16050
- ON kavach_rebac_relationships (subject_type, subject_id)`,
16051
- `CREATE INDEX ${ifne} kavach_rebac_relationships_object
16052
- ON kavach_rebac_relationships (object_type, object_id)`,
16053
- `CREATE UNIQUE INDEX ${ifne} kavach_rebac_relationships_tuple
16054
- ON kavach_rebac_relationships (subject_type, subject_id, relation, object_type, object_id)`,
16361
+ )`
16362
+ },
16363
+ {
16364
+ feature: "rebac",
16365
+ sql: `CREATE INDEX ${ifne} kavach_rebac_relationships_subject
16366
+ ON kavach_rebac_relationships (subject_type, subject_id)`
16367
+ },
16368
+ {
16369
+ feature: "rebac",
16370
+ sql: `CREATE INDEX ${ifne} kavach_rebac_relationships_object
16371
+ ON kavach_rebac_relationships (object_type, object_id)`
16372
+ },
16373
+ {
16374
+ feature: "rebac",
16375
+ sql: `CREATE UNIQUE INDEX ${ifne} kavach_rebac_relationships_tuple
16376
+ ON kavach_rebac_relationships (subject_type, subject_id, relation, object_type, object_id)`
16377
+ },
16055
16378
  // ------------------------------------------------------------------
16056
16379
  // kavach_federation_instances (trusted remote KavachOS instances)
16057
16380
  // ------------------------------------------------------------------
16058
- `CREATE TABLE ${ifne} kavach_federation_instances (
16381
+ {
16382
+ feature: "federation",
16383
+ sql: `CREATE TABLE ${ifne} kavach_federation_instances (
16059
16384
  id TEXT NOT NULL PRIMARY KEY,
16060
16385
  instance_id TEXT NOT NULL UNIQUE,
16061
16386
  instance_url TEXT NOT NULL,
@@ -16064,11 +16389,14 @@ function buildStatements(provider) {
16064
16389
  discovered_at ${tsNull},
16065
16390
  created_at ${ts} NOT NULL,
16066
16391
  updated_at ${ts} NOT NULL
16067
- )`,
16392
+ )`
16393
+ },
16068
16394
  // ------------------------------------------------------------------
16069
16395
  // kavach_federation_tokens (issued/received federation tokens)
16070
16396
  // ------------------------------------------------------------------
16071
- `CREATE TABLE ${ifne} kavach_federation_tokens (
16397
+ {
16398
+ feature: "federation",
16399
+ sql: `CREATE TABLE ${ifne} kavach_federation_tokens (
16072
16400
  id TEXT NOT NULL PRIMARY KEY,
16073
16401
  token_jti TEXT NOT NULL UNIQUE,
16074
16402
  agent_id TEXT NOT NULL,
@@ -16079,45 +16407,61 @@ function buildStatements(provider) {
16079
16407
  trust_score INTEGER,
16080
16408
  expires_at ${ts} NOT NULL,
16081
16409
  created_at ${ts} NOT NULL
16082
- )`,
16083
- `CREATE INDEX ${ifne} kavach_federation_tokens_agent
16084
- ON kavach_federation_tokens (agent_id)`,
16085
- `CREATE INDEX ${ifne} kavach_federation_tokens_source
16086
- ON kavach_federation_tokens (source_instance_id)`,
16410
+ )`
16411
+ },
16412
+ {
16413
+ feature: "federation",
16414
+ sql: `CREATE INDEX ${ifne} kavach_federation_tokens_agent
16415
+ ON kavach_federation_tokens (agent_id)`
16416
+ },
16417
+ {
16418
+ feature: "federation",
16419
+ sql: `CREATE INDEX ${ifne} kavach_federation_tokens_source
16420
+ ON kavach_federation_tokens (source_instance_id)`
16421
+ },
16087
16422
  // ------------------------------------------------------------------
16088
16423
  // kavach_refresh_token_families (token rotation / reuse detection)
16089
16424
  // ------------------------------------------------------------------
16090
- `CREATE TABLE ${ifne} kavach_refresh_token_families (
16425
+ {
16426
+ feature: "jwt",
16427
+ sql: `CREATE TABLE ${ifne} kavach_refresh_token_families (
16091
16428
  id TEXT NOT NULL PRIMARY KEY,
16092
16429
  user_id TEXT NOT NULL REFERENCES kavach_users(id) ON DELETE CASCADE,
16093
16430
  absolute_expires_at ${ts} NOT NULL,
16094
16431
  revoked ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
16095
16432
  created_at ${ts} NOT NULL
16096
- )`,
16097
- `CREATE INDEX ${ifne} kavach_refresh_token_families_user_id
16098
- ON kavach_refresh_token_families (user_id)`,
16433
+ )`
16434
+ },
16435
+ {
16436
+ feature: "jwt",
16437
+ sql: `CREATE INDEX ${ifne} kavach_refresh_token_families_user_id
16438
+ ON kavach_refresh_token_families (user_id)`
16439
+ },
16099
16440
  // ------------------------------------------------------------------
16100
16441
  // kavach_refresh_tokens (individual one-time-use tokens per family)
16101
16442
  // ------------------------------------------------------------------
16102
- `CREATE TABLE ${ifne} kavach_refresh_tokens (
16443
+ {
16444
+ feature: "jwt",
16445
+ sql: `CREATE TABLE ${ifne} kavach_refresh_tokens (
16103
16446
  id TEXT NOT NULL PRIMARY KEY,
16104
16447
  family_id TEXT NOT NULL REFERENCES kavach_refresh_token_families(id) ON DELETE CASCADE,
16105
16448
  token_hash TEXT NOT NULL UNIQUE,
16106
16449
  used ${bool} NOT NULL DEFAULT ${isPostgres ? "FALSE" : "0"},
16107
16450
  expires_at ${ts} NOT NULL,
16108
16451
  created_at ${ts} NOT NULL
16109
- )`,
16110
- `CREATE INDEX ${ifne} kavach_refresh_tokens_family_id
16452
+ )`
16453
+ },
16454
+ {
16455
+ feature: "jwt",
16456
+ sql: `CREATE INDEX ${ifne} kavach_refresh_tokens_family_id
16111
16457
  ON kavach_refresh_tokens (family_id)`
16112
- // ------------------------------------------------------------------
16113
- // kavach_users ban columns (ALTER TABLE IF NOT EXISTS — safe no-ops)
16114
- // These are appended as separate ALTER statements for existing DBs.
16115
- // For SQLite we use a separate migration path since SQLite ALTER is limited.
16116
- // ------------------------------------------------------------------
16458
+ }
16117
16459
  ];
16118
16460
  }
16119
- async function createTables(db, provider) {
16120
- const statements = buildStatements(provider);
16461
+ async function createTables(db, provider, config) {
16462
+ const allStatements = buildStatements(provider);
16463
+ const features = resolveEnabledFeatures(config);
16464
+ const statements = allStatements.filter((s) => features[s.feature]).map((s) => s.sql);
16121
16465
  if (provider === "sqlite" || provider === "sqlite-native") {
16122
16466
  const session = db.session;
16123
16467
  if (session?.client?.exec) {
@@ -17227,6 +17571,9 @@ function validateArgPatterns(patterns, args) {
17227
17571
  return { valid: true };
17228
17572
  }
17229
17573
  async function checkRateLimit(db, agentId, resource, maxCallsPerHour) {
17574
+ if (!agentId) {
17575
+ return { allowed: true };
17576
+ }
17230
17577
  const oneHourAgo = new Date(Date.now() - 60 * 60 * 1e3);
17231
17578
  const rows = await db.select().from(rateLimits).where(
17232
17579
  and(
@@ -17257,66 +17604,20 @@ async function checkRateLimit(db, agentId, resource, maxCallsPerHour) {
17257
17604
  }
17258
17605
  return { allowed: true };
17259
17606
  }
17260
- function createPermissionEngine(config) {
17261
- const { db, auditAll } = config;
17262
- async function authorize(agent, request) {
17263
- const startTime = performance.now();
17264
- const auditId = generateId();
17265
- const matchingPermission = agent.permissions.find(
17266
- (p2) => matchResource(p2.resource, request.resource) && matchAction(p2.actions, request.action)
17267
- );
17268
- if (!matchingPermission) {
17269
- const result2 = {
17270
- allowed: false,
17271
- reason: `No permission grants agent "${agent.name}" access to "${request.action}" on "${request.resource}"`,
17272
- auditId
17273
- };
17274
- if (auditAll) {
17275
- await writeAuditLog(db, agent, request, result2, startTime, auditId);
17276
- }
17277
- return result2;
17278
- }
17279
- if (matchingPermission.constraints) {
17280
- const constraintResult = await evaluateConstraints(
17281
- db,
17282
- agent,
17283
- request,
17284
- matchingPermission.constraints
17285
- );
17286
- if (!constraintResult.allowed) {
17287
- const result2 = {
17288
- allowed: false,
17289
- reason: constraintResult.reason,
17290
- auditId
17291
- };
17292
- if (auditAll) {
17293
- await writeAuditLog(db, agent, request, result2, startTime, auditId);
17294
- }
17295
- return result2;
17296
- }
17297
- }
17298
- const result = { allowed: true, auditId };
17299
- if (auditAll) {
17300
- await writeAuditLog(db, agent, request, result, startTime, auditId);
17301
- }
17302
- return result;
17303
- }
17304
- return { authorize };
17305
- }
17306
- async function evaluateConstraints(db, agent, request, constraints) {
17607
+ async function evaluateConstraints(db, input, constraints) {
17307
17608
  if (constraints.maxCallsPerHour) {
17308
17609
  const rateResult = await checkRateLimit(
17309
17610
  db,
17310
- agent.id,
17311
- request.resource,
17611
+ input.subjectId,
17612
+ input.resource,
17312
17613
  constraints.maxCallsPerHour
17313
17614
  );
17314
17615
  if (!rateResult.allowed) {
17315
17616
  return rateResult;
17316
17617
  }
17317
17618
  }
17318
- if (constraints.allowedArgPatterns && request.arguments) {
17319
- const patternResult = validateArgPatterns(constraints.allowedArgPatterns, request.arguments);
17619
+ if (constraints.allowedArgPatterns && input.arguments) {
17620
+ const patternResult = validateArgPatterns(constraints.allowedArgPatterns, input.arguments);
17320
17621
  if (!patternResult.valid) {
17321
17622
  return { allowed: false, reason: patternResult.reason };
17322
17623
  }
@@ -17340,21 +17641,77 @@ async function evaluateConstraints(db, agent, request, constraints) {
17340
17641
  }
17341
17642
  }
17342
17643
  if (constraints.ipAllowlist && constraints.ipAllowlist.length > 0) {
17343
- if (!request.ip) {
17644
+ if (!input.ip) {
17344
17645
  return {
17345
17646
  allowed: false,
17346
17647
  reason: "IP_NOT_ALLOWED: No IP address provided; resource requires an IP allowlist match"
17347
17648
  };
17348
17649
  }
17349
- if (!isIPAllowed(constraints.ipAllowlist, request.ip)) {
17650
+ if (!isIPAllowed(constraints.ipAllowlist, input.ip)) {
17350
17651
  return {
17351
17652
  allowed: false,
17352
- reason: `IP_NOT_ALLOWED: IP "${request.ip}" is not in the allowlist for this resource`
17653
+ reason: `IP_NOT_ALLOWED: IP "${input.ip}" is not in the allowlist for this resource`
17353
17654
  };
17354
17655
  }
17355
17656
  }
17356
17657
  return { allowed: true };
17357
17658
  }
17659
+ function isCacheUnsafe(constraints) {
17660
+ if (!constraints) return false;
17661
+ return Boolean(constraints.maxCallsPerHour) || Boolean(constraints.timeWindow) || Array.isArray(constraints.allowedArgPatterns) && constraints.allowedArgPatterns.length > 0;
17662
+ }
17663
+
17664
+ // src/permission/engine.ts
17665
+ function createPermissionEngine(config) {
17666
+ const { db, auditAll } = config;
17667
+ async function authorize(agent, request) {
17668
+ const startTime = performance.now();
17669
+ const auditId = generateId();
17670
+ const matchingPermission = agent.permissions.find(
17671
+ (p2) => matchResource(p2.resource, request.resource) && matchAction(p2.actions, request.action)
17672
+ );
17673
+ if (!matchingPermission) {
17674
+ const result2 = {
17675
+ allowed: false,
17676
+ reason: `No permission grants agent "${agent.name}" access to "${request.action}" on "${request.resource}"`,
17677
+ auditId
17678
+ };
17679
+ if (auditAll) {
17680
+ await writeAuditLog(db, agent, request, result2, startTime, auditId);
17681
+ }
17682
+ return result2;
17683
+ }
17684
+ if (matchingPermission.constraints) {
17685
+ const constraintResult = await evaluateConstraints(
17686
+ db,
17687
+ {
17688
+ subjectId: agent.id,
17689
+ resource: request.resource,
17690
+ arguments: request.arguments,
17691
+ ip: request.ip
17692
+ },
17693
+ matchingPermission.constraints
17694
+ );
17695
+ if (!constraintResult.allowed) {
17696
+ const result2 = {
17697
+ allowed: false,
17698
+ reason: constraintResult.reason,
17699
+ auditId
17700
+ };
17701
+ if (auditAll) {
17702
+ await writeAuditLog(db, agent, request, result2, startTime, auditId);
17703
+ }
17704
+ return result2;
17705
+ }
17706
+ }
17707
+ const result = { allowed: true, auditId };
17708
+ if (auditAll) {
17709
+ await writeAuditLog(db, agent, request, result, startTime, auditId);
17710
+ }
17711
+ return result;
17712
+ }
17713
+ return { authorize };
17714
+ }
17358
17715
  async function writeAuditLog(db, agent, request, result, startTime, auditId) {
17359
17716
  const durationMs = Math.round(performance.now() - startTime);
17360
17717
  await db.insert(auditLogs).values({
@@ -17737,6 +18094,509 @@ function createPolicyModule(db) {
17737
18094
  return { create, get, list, update, remove, checkBudget, recordUsage, resetDaily, resetMonthly };
17738
18095
  }
17739
18096
 
18097
+ // src/policy/cache.ts
18098
+ function readEnvNumber(name) {
18099
+ if (typeof process === "undefined") return void 0;
18100
+ const raw = process.env[name];
18101
+ if (raw === void 0 || raw === "") return void 0;
18102
+ const n = Number(raw);
18103
+ return Number.isFinite(n) ? n : void 0;
18104
+ }
18105
+ function readEnvBool(name) {
18106
+ if (typeof process === "undefined") return void 0;
18107
+ const raw = process.env[name];
18108
+ if (raw === void 0 || raw === "") return void 0;
18109
+ return raw.toLowerCase() !== "false" && raw !== "0";
18110
+ }
18111
+ var DEFAULT_MAX_ENTRIES = 1e4;
18112
+ var DEFAULT_TTL_MS = 6e4;
18113
+ function createPolicyCache(config) {
18114
+ const rawMax = config.maxEntries ?? readEnvNumber("KAVACH_POLICY_CACHE_MAX") ?? DEFAULT_MAX_ENTRIES;
18115
+ const maxEntries = rawMax > 0 ? rawMax : DEFAULT_MAX_ENTRIES;
18116
+ const ttlMs = config.ttlMs ?? readEnvNumber("KAVACH_POLICY_CACHE_TTL_MS") ?? DEFAULT_TTL_MS;
18117
+ const enabled = config.enabled ?? readEnvBool("KAVACH_POLICY_CACHE") ?? true;
18118
+ const store = /* @__PURE__ */ new Map();
18119
+ let hits = 0;
18120
+ let misses = 0;
18121
+ let evictions = 0;
18122
+ function evictOldest() {
18123
+ const firstKey = store.keys().next().value;
18124
+ if (firstKey !== void 0) {
18125
+ store.delete(firstKey);
18126
+ evictions++;
18127
+ }
18128
+ }
18129
+ function isExpired(entry) {
18130
+ return Date.now() >= entry.expiresAt;
18131
+ }
18132
+ function get(key) {
18133
+ if (!enabled) {
18134
+ misses++;
18135
+ return void 0;
18136
+ }
18137
+ const entry = store.get(key);
18138
+ if (entry === void 0) {
18139
+ misses++;
18140
+ return void 0;
18141
+ }
18142
+ if (isExpired(entry)) {
18143
+ store.delete(key);
18144
+ evictions++;
18145
+ misses++;
18146
+ return void 0;
18147
+ }
18148
+ store.delete(key);
18149
+ store.set(key, entry);
18150
+ hits++;
18151
+ return entry.value;
18152
+ }
18153
+ function set(key, value, options) {
18154
+ if (!enabled || options?.skipCache === true) return;
18155
+ const existing = store.get(key);
18156
+ if (existing !== void 0) {
18157
+ store.delete(key);
18158
+ }
18159
+ while (store.size >= maxEntries) {
18160
+ evictOldest();
18161
+ }
18162
+ store.set(key, { value, expiresAt: Date.now() + ttlMs });
18163
+ }
18164
+ function del(key) {
18165
+ return store.delete(key);
18166
+ }
18167
+ function clear() {
18168
+ store.clear();
18169
+ }
18170
+ function invalidatePrefix(prefix) {
18171
+ let count = 0;
18172
+ for (const key of store.keys()) {
18173
+ if (key.startsWith(prefix)) {
18174
+ store.delete(key);
18175
+ count++;
18176
+ }
18177
+ }
18178
+ return count;
18179
+ }
18180
+ function stats() {
18181
+ return {
18182
+ hits,
18183
+ misses,
18184
+ size: store.size,
18185
+ evictions
18186
+ };
18187
+ }
18188
+ return { get, set, delete: del, clear, invalidatePrefix, stats };
18189
+ }
18190
+
18191
+ // src/policy/types.ts
18192
+ var POLICY_ERROR_CODES = {
18193
+ INVALID_INPUT: "POLICY_INVALID_INPUT",
18194
+ SUBJECT_NOT_FOUND: "POLICY_SUBJECT_NOT_FOUND",
18195
+ GRAPH_QUERY_FAILED: "POLICY_GRAPH_QUERY_FAILED",
18196
+ NO_MATCHING_PERMISSION: "POLICY_NO_MATCHING_PERMISSION",
18197
+ CONSTRAINT_FAILED: "POLICY_CONSTRAINT_FAILED"
18198
+ };
18199
+
18200
+ // src/policy/combiner.ts
18201
+ function combine(partials, strategy = "deny-overrides") {
18202
+ if (partials.length === 0) {
18203
+ return {
18204
+ allowed: false,
18205
+ effect: "indeterminate",
18206
+ reason: POLICY_ERROR_CODES.NO_MATCHING_PERMISSION
18207
+ };
18208
+ }
18209
+ if (strategy === "deny-overrides") {
18210
+ const firstDeny = partials.find((p2) => p2.effect === "deny");
18211
+ if (firstDeny !== void 0) {
18212
+ return {
18213
+ allowed: false,
18214
+ effect: "deny",
18215
+ reason: firstDeny.reason,
18216
+ matchedPermissionId: firstDeny.matchedPermissionId,
18217
+ matchedRelation: firstDeny.matchedRelation
18218
+ };
18219
+ }
18220
+ const firstPermit = partials.find((p2) => p2.effect === "permit");
18221
+ if (firstPermit !== void 0) {
18222
+ return {
18223
+ allowed: true,
18224
+ effect: "permit",
18225
+ reason: firstPermit.reason,
18226
+ matchedPermissionId: firstPermit.matchedPermissionId,
18227
+ matchedRelation: firstPermit.matchedRelation
18228
+ };
18229
+ }
18230
+ }
18231
+ if (strategy === "permit-overrides") {
18232
+ const firstPermit = partials.find((p2) => p2.effect === "permit");
18233
+ if (firstPermit !== void 0) {
18234
+ return {
18235
+ allowed: true,
18236
+ effect: "permit",
18237
+ reason: firstPermit.reason,
18238
+ matchedPermissionId: firstPermit.matchedPermissionId,
18239
+ matchedRelation: firstPermit.matchedRelation
18240
+ };
18241
+ }
18242
+ const firstDeny = partials.find((p2) => p2.effect === "deny");
18243
+ if (firstDeny !== void 0) {
18244
+ return {
18245
+ allowed: false,
18246
+ effect: "deny",
18247
+ reason: firstDeny.reason,
18248
+ matchedPermissionId: firstDeny.matchedPermissionId,
18249
+ matchedRelation: firstDeny.matchedRelation
18250
+ };
18251
+ }
18252
+ }
18253
+ return {
18254
+ allowed: false,
18255
+ effect: "indeterminate",
18256
+ reason: POLICY_ERROR_CODES.NO_MATCHING_PERMISSION
18257
+ };
18258
+ }
18259
+ function parsePermissionString(raw) {
18260
+ const idx = raw.lastIndexOf(":");
18261
+ if (idx === -1) return null;
18262
+ const resource = raw.slice(0, idx);
18263
+ const action = raw.slice(idx + 1);
18264
+ if (!resource || !action) return null;
18265
+ return { resource, action };
18266
+ }
18267
+ function toPermissions(rawStrings) {
18268
+ const map = /* @__PURE__ */ new Map();
18269
+ for (const raw of rawStrings) {
18270
+ const parsed = parsePermissionString(raw);
18271
+ if (!parsed) continue;
18272
+ const existing = map.get(parsed.resource);
18273
+ if (existing) {
18274
+ existing.add(parsed.action);
18275
+ } else {
18276
+ map.set(parsed.resource, /* @__PURE__ */ new Set([parsed.action]));
18277
+ }
18278
+ }
18279
+ return Array.from(map.entries()).map(([resource, actionsSet]) => ({
18280
+ resource,
18281
+ actions: Array.from(actionsSet).sort()
18282
+ }));
18283
+ }
18284
+ function deduplicate(permissions2) {
18285
+ const seen = /* @__PURE__ */ new Set();
18286
+ const result = [];
18287
+ for (const perm of permissions2) {
18288
+ const key = `${perm.resource}|${[...perm.actions].sort().join(",")}`;
18289
+ if (!seen.has(key)) {
18290
+ seen.add(key);
18291
+ result.push(perm);
18292
+ }
18293
+ }
18294
+ return result;
18295
+ }
18296
+ function createRbacResolver(deps) {
18297
+ const { db } = deps;
18298
+ async function resolveRolePermissions(input) {
18299
+ const { userId, orgId } = input;
18300
+ const baseWhere = orgId ? and(eq(orgMembers.userId, userId), eq(orgMembers.orgId, orgId)) : eq(orgMembers.userId, userId);
18301
+ const roleRows = await db.select({ permissions: orgRoles.permissions }).from(orgMembers).innerJoin(
18302
+ orgRoles,
18303
+ and(eq(orgRoles.orgId, orgMembers.orgId), eq(orgRoles.name, orgMembers.role))
18304
+ ).where(baseWhere);
18305
+ if (roleRows.length === 0) return [];
18306
+ const allRawPermissions = roleRows.flatMap((r) => r.permissions);
18307
+ if (allRawPermissions.length === 0) return [];
18308
+ return deduplicate(toPermissions(allRawPermissions));
18309
+ }
18310
+ return { resolveRolePermissions };
18311
+ }
18312
+
18313
+ // src/policy/rebac-bridge.ts
18314
+ var WILDCARD_REASON = "rebac:wildcard-resource-not-supported";
18315
+ var INVALID_SUBJECT_REASON = "rebac:invalid-subject";
18316
+ var GRAPH_FAILED_REASON = "rebac:graph-query-failed";
18317
+ var MATCHED_REASON = "rebac:matched";
18318
+ var NO_TUPLE_REASON = "rebac:no-tuple";
18319
+ function parseResource(resource) {
18320
+ if (resource.includes("*")) return null;
18321
+ const colonIdx = resource.indexOf(":");
18322
+ if (colonIdx === -1) return null;
18323
+ const objectType = resource.slice(0, colonIdx);
18324
+ const objectId = resource.slice(colonIdx + 1);
18325
+ if (!objectType || !objectId) return null;
18326
+ return { objectType, objectId };
18327
+ }
18328
+ function parseSubject(subject) {
18329
+ if (subject.agentId !== void 0 && subject.userId !== void 0) {
18330
+ return null;
18331
+ }
18332
+ if (subject.agentId !== void 0) {
18333
+ return { subjectType: "agent", subjectId: subject.agentId };
18334
+ }
18335
+ if (subject.userId !== void 0) {
18336
+ return { subjectType: "user", subjectId: subject.userId };
18337
+ }
18338
+ if (subject.orgId !== void 0) {
18339
+ return { subjectType: "org", subjectId: subject.orgId };
18340
+ }
18341
+ return null;
18342
+ }
18343
+ function createRebacBridge(deps) {
18344
+ const rebac = createReBACModule({}, deps.db);
18345
+ async function checkRelation(input) {
18346
+ const parsed = parseResource(input.resource);
18347
+ if (!parsed) {
18348
+ return { matched: false, reason: WILDCARD_REASON };
18349
+ }
18350
+ const subject = parseSubject(input.subject);
18351
+ if (!subject) {
18352
+ return { matched: false, reason: INVALID_SUBJECT_REASON };
18353
+ }
18354
+ const { objectType, objectId } = parsed;
18355
+ const { subjectType, subjectId } = subject;
18356
+ let result;
18357
+ try {
18358
+ result = await rebac.check({
18359
+ subjectType,
18360
+ subjectId,
18361
+ permission: input.relation,
18362
+ objectType,
18363
+ objectId
18364
+ });
18365
+ } catch {
18366
+ return { matched: false, reason: GRAPH_FAILED_REASON };
18367
+ }
18368
+ if (!result.success) {
18369
+ return { matched: false, reason: GRAPH_FAILED_REASON };
18370
+ }
18371
+ return result.data.allowed ? { matched: true, reason: MATCHED_REASON } : { matched: false, reason: NO_TUPLE_REASON };
18372
+ }
18373
+ return { checkRelation };
18374
+ }
18375
+
18376
+ // src/policy/engine.ts
18377
+ function createPolicyEngine(deps) {
18378
+ const { db, config = {} } = deps;
18379
+ const cache = createPolicyCache(config.cache ?? {});
18380
+ const rbac = createRbacResolver({ db });
18381
+ const rebac = createRebacBridge({ db });
18382
+ const strategy = config.combineStrategy ?? "deny-overrides";
18383
+ const auditEnabled = config.audit !== false;
18384
+ const sampleRate = clampSampleRate(config.auditSampleRate);
18385
+ async function evaluate(input) {
18386
+ const start = performance.now();
18387
+ const validation = validateInput(input);
18388
+ if (!validation.ok) {
18389
+ return finalize(
18390
+ {
18391
+ allowed: false,
18392
+ effect: "indeterminate",
18393
+ reason: validation.reason,
18394
+ cacheHit: false,
18395
+ durationMs: 0
18396
+ },
18397
+ start
18398
+ );
18399
+ }
18400
+ const cacheKey = buildCacheKey(input);
18401
+ const cached = cache.get(cacheKey);
18402
+ if (cached) {
18403
+ const auditIdForHit = willEmitAudit(input) ? generateId() : void 0;
18404
+ const decision2 = {
18405
+ ...cached,
18406
+ auditId: auditIdForHit,
18407
+ cacheHit: true,
18408
+ durationMs: Math.round(performance.now() - start)
18409
+ };
18410
+ emitAudit(decision2, input, auditIdForHit).catch(noop);
18411
+ return decision2;
18412
+ }
18413
+ let effective;
18414
+ try {
18415
+ effective = await resolveEffectivePermissions(db, rbac, input);
18416
+ } catch {
18417
+ return finalize(
18418
+ {
18419
+ allowed: false,
18420
+ effect: "indeterminate",
18421
+ reason: POLICY_ERROR_CODES.SUBJECT_NOT_FOUND,
18422
+ cacheHit: false,
18423
+ durationMs: 0
18424
+ },
18425
+ start
18426
+ );
18427
+ }
18428
+ const partials = [];
18429
+ let cacheUnsafeSeen = false;
18430
+ for (const perm of effective) {
18431
+ if (!matchResource(perm.resource, input.resource)) continue;
18432
+ if (!matchAction(perm.actions, input.action)) continue;
18433
+ if (perm.relation) {
18434
+ const result = await rebac.checkRelation({
18435
+ subject: input.subject,
18436
+ relation: perm.relation,
18437
+ resource: input.resource
18438
+ });
18439
+ if (result.reason === "rebac:graph-query-failed") {
18440
+ return finalize(
18441
+ {
18442
+ allowed: false,
18443
+ effect: "indeterminate",
18444
+ reason: POLICY_ERROR_CODES.GRAPH_QUERY_FAILED,
18445
+ cacheHit: false,
18446
+ durationMs: 0
18447
+ },
18448
+ start
18449
+ );
18450
+ }
18451
+ if (!result.matched) continue;
18452
+ }
18453
+ if (perm.constraints) {
18454
+ if (isCacheUnsafe(perm.constraints)) cacheUnsafeSeen = true;
18455
+ const constraintResult = await evaluateConstraints(
18456
+ db,
18457
+ {
18458
+ subjectId: input.subject.agentId ?? "",
18459
+ resource: input.resource,
18460
+ arguments: input.context?.arguments,
18461
+ ip: input.context?.ip
18462
+ },
18463
+ perm.constraints
18464
+ );
18465
+ if (!constraintResult.allowed) {
18466
+ partials.push({
18467
+ effect: "deny",
18468
+ reason: constraintResult.reason ?? POLICY_ERROR_CODES.CONSTRAINT_FAILED,
18469
+ matchedRelation: perm.relation
18470
+ });
18471
+ continue;
18472
+ }
18473
+ }
18474
+ partials.push({
18475
+ effect: "permit",
18476
+ reason: "matched",
18477
+ matchedRelation: perm.relation
18478
+ });
18479
+ }
18480
+ const combined = combine(partials, strategy);
18481
+ const auditIdForMiss = willEmitAudit(input) ? generateId() : void 0;
18482
+ const decision = {
18483
+ ...combined,
18484
+ auditId: auditIdForMiss,
18485
+ cacheHit: false,
18486
+ durationMs: Math.round(performance.now() - start)
18487
+ };
18488
+ if (!cacheUnsafeSeen) {
18489
+ cache.set(cacheKey, decision);
18490
+ }
18491
+ emitAudit(decision, input, auditIdForMiss).catch(noop);
18492
+ return decision;
18493
+ }
18494
+ function willEmitAudit(input) {
18495
+ if (!auditEnabled) return false;
18496
+ if (!input.subject.agentId) return false;
18497
+ return sampleRate >= 1 || Math.random() < sampleRate;
18498
+ }
18499
+ function invalidate(scope) {
18500
+ if (scope.agentId) cache.invalidatePrefix(`${scope.agentId}|`);
18501
+ if (scope.userId) cache.invalidatePrefix(`${scope.userId}|`);
18502
+ if (scope.resource) cache.clear();
18503
+ }
18504
+ function stats() {
18505
+ return cache.stats();
18506
+ }
18507
+ async function emitAudit(decision, input, auditId) {
18508
+ if (!auditId || !input.subject.agentId) return;
18509
+ let userId = input.subject.userId;
18510
+ if (!userId) {
18511
+ const ownerRows = await db.select({ ownerId: agents.ownerId }).from(agents).where(eq(agents.id, input.subject.agentId)).limit(1);
18512
+ userId = ownerRows[0]?.ownerId;
18513
+ if (!userId) return;
18514
+ }
18515
+ try {
18516
+ await db.insert(auditLogs).values({
18517
+ id: auditId,
18518
+ agentId: input.subject.agentId,
18519
+ userId,
18520
+ action: input.action,
18521
+ resource: input.resource,
18522
+ parameters: input.context?.arguments ?? {},
18523
+ result: decision.allowed ? "allowed" : "denied",
18524
+ reason: decision.reason ?? null,
18525
+ durationMs: decision.durationMs,
18526
+ timestamp: /* @__PURE__ */ new Date(),
18527
+ ip: input.context?.ip ?? null,
18528
+ userAgent: typeof input.context?.userAgent === "string" ? input.context.userAgent : null,
18529
+ cacheHit: decision.cacheHit
18530
+ });
18531
+ } catch {
18532
+ }
18533
+ }
18534
+ return { evaluate, invalidate, stats };
18535
+ }
18536
+ function buildCacheKey(input) {
18537
+ const subjectKey = input.subject.agentId ?? input.subject.userId ?? "";
18538
+ const orgKey = input.subject.orgId ?? "__noorg__";
18539
+ const ipKey = input.context?.ip ?? "";
18540
+ return `${subjectKey}|${orgKey}|${input.action}|${input.resource}|${ipKey}`;
18541
+ }
18542
+ function validateInput(input) {
18543
+ if (!input || !input.subject || !input.action || !input.resource) {
18544
+ return { ok: false, reason: POLICY_ERROR_CODES.INVALID_INPUT };
18545
+ }
18546
+ if (!input.subject.agentId && !input.subject.userId) {
18547
+ return { ok: false, reason: POLICY_ERROR_CODES.INVALID_INPUT };
18548
+ }
18549
+ return { ok: true };
18550
+ }
18551
+ function clampSampleRate(rate) {
18552
+ if (typeof rate !== "number" || Number.isNaN(rate)) return 1;
18553
+ if (rate < 0) return 0;
18554
+ if (rate > 1) return 1;
18555
+ return rate;
18556
+ }
18557
+ function finalize(decision, start) {
18558
+ return {
18559
+ ...decision,
18560
+ durationMs: Math.round(performance.now() - start)
18561
+ };
18562
+ }
18563
+ async function resolveEffectivePermissions(db, rbac, input) {
18564
+ const direct = input.subject.agentId ? await fetchDirectPermissions(db, input.subject.agentId) : [];
18565
+ const delegated = input.subject.agentId ? await fetchDelegatedPermissions(db, input.subject.agentId) : [];
18566
+ const roles = input.subject.userId ? await rbac.resolveRolePermissions({
18567
+ userId: input.subject.userId,
18568
+ orgId: input.subject.orgId
18569
+ }) : [];
18570
+ return [...direct, ...delegated, ...roles];
18571
+ }
18572
+ async function fetchDirectPermissions(db, agentId) {
18573
+ const rows = await db.select().from(permissions).where(eq(permissions.agentId, agentId));
18574
+ return rows.map((r) => ({
18575
+ resource: r.resource,
18576
+ actions: r.actions,
18577
+ constraints: r.constraints ?? void 0,
18578
+ relation: r.relation ?? void 0
18579
+ }));
18580
+ }
18581
+ async function fetchDelegatedPermissions(db, agentId) {
18582
+ const now = /* @__PURE__ */ new Date();
18583
+ const chains = await db.select().from(delegationChains).where(
18584
+ and(
18585
+ eq(delegationChains.toAgentId, agentId),
18586
+ eq(delegationChains.status, "active"),
18587
+ gt(delegationChains.expiresAt, now)
18588
+ )
18589
+ );
18590
+ return chains.flatMap(
18591
+ (chain) => chain.permissions.map((perm) => ({
18592
+ resource: perm.resource,
18593
+ actions: perm.actions
18594
+ }))
18595
+ );
18596
+ }
18597
+ function noop() {
18598
+ }
18599
+
17740
18600
  // src/redirect/chain.ts
17741
18601
  var DEFAULT_COOKIE_NAME = "kavach_redirect";
17742
18602
  var DEFAULT_MAX_AGE = 600;
@@ -18299,8 +19159,9 @@ async function createKavach(config) {
18299
19159
  const authAdapter = config.auth?.adapter ?? null;
18300
19160
  const db = await createDatabase(config.database);
18301
19161
  if (!config.database.skipMigrations) {
18302
- await createTables(db, config.database.provider);
19162
+ await createTables(db, config.database.provider, config);
18303
19163
  }
19164
+ const policyEngine = createPolicyEngine({ db, config: config.policy });
18304
19165
  const agentConfig = {
18305
19166
  db,
18306
19167
  maxPerUser: config.agents?.maxPerUser ?? 10,
@@ -18950,6 +19811,34 @@ async function createKavach(config) {
18950
19811
  * ```
18951
19812
  */
18952
19813
  redirects: redirectChain,
19814
+ /**
19815
+ * Unified policy engine.
19816
+ *
19817
+ * Single decision point that combines RBAC role expansion, ABAC constraint
19818
+ * evaluation, and ReBAC graph queries. Backed by a process-local LRU cache
19819
+ * with deterministic invalidation.
19820
+ *
19821
+ * @example
19822
+ * ```typescript
19823
+ * const decision = await kavach.policy.evaluate({
19824
+ * subject: { agentId: 'agent-abc' },
19825
+ * action: 'read',
19826
+ * resource: 'tool:github:list_issues',
19827
+ * });
19828
+ * if (!decision.allowed) throw new Error(decision.reason);
19829
+ *
19830
+ * // Flush cached decisions after a permission change
19831
+ * kavach.policy.invalidate({ agentId: 'agent-abc' });
19832
+ *
19833
+ * // Inspect cache health
19834
+ * const { hits, misses, size, evictions } = kavach.policy.stats();
19835
+ * ```
19836
+ */
19837
+ policy: {
19838
+ evaluate: policyEngine.evaluate,
19839
+ invalidate: policyEngine.invalidate,
19840
+ stats: policyEngine.stats
19841
+ },
18953
19842
  /**
18954
19843
  * Plugin system.
18955
19844
  *
@@ -20088,7 +20977,7 @@ var CredentialSubjectSchema = z.object({
20088
20977
  ).optional(),
20089
20978
  name: z.string().optional(),
20090
20979
  type: z.string().optional()
20091
- });
20980
+ }).passthrough();
20092
20981
  var VerifiableCredentialSchema = z.object({
20093
20982
  "@context": z.array(z.string()).min(1),
20094
20983
  id: z.string().optional(),
@@ -20109,8 +20998,156 @@ var VerifiablePresentationSchema = z.object({
20109
20998
  proof: ProofSchema.optional()
20110
20999
  });
20111
21000
 
20112
- // src/vc/issuer.ts
21001
+ // src/vc/audit-export.ts
21002
+ var KAVACHOS_AUDIT_CREDENTIAL = "KavachosAuditCredential";
21003
+ var KAVACHOS_AUDIT_CONTEXT = "https://kavachos.com/contexts/audit/v1.jsonld";
21004
+ var KAVACHOS_VERSION = "0.3.0";
20113
21005
  var DEFAULT_TTL_SECONDS2 = 86400;
21006
+ function toDecision(result) {
21007
+ if (result === "allowed") return "allow";
21008
+ return "deny";
21009
+ }
21010
+ function buildAuditCredential(record, issuerDid) {
21011
+ const subject = {
21012
+ id: record.id,
21013
+ agentId: record.agentId,
21014
+ ...record.userId ? { principalId: record.userId } : {},
21015
+ operation: record.action,
21016
+ target: record.resource,
21017
+ decision: toDecision(record.result),
21018
+ ...record.reason ? { policyName: record.reason } : {},
21019
+ timestamp: record.timestamp.toISOString(),
21020
+ kavachosVersion: KAVACHOS_VERSION
21021
+ };
21022
+ return {
21023
+ "@context": [VC_CONTEXT_V2, KAVACHOS_AUDIT_CONTEXT],
21024
+ id: `urn:uuid:${generateId()}`,
21025
+ type: [VC_TYPE_CREDENTIAL, KAVACHOS_AUDIT_CREDENTIAL],
21026
+ issuer: issuerDid,
21027
+ issuanceDate: (/* @__PURE__ */ new Date()).toISOString(),
21028
+ expirationDate: new Date(Date.now() + DEFAULT_TTL_SECONDS2 * 1e3).toISOString(),
21029
+ // Cast: AuditCredentialSubject is intentionally wider than CredentialSubject
21030
+ // because the VC schema uses an open-ended subject. The additional fields
21031
+ // (operation, target, decision, etc.) are preserved via spread at runtime.
21032
+ credentialSubject: subject
21033
+ };
21034
+ }
21035
+ async function signAsJsonLd(credential, config) {
21036
+ const { issuerDid, privateKeyJwk } = config;
21037
+ const kid = `${issuerDid}#${issuerDid.split(":").pop() ?? "key-1"}`;
21038
+ const key = await importJWK(privateKeyJwk, "EdDSA");
21039
+ const { proof: _proof, ...vcWithoutProof } = credential;
21040
+ const payload = new TextEncoder().encode(JSON.stringify(vcWithoutProof));
21041
+ const jws = await new CompactSign(payload).setProtectedHeader({ alg: "EdDSA", kid }).sign(key);
21042
+ const proof = {
21043
+ type: "JsonWebSignature2020",
21044
+ created: (/* @__PURE__ */ new Date()).toISOString(),
21045
+ verificationMethod: kid,
21046
+ proofPurpose: "assertionMethod",
21047
+ jws
21048
+ };
21049
+ return { ...credential, proof };
21050
+ }
21051
+ async function signAsJwt(credential, config) {
21052
+ const { issuerDid, privateKeyJwk } = config;
21053
+ const ttl = config.defaultTtl ?? DEFAULT_TTL_SECONDS2;
21054
+ const kid = `${issuerDid}#${issuerDid.split(":").pop() ?? "key-1"}`;
21055
+ const key = await importJWK(privateKeyJwk, "EdDSA");
21056
+ const { proof: _proof, ...vcWithoutProof } = credential;
21057
+ const builder = new SignJWT({ vc: vcWithoutProof }).setProtectedHeader({ alg: "EdDSA", kid, typ: "JWT" }).setIssuer(issuerDid).setIssuedAt().setExpirationTime(Math.floor(Date.now() / 1e3) + ttl);
21058
+ if (credential.id) builder.setJti(credential.id);
21059
+ if (credential.credentialSubject.id) builder.setSubject(credential.credentialSubject.id);
21060
+ const jwt = await builder.sign(key);
21061
+ return { credential, jwt };
21062
+ }
21063
+ async function signPresentationAsJsonLd(presentation, config) {
21064
+ const { issuerDid, privateKeyJwk } = config;
21065
+ const kid = `${issuerDid}#${issuerDid.split(":").pop() ?? "key-1"}`;
21066
+ const key = await importJWK(privateKeyJwk, "EdDSA");
21067
+ const { proof: _proof, ...vpWithoutProof } = presentation;
21068
+ const payload = new TextEncoder().encode(JSON.stringify(vpWithoutProof));
21069
+ const jws = await new CompactSign(payload).setProtectedHeader({ alg: "EdDSA", kid }).sign(key);
21070
+ const proof = {
21071
+ type: "JsonWebSignature2020",
21072
+ created: (/* @__PURE__ */ new Date()).toISOString(),
21073
+ verificationMethod: kid,
21074
+ proofPurpose: "assertionMethod",
21075
+ jws
21076
+ };
21077
+ return { ...presentation, proof };
21078
+ }
21079
+ async function exportAuditAsVC(options) {
21080
+ const {
21081
+ since,
21082
+ until,
21083
+ issuerDid,
21084
+ issuerConfig,
21085
+ format = "ldp_vc",
21086
+ output = "individual",
21087
+ filter,
21088
+ records
21089
+ } = options;
21090
+ const inRange = records.filter((r) => {
21091
+ const t = r.timestamp.getTime();
21092
+ return t >= since.getTime() && t <= until.getTime();
21093
+ });
21094
+ const filtered = filter ? inRange.filter(filter) : inRange;
21095
+ if (filtered.length === 0) {
21096
+ return {
21097
+ credentials: [],
21098
+ format,
21099
+ issuedAt: /* @__PURE__ */ new Date(),
21100
+ count: 0
21101
+ };
21102
+ }
21103
+ const credentials = [];
21104
+ const jwts = [];
21105
+ for (const record of filtered) {
21106
+ const base = buildAuditCredential(record, issuerDid);
21107
+ if (format === "jwt_vc") {
21108
+ const { credential, jwt } = await signAsJwt(base, issuerConfig);
21109
+ credentials.push(credential);
21110
+ jwts.push(jwt);
21111
+ } else {
21112
+ const signed = await signAsJsonLd(base, issuerConfig);
21113
+ credentials.push(signed);
21114
+ }
21115
+ }
21116
+ const issuedAt = /* @__PURE__ */ new Date();
21117
+ if (output === "individual") {
21118
+ return {
21119
+ credentials,
21120
+ ...format === "jwt_vc" ? { jwts } : {},
21121
+ format,
21122
+ issuedAt,
21123
+ count: credentials.length
21124
+ };
21125
+ }
21126
+ const basePresentation = {
21127
+ "@context": [VC_CONTEXT_V2, KAVACHOS_AUDIT_CONTEXT],
21128
+ id: `urn:uuid:${generateId()}`,
21129
+ type: [VC_TYPE_PRESENTATION],
21130
+ holder: issuerDid,
21131
+ verifiableCredential: credentials
21132
+ };
21133
+ const presentation = format === "jwt_vc" ? basePresentation : await signPresentationAsJsonLd(basePresentation, issuerConfig);
21134
+ return {
21135
+ credentials,
21136
+ ...format === "jwt_vc" ? { jwts } : {},
21137
+ presentation,
21138
+ format,
21139
+ issuedAt,
21140
+ count: credentials.length
21141
+ };
21142
+ }
21143
+ function listAuditRecords(records, since, until, filter) {
21144
+ const inRange = records.filter((r) => {
21145
+ const t = r.timestamp.getTime();
21146
+ return t >= since.getTime() && t <= until.getTime();
21147
+ });
21148
+ return filter ? inRange.filter(filter) : inRange;
21149
+ }
21150
+ var DEFAULT_TTL_SECONDS3 = 86400;
20114
21151
  function makeError8(code2, message, details) {
20115
21152
  return { code: code2, message, ...{} };
20116
21153
  }
@@ -20121,9 +21158,9 @@ function futureISO(seconds) {
20121
21158
  return new Date(Date.now() + seconds * 1e3).toISOString();
20122
21159
  }
20123
21160
  function createVCIssuer(config) {
20124
- const { issuerDid, privateKeyJwk, defaultTtl = DEFAULT_TTL_SECONDS2 } = config;
21161
+ const { issuerDid, privateKeyJwk, defaultTtl = DEFAULT_TTL_SECONDS3 } = config;
20125
21162
  const kid = `${issuerDid}#${issuerDid.split(":").pop() ?? "key-1"}`;
20126
- async function signAsJwt(credential, subject, ttl) {
21163
+ async function signAsJwt2(credential, subject, ttl) {
20127
21164
  try {
20128
21165
  const key = await importJWK(privateKeyJwk, "EdDSA");
20129
21166
  const { proof: _proof, ...vcWithoutProof } = credential;
@@ -20148,13 +21185,13 @@ function createVCIssuer(config) {
20148
21185
  };
20149
21186
  }
20150
21187
  }
20151
- async function signAsJsonLd(credential) {
21188
+ async function signAsJsonLd2(credential) {
20152
21189
  try {
20153
21190
  const key = await importJWK(privateKeyJwk, "EdDSA");
20154
21191
  const { proof: _proof, ...vcWithoutProof } = credential;
20155
21192
  const payload = new TextEncoder().encode(JSON.stringify(vcWithoutProof));
20156
- const { CompactSign } = await import('jose');
20157
- const jws = await new CompactSign(payload).setProtectedHeader({ alg: "EdDSA", kid }).sign(key);
21193
+ const { CompactSign: CompactSign2 } = await import('jose');
21194
+ const jws = await new CompactSign2(payload).setProtectedHeader({ alg: "EdDSA", kid }).sign(key);
20158
21195
  const proof = {
20159
21196
  type: "JsonWebSignature2020",
20160
21197
  created: nowISO(),
@@ -20190,9 +21227,9 @@ function createVCIssuer(config) {
20190
21227
  }
20191
21228
  async function signCredential(credential, subject, ttl, format) {
20192
21229
  if (format === "jwt") {
20193
- return signAsJwt(credential, subject, ttl);
21230
+ return signAsJwt2(credential, subject, ttl);
20194
21231
  }
20195
- return signAsJsonLd(credential);
21232
+ return signAsJsonLd2(credential);
20196
21233
  }
20197
21234
  async function issueAgentCredential(input) {
20198
21235
  const {
@@ -20717,6 +21754,6 @@ async function verifyWebhookSignature3(secret, rawBody, signature) {
20717
21754
  return diff === 0;
20718
21755
  }
20719
21756
 
20720
- export { CredentialStatusSchema, CredentialSubjectSchema, EVENT_TYPES, HibpApiError, HibpBreachedError, KAVACH_AGENT_CREDENTIAL, KAVACH_DELEGATION_CREDENTIAL, KAVACH_PERMISSION_CREDENTIAL, KVStore, MemoryStore, MultiSessionLimitError, OAuthProxyError, OneTapVerifyError, ProofSchema, RefreshTokenError, SSO_ERROR, SsoError, VC_CONTEXT_V1, VC_CONTEXT_V2, VC_TYPE_CREDENTIAL, VC_TYPE_PRESENTATION, VerifiableCredentialSchema, VerifiablePresentationSchema, additionalFields, admin, agentCards, agentDids, agents, anonymousAuth, apiKeys2 as apiKeys, apiKeys as apiKeysTable, approvalRequests, auditLogs, bearerAuth, budgetPolicies, buildDidDocument, buildSessionMetadata, classifyViolation, constantTimeEqual, createAdditionalFieldsModule, createAdminModule, createAgentModule, createAnonymousAuthModule, createApiKeyManagerModule, createAppleProvider, createApprovalModule, createAuditModule, createCaptchaModule, createCookieSessionManager, createCostAttributionModule, createCustomSessionModule, createDatabase, createDatabaseSync, createDelegationModule, createDeviceAuthModule, createDidModule, createDiscordProvider, createEmailOtpModule, createEmailTemplates, createEmailVerificationModule, createEphemeralSessionModule, createEventStreamModule, createFederationModule, createGdprModule, createGithubProvider, createGitlabProvider, createGoogleProvider, createHibpModule, createI18n, createJwtSessionModule, createKavach, createLastLoginModule, createLinkedInProvider, createMagicLinkModule, createMicrosoftProvider, createMultiSessionModule, createOAuthModule, createOAuthProxyModule, createOidcProviderModule, createOneTapModule, createOneTimeTokenModule, createOpenApiModule, createOrgModule, createPasskeyModule, createPasswordResetModule, createPermissionEngine, createPhoneAuthModule, createPluginRouter, createPolarModule, createPolicyModule, createPresentation, createPrivilegeAnalyzer, createRateLimiter, createReBACModule, createRedirectChain, createScimModule, createSessionFreshnessModule, createSessionManager, createSessionRefresher, createSiweModule, createSlackProvider, createSsoModule, createStripeModule, createTables, createTenantModule, createTokenFamilyStore, createTotpModule, createTrustModule, createTrustedDeviceModule, createTwitterProvider, createUsernameAuthModule, createVCIssuer, createVCVerifier, createWebhookModule2 as createWebhookModule, customAuth, customSession, de, delegationChains, deviceAuth, deviceLabelFromRequest, emailOtp, emailOtps, en, es, fr, fromBase64Url, fromHex, gdpr, generateCsrfToken, generateDidKey, generateDidWeb, generateId, generateOpenAPISpec, getCookie2 as getCookie, getDidWebUrl, getPermissionTemplate, headerAuth, hmacSha1Raw, hmacSha256, hmacSha256Raw, importHmacKey, initializePlugins, ja, kvStore, magicLink, magicLinks, mcpServers, oauth, oauthAccessTokens, oauthAuthorizationCodes, oauthClients, oauthProxy, oneTap, orgInvitations, orgMembers, orgRoles, organization, organizations, parseCookies2 as parseCookies, parseCookiesFromRequest, passkey, passkeyChallenges, passkeyCredentials, pbkdf2Hash, pbkdf2Verify, permissionTemplates, permissions, polar, randomBytes, randomBytesHex, rateLimit, rateLimits, resolveDidKey, resolveDidWeb, scim, serializeCookie, serializeCookieDeletion, sessions, sha1, sha256, sha256Raw, signPayload2 as signPayload, siwe, ssoConnections, stripe, tenants, toBase64Url, toHex, totpRecords, trustScores, twoFactor, users, validateCsrfToken, validateOrigin, verifyPayload, verifyPresentation, verifyWebhookSignature3 as verifyWebhookSignature, withRateLimit, zh };
21757
+ export { CredentialStatusSchema, CredentialSubjectSchema, EVENT_TYPES, HibpApiError, HibpBreachedError, KAVACHOS_AUDIT_CONTEXT, KAVACHOS_AUDIT_CREDENTIAL, KAVACH_AGENT_CREDENTIAL, KAVACH_DELEGATION_CREDENTIAL, KAVACH_PERMISSION_CREDENTIAL, KVStore, MemoryStore, MultiSessionLimitError, OAuthProxyError, OneTapVerifyError, ProofSchema, RefreshTokenError, SSO_ERROR, SsoError, VC_CONTEXT_V1, VC_CONTEXT_V2, VC_TYPE_CREDENTIAL, VC_TYPE_PRESENTATION, VerifiableCredentialSchema, VerifiablePresentationSchema, additionalFields, admin, agentCards, agentDids, agents, anonymousAuth, apiKeys2 as apiKeys, apiKeys as apiKeysTable, approvalRequests, auditLogs, bearerAuth, budgetPolicies, buildDidDocument, buildSessionMetadata, classifyViolation, constantTimeEqual, createAdditionalFieldsModule, createAdminModule, createAgentModule, createAnonymousAuthModule, createApiKeyManagerModule, createAppleProvider, createApprovalModule, createAuditModule, createCaptchaModule, createCookieSessionManager, createCostAttributionModule, createCustomSessionModule, createDatabase, createDatabaseSync, createDelegationModule, createDeviceAuthModule, createDidModule, createDiscordProvider, createEmailOtpModule, createEmailTemplates, createEmailVerificationModule, createEphemeralSessionModule, createEventStreamModule, createFederationModule, createGdprModule, createGithubProvider, createGitlabProvider, createGoogleProvider, createHibpModule, createI18n, createJwtSessionModule, createKavach, createLastLoginModule, createLinkedInProvider, createMagicLinkModule, createMicrosoftProvider, createMultiSessionModule, createOAuthModule, createOAuthProxyModule, createOidcProviderModule, createOneTapModule, createOneTimeTokenModule, createOpenApiModule, createOrgModule, createPasskeyModule, createPasswordResetModule, createPermissionEngine, createPhoneAuthModule, createPluginRouter, createPolarModule, createPolicyModule, createPresentation, createPrivilegeAnalyzer, createRateLimiter, createReBACModule, createRedirectChain, createScimModule, createSessionFreshnessModule, createSessionManager, createSessionRefresher, createSiweModule, createSlackProvider, createSsoModule, createStripeModule, createTables, createTenantModule, createTokenFamilyStore, createTotpModule, createTrustModule, createTrustedDeviceModule, createTwitterProvider, createUsernameAuthModule, createVCIssuer, createVCVerifier, createWebhookModule2 as createWebhookModule, customAuth, customSession, de, delegationChains, deviceAuth, deviceLabelFromRequest, emailOtp, emailOtps, en, es, exportAuditAsVC, fr, fromBase64Url, fromHex, gdpr, generateCsrfToken, generateDidKey, generateDidWeb, generateId, generateOpenAPISpec, getCookie2 as getCookie, getDidWebUrl, getPermissionTemplate, headerAuth, hmacSha1Raw, hmacSha256, hmacSha256Raw, importHmacKey, initializePlugins, ja, kvStore, listAuditRecords, magicLink, magicLinks, mcpServers, oauth, oauthAccessTokens, oauthAuthorizationCodes, oauthClients, oauthProxy, oneTap, orgInvitations, orgMembers, orgRoles, organization, organizations, parseCookies2 as parseCookies, parseCookiesFromRequest, passkey, passkeyChallenges, passkeyCredentials, pbkdf2Hash, pbkdf2Verify, permissionTemplates, permissions, polar, randomBytes, randomBytesHex, rateLimit, rateLimits, resolveDidKey, resolveDidWeb, scim, serializeCookie, serializeCookieDeletion, sessions, sha1, sha256, sha256Raw, signPayload2 as signPayload, siwe, ssoConnections, stripe, tenants, toBase64Url, toHex, totpRecords, trustScores, twoFactor, users, validateCsrfToken, validateOrigin, verifyPayload, verifyPresentation, verifyWebhookSignature3 as verifyWebhookSignature, withRateLimit, zh };
20721
21758
  //# sourceMappingURL=index.js.map
20722
21759
  //# sourceMappingURL=index.js.map