kavachos 0.3.0 → 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 +32 -4
- package/dist/index.js +851 -67
- 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
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { D as Database, A as AgentIdentity, i as AuthorizeRequest, j as AuthorizeResult, P as Permission } from '../types-
|
|
2
|
-
export {
|
|
1
|
+
import { D as Database, A as AgentIdentity, i as AuthorizeRequest, j as AuthorizeResult, P as Permission } from '../types-RJPOU4un.js';
|
|
2
|
+
export { ar as PermissionConstraints } from '../types-RJPOU4un.js';
|
|
3
3
|
import 'drizzle-orm/sqlite-core';
|
|
4
|
-
import '../types-
|
|
4
|
+
import '../types-BiUe9e8u.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
import '../redirect/index.js';
|
|
7
7
|
|
|
@@ -11,6 +11,11 @@ interface PermissionEngineConfig {
|
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
13
13
|
* Create the permission/authorization engine.
|
|
14
|
+
*
|
|
15
|
+
* This remains the public entry point used by adapters. The constraint and
|
|
16
|
+
* matching primitives now live in policy/abac.ts so the new unified policy
|
|
17
|
+
* engine can reuse them. A follow-on patch rewires this function to delegate
|
|
18
|
+
* to policy/engine.ts; today it still performs direct-permission evaluation.
|
|
14
19
|
*/
|
|
15
20
|
declare function createPermissionEngine(config: PermissionEngineConfig): {
|
|
16
21
|
authorize: (agent: AgentIdentity, request: AuthorizeRequest) => Promise<AuthorizeResult>;
|
package/dist/permission/index.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import { and, eq, gte } from 'drizzle-orm';
|
|
2
1
|
import { sqliteTable, integer, text } from 'drizzle-orm/sqlite-core';
|
|
3
|
-
|
|
4
|
-
// src/permission/engine.ts
|
|
2
|
+
import { and, eq, gte } from 'drizzle-orm';
|
|
5
3
|
|
|
6
4
|
// src/crypto/web-crypto.ts
|
|
7
5
|
function generateId() {
|
|
@@ -76,6 +74,8 @@ sqliteTable("kavach_permissions", {
|
|
|
76
74
|
actions: text("actions", { mode: "json" }).notNull().$type(),
|
|
77
75
|
// ["read", "write", "execute"]
|
|
78
76
|
constraints: text("constraints", { mode: "json" }).$type(),
|
|
77
|
+
// When set, the policy engine consults the ReBAC graph for this permission.
|
|
78
|
+
relation: text("relation"),
|
|
79
79
|
createdAt: integer("created_at", { mode: "timestamp" }).notNull()
|
|
80
80
|
});
|
|
81
81
|
sqliteTable("kavach_delegation_chains", {
|
|
@@ -105,6 +105,8 @@ var auditLogs = sqliteTable("kavach_audit_logs", {
|
|
|
105
105
|
tokensCost: integer("tokens_cost"),
|
|
106
106
|
ip: text("ip"),
|
|
107
107
|
userAgent: text("user_agent"),
|
|
108
|
+
// True when this audit row corresponds to a policy-engine cache-hit evaluation.
|
|
109
|
+
cacheHit: integer("cache_hit", { mode: "boolean" }).notNull().default(false),
|
|
108
110
|
timestamp: integer("timestamp", { mode: "timestamp" }).notNull()
|
|
109
111
|
});
|
|
110
112
|
var rateLimits = sqliteTable("kavach_rate_limits", {
|
|
@@ -541,8 +543,6 @@ sqliteTable("kavach_refresh_tokens", {
|
|
|
541
543
|
expiresAt: integer("expires_at", { mode: "timestamp" }).notNull(),
|
|
542
544
|
createdAt: integer("created_at", { mode: "timestamp" }).notNull()
|
|
543
545
|
});
|
|
544
|
-
|
|
545
|
-
// src/permission/engine.ts
|
|
546
546
|
function matchResource(pattern, resource) {
|
|
547
547
|
if (pattern === "*") return true;
|
|
548
548
|
const patternParts = pattern.split(":");
|
|
@@ -600,6 +600,9 @@ function validateArgPatterns(patterns, args) {
|
|
|
600
600
|
return { valid: true };
|
|
601
601
|
}
|
|
602
602
|
async function checkRateLimit(db, agentId, resource, maxCallsPerHour) {
|
|
603
|
+
if (!agentId) {
|
|
604
|
+
return { allowed: true };
|
|
605
|
+
}
|
|
603
606
|
const oneHourAgo = new Date(Date.now() - 60 * 60 * 1e3);
|
|
604
607
|
const rows = await db.select().from(rateLimits).where(
|
|
605
608
|
and(
|
|
@@ -630,66 +633,20 @@ async function checkRateLimit(db, agentId, resource, maxCallsPerHour) {
|
|
|
630
633
|
}
|
|
631
634
|
return { allowed: true };
|
|
632
635
|
}
|
|
633
|
-
function
|
|
634
|
-
const { db, auditAll } = config;
|
|
635
|
-
async function authorize(agent, request) {
|
|
636
|
-
const startTime = performance.now();
|
|
637
|
-
const auditId = generateId();
|
|
638
|
-
const matchingPermission = agent.permissions.find(
|
|
639
|
-
(p) => matchResource(p.resource, request.resource) && matchAction(p.actions, request.action)
|
|
640
|
-
);
|
|
641
|
-
if (!matchingPermission) {
|
|
642
|
-
const result2 = {
|
|
643
|
-
allowed: false,
|
|
644
|
-
reason: `No permission grants agent "${agent.name}" access to "${request.action}" on "${request.resource}"`,
|
|
645
|
-
auditId
|
|
646
|
-
};
|
|
647
|
-
if (auditAll) {
|
|
648
|
-
await writeAuditLog(db, agent, request, result2, startTime, auditId);
|
|
649
|
-
}
|
|
650
|
-
return result2;
|
|
651
|
-
}
|
|
652
|
-
if (matchingPermission.constraints) {
|
|
653
|
-
const constraintResult = await evaluateConstraints(
|
|
654
|
-
db,
|
|
655
|
-
agent,
|
|
656
|
-
request,
|
|
657
|
-
matchingPermission.constraints
|
|
658
|
-
);
|
|
659
|
-
if (!constraintResult.allowed) {
|
|
660
|
-
const result2 = {
|
|
661
|
-
allowed: false,
|
|
662
|
-
reason: constraintResult.reason,
|
|
663
|
-
auditId
|
|
664
|
-
};
|
|
665
|
-
if (auditAll) {
|
|
666
|
-
await writeAuditLog(db, agent, request, result2, startTime, auditId);
|
|
667
|
-
}
|
|
668
|
-
return result2;
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
const result = { allowed: true, auditId };
|
|
672
|
-
if (auditAll) {
|
|
673
|
-
await writeAuditLog(db, agent, request, result, startTime, auditId);
|
|
674
|
-
}
|
|
675
|
-
return result;
|
|
676
|
-
}
|
|
677
|
-
return { authorize };
|
|
678
|
-
}
|
|
679
|
-
async function evaluateConstraints(db, agent, request, constraints) {
|
|
636
|
+
async function evaluateConstraints(db, input, constraints) {
|
|
680
637
|
if (constraints.maxCallsPerHour) {
|
|
681
638
|
const rateResult = await checkRateLimit(
|
|
682
639
|
db,
|
|
683
|
-
|
|
684
|
-
|
|
640
|
+
input.subjectId,
|
|
641
|
+
input.resource,
|
|
685
642
|
constraints.maxCallsPerHour
|
|
686
643
|
);
|
|
687
644
|
if (!rateResult.allowed) {
|
|
688
645
|
return rateResult;
|
|
689
646
|
}
|
|
690
647
|
}
|
|
691
|
-
if (constraints.allowedArgPatterns &&
|
|
692
|
-
const patternResult = validateArgPatterns(constraints.allowedArgPatterns,
|
|
648
|
+
if (constraints.allowedArgPatterns && input.arguments) {
|
|
649
|
+
const patternResult = validateArgPatterns(constraints.allowedArgPatterns, input.arguments);
|
|
693
650
|
if (!patternResult.valid) {
|
|
694
651
|
return { allowed: false, reason: patternResult.reason };
|
|
695
652
|
}
|
|
@@ -713,21 +670,73 @@ async function evaluateConstraints(db, agent, request, constraints) {
|
|
|
713
670
|
}
|
|
714
671
|
}
|
|
715
672
|
if (constraints.ipAllowlist && constraints.ipAllowlist.length > 0) {
|
|
716
|
-
if (!
|
|
673
|
+
if (!input.ip) {
|
|
717
674
|
return {
|
|
718
675
|
allowed: false,
|
|
719
676
|
reason: "IP_NOT_ALLOWED: No IP address provided; resource requires an IP allowlist match"
|
|
720
677
|
};
|
|
721
678
|
}
|
|
722
|
-
if (!isIPAllowed(constraints.ipAllowlist,
|
|
679
|
+
if (!isIPAllowed(constraints.ipAllowlist, input.ip)) {
|
|
723
680
|
return {
|
|
724
681
|
allowed: false,
|
|
725
|
-
reason: `IP_NOT_ALLOWED: IP "${
|
|
682
|
+
reason: `IP_NOT_ALLOWED: IP "${input.ip}" is not in the allowlist for this resource`
|
|
726
683
|
};
|
|
727
684
|
}
|
|
728
685
|
}
|
|
729
686
|
return { allowed: true };
|
|
730
687
|
}
|
|
688
|
+
|
|
689
|
+
// src/permission/engine.ts
|
|
690
|
+
function createPermissionEngine(config) {
|
|
691
|
+
const { db, auditAll } = config;
|
|
692
|
+
async function authorize(agent, request) {
|
|
693
|
+
const startTime = performance.now();
|
|
694
|
+
const auditId = generateId();
|
|
695
|
+
const matchingPermission = agent.permissions.find(
|
|
696
|
+
(p) => matchResource(p.resource, request.resource) && matchAction(p.actions, request.action)
|
|
697
|
+
);
|
|
698
|
+
if (!matchingPermission) {
|
|
699
|
+
const result2 = {
|
|
700
|
+
allowed: false,
|
|
701
|
+
reason: `No permission grants agent "${agent.name}" access to "${request.action}" on "${request.resource}"`,
|
|
702
|
+
auditId
|
|
703
|
+
};
|
|
704
|
+
if (auditAll) {
|
|
705
|
+
await writeAuditLog(db, agent, request, result2, startTime, auditId);
|
|
706
|
+
}
|
|
707
|
+
return result2;
|
|
708
|
+
}
|
|
709
|
+
if (matchingPermission.constraints) {
|
|
710
|
+
const constraintResult = await evaluateConstraints(
|
|
711
|
+
db,
|
|
712
|
+
{
|
|
713
|
+
subjectId: agent.id,
|
|
714
|
+
resource: request.resource,
|
|
715
|
+
arguments: request.arguments,
|
|
716
|
+
ip: request.ip
|
|
717
|
+
},
|
|
718
|
+
matchingPermission.constraints
|
|
719
|
+
);
|
|
720
|
+
if (!constraintResult.allowed) {
|
|
721
|
+
const result2 = {
|
|
722
|
+
allowed: false,
|
|
723
|
+
reason: constraintResult.reason,
|
|
724
|
+
auditId
|
|
725
|
+
};
|
|
726
|
+
if (auditAll) {
|
|
727
|
+
await writeAuditLog(db, agent, request, result2, startTime, auditId);
|
|
728
|
+
}
|
|
729
|
+
return result2;
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
const result = { allowed: true, auditId };
|
|
733
|
+
if (auditAll) {
|
|
734
|
+
await writeAuditLog(db, agent, request, result, startTime, auditId);
|
|
735
|
+
}
|
|
736
|
+
return result;
|
|
737
|
+
}
|
|
738
|
+
return { authorize };
|
|
739
|
+
}
|
|
731
740
|
async function writeAuditLog(db, agent, request, result, startTime, auditId) {
|
|
732
741
|
const durationMs = Math.round(performance.now() - startTime);
|
|
733
742
|
await db.insert(auditLogs).values({
|