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/a2a/index.d.ts +2 -2
- package/dist/agent/index.d.ts +3 -3
- package/dist/agent/index.js +4 -0
- package/dist/agent/index.js.map +1 -1
- package/dist/audit/index.d.ts +2 -2
- package/dist/audit/index.js +4 -0
- package/dist/audit/index.js.map +1 -1
- package/dist/auth/index.d.ts +64 -3
- package/dist/auth/index.js +91 -2
- package/dist/auth/index.js.map +1 -1
- package/dist/index.d.ts +40 -6
- package/dist/index.js +1239 -202
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +2 -2
- package/dist/mcp/index.js +38 -1
- package/dist/mcp/index.js.map +1 -1
- package/dist/permission/index.d.ts +8 -3
- package/dist/permission/index.js +68 -59
- package/dist/permission/index.js.map +1 -1
- package/dist/{types-BuHrZcjE.d.ts → types-BiUe9e8u.d.ts} +24 -0
- package/dist/{types-B02D3kZy.d.ts → types-RJPOU4un.d.ts} +114 -2
- package/dist/vc/index.d.ts +254 -65
- package/dist/vc/index.js +160 -12
- package/dist/vc/index.js.map +1 -1
- package/package.json +2 -1
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15911
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15974
|
-
|
|
15975
|
-
|
|
15976
|
-
|
|
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
|
-
|
|
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
|
-
|
|
15994
|
-
|
|
15995
|
-
|
|
15996
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16009
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16022
|
-
|
|
16023
|
-
|
|
16024
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16036
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16050
|
-
|
|
16051
|
-
|
|
16052
|
-
|
|
16053
|
-
|
|
16054
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
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
|
-
|
|
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
|
-
|
|
16098
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
17311
|
-
|
|
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 &&
|
|
17319
|
-
const patternResult = validateArgPatterns(constraints.allowedArgPatterns,
|
|
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 (!
|
|
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,
|
|
17650
|
+
if (!isIPAllowed(constraints.ipAllowlist, input.ip)) {
|
|
17350
17651
|
return {
|
|
17351
17652
|
allowed: false,
|
|
17352
|
-
reason: `IP_NOT_ALLOWED: IP "${
|
|
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/
|
|
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 =
|
|
21161
|
+
const { issuerDid, privateKeyJwk, defaultTtl = DEFAULT_TTL_SECONDS3 } = config;
|
|
20125
21162
|
const kid = `${issuerDid}#${issuerDid.split(":").pop() ?? "key-1"}`;
|
|
20126
|
-
async function
|
|
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
|
|
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
|
|
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
|
|
21230
|
+
return signAsJwt2(credential, subject, ttl);
|
|
20194
21231
|
}
|
|
20195
|
-
return
|
|
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
|