@sentinel-atl/stepup 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # @sentinel-atl/stepup
2
+
3
+ Step-up authentication — re-prompt humans for sensitive agent actions.
4
+
5
+ ## Features
6
+
7
+ - **Policy-based triggers** — define when step-up auth is required (scope, risk, time-based)
8
+ - **Challenge-response** — time-bounded, single-use approval tokens
9
+ - **Multi-factor** — support for TOTP, biometric, and custom challenge types
10
+ - **Audit integration** — all step-up events logged
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install @sentinel-atl/stepup
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```ts
21
+ import { StepUpManager } from '@sentinel-atl/stepup';
22
+
23
+ const mgr = new StepUpManager({
24
+ auditLog,
25
+ policies: [
26
+ { trigger: 'scope', scopes: ['admin:*'], challengeType: 'totp' },
27
+ { trigger: 'risk_score', threshold: 0.8, challengeType: 'biometric' },
28
+ ],
29
+ });
30
+
31
+ // Check if step-up is needed
32
+ const result = mgr.evaluate({
33
+ agentDid: 'did:key:z6Mk...',
34
+ requestedScopes: ['admin:delete'],
35
+ });
36
+
37
+ if (result.required) {
38
+ // Present challenge to human
39
+ const challenge = mgr.createChallenge(result);
40
+ // ... human responds ...
41
+ const approval = mgr.verifyResponse(challenge, response);
42
+ }
43
+ ```
44
+
45
+ ## API
46
+
47
+ | Method | Description |
48
+ |---|---|
49
+ | `new StepUpManager(config)` | Create manager with policies |
50
+ | `evaluate(context)` | Check if step-up is required |
51
+ | `createChallenge(result)` | Create a time-bounded challenge |
52
+ | `verifyResponse(challenge, response)` | Verify human response |
53
+
54
+ ## License
55
+
56
+ MIT
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=stepup.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stepup.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/stepup.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,137 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { StepUpManager } from '../index.js';
3
+ import { InMemoryKeyProvider, publicKeyToDid } from '@sentinel-atl/core';
4
+ async function makeIdentity(kp, name) {
5
+ await kp.generate(name);
6
+ const pubKey = await kp.getPublicKey(name);
7
+ return { keyId: name, did: publicKeyToDid(pubKey) };
8
+ }
9
+ describe('@sentinel-atl/stepup', () => {
10
+ let manager;
11
+ let principalKP;
12
+ let principal;
13
+ let agentKP;
14
+ let agent;
15
+ beforeEach(async () => {
16
+ principalKP = new InMemoryKeyProvider();
17
+ principal = await makeIdentity(principalKP, 'human');
18
+ agentKP = new InMemoryKeyProvider();
19
+ agent = await makeIdentity(agentKP, 'agent');
20
+ manager = new StepUpManager({
21
+ alwaysRequireActions: ['delete_account', 'transfer_funds'],
22
+ sensitivityLevels: ['high', 'critical'],
23
+ challengeTimeoutMs: 5 * 60_000,
24
+ maxPendingChallenges: 3,
25
+ });
26
+ });
27
+ // ─── requiresStepUp ────────────────────────────────────────────
28
+ describe('requiresStepUp', () => {
29
+ it('requires step-up for explicit actions', () => {
30
+ const result = manager.requiresStepUp('delete_account');
31
+ expect(result.required).toBe(true);
32
+ expect(result.trigger).toBe('policy_rule');
33
+ });
34
+ it('requires step-up for high sensitivity', () => {
35
+ const result = manager.requiresStepUp('some_action', 'high');
36
+ expect(result.required).toBe(true);
37
+ expect(result.trigger).toBe('sensitivity_high');
38
+ });
39
+ it('requires step-up for critical sensitivity', () => {
40
+ const result = manager.requiresStepUp('some_action', 'critical');
41
+ expect(result.required).toBe(true);
42
+ expect(result.trigger).toBe('sensitivity_critical');
43
+ });
44
+ it('does not require step-up for low sensitivity', () => {
45
+ const result = manager.requiresStepUp('read_email', 'low');
46
+ expect(result.required).toBe(false);
47
+ });
48
+ it('does not require step-up for unknown actions', () => {
49
+ const result = manager.requiresStepUp('read_email');
50
+ expect(result.required).toBe(false);
51
+ });
52
+ });
53
+ // ─── Challenge creation ────────────────────────────────────────
54
+ describe('challenges', () => {
55
+ it('creates a challenge', () => {
56
+ const challenge = manager.createChallenge(agent.did, principal.did, 'delete_account', ['admin:delete'], 'policy_rule', 'Delete user account #12345');
57
+ expect(challenge.challengeId).toMatch(/^stepup-/);
58
+ expect(challenge.agentDid).toBe(agent.did);
59
+ expect(challenge.principalDid).toBe(principal.did);
60
+ expect(challenge.action).toBe('delete_account');
61
+ expect(challenge.nonce).toBeDefined();
62
+ expect(challenge.expiresAt).toBeDefined();
63
+ expect(manager.getPendingCount()).toBe(1);
64
+ });
65
+ it('enforces max pending challenges', () => {
66
+ for (let i = 0; i < 3; i++) {
67
+ manager.createChallenge(agent.did, principal.did, `action_${i}`, [], 'policy_rule', `Action ${i}`);
68
+ }
69
+ expect(() => {
70
+ manager.createChallenge(agent.did, principal.did, 'action_4', [], 'policy_rule', 'Action 4');
71
+ }).toThrow('Max pending challenges');
72
+ });
73
+ it('cancels a challenge', () => {
74
+ const challenge = manager.createChallenge(agent.did, principal.did, 'test', [], 'policy_rule', 'Test');
75
+ expect(manager.getPendingCount()).toBe(1);
76
+ manager.cancelChallenge(challenge.challengeId);
77
+ expect(manager.getPendingCount()).toBe(0);
78
+ });
79
+ });
80
+ // ─── Approval flow ─────────────────────────────────────────────
81
+ describe('approval flow', () => {
82
+ let challenge;
83
+ beforeEach(() => {
84
+ challenge = manager.createChallenge(agent.did, principal.did, 'transfer_funds', ['payment:transfer'], 'sensitivity_high', 'Transfer $5,000 to vendor');
85
+ });
86
+ it('approves with valid principal signature', async () => {
87
+ const approval = await manager.signApproval(principalKP, principal.keyId, challenge, 'approved');
88
+ const result = await manager.verifyApproval(approval);
89
+ expect(result.approved).toBe(true);
90
+ expect(result.challengeId).toBe(challenge.challengeId);
91
+ });
92
+ it('handles denial', async () => {
93
+ const approval = await manager.signApproval(principalKP, principal.keyId, challenge, 'denied');
94
+ const result = await manager.verifyApproval(approval);
95
+ expect(result.approved).toBe(false);
96
+ expect(result.error).toContain('Denied by principal');
97
+ });
98
+ it('rejects wrong signer', async () => {
99
+ // Agent tries to approve instead of principal
100
+ const fakeApproval = await manager.signApproval(agentKP, agent.keyId, challenge, 'approved');
101
+ // Override the principalDid to match challenge (spoofing attempt)
102
+ // The signature won't match principal's key
103
+ const result = await manager.verifyApproval(fakeApproval);
104
+ expect(result.approved).toBe(false);
105
+ });
106
+ it('prevents replay (second use of same challenge)', async () => {
107
+ const approval = await manager.signApproval(principalKP, principal.keyId, challenge, 'approved');
108
+ // First use succeeds
109
+ const r1 = await manager.verifyApproval(approval);
110
+ expect(r1.approved).toBe(true);
111
+ // Replay fails (challenge consumed)
112
+ const r2 = await manager.verifyApproval(approval);
113
+ expect(r2.approved).toBe(false);
114
+ expect(r2.error).toContain('not found or already consumed');
115
+ });
116
+ it('rejects expired challenge', async () => {
117
+ // Create manager with 0ms timeout
118
+ const fastManager = new StepUpManager({ challengeTimeoutMs: 0 });
119
+ const expiredChallenge = fastManager.createChallenge(agent.did, principal.did, 'test', [], 'policy_rule', 'Expired test');
120
+ // Wait a tick for expiry
121
+ await new Promise(r => setTimeout(r, 5));
122
+ const approval = await fastManager.signApproval(principalKP, principal.keyId, expiredChallenge, 'approved');
123
+ const result = await fastManager.verifyApproval(approval);
124
+ expect(result.approved).toBe(false);
125
+ expect(result.error).toContain('expired');
126
+ });
127
+ it('rejects principal DID mismatch', async () => {
128
+ const approval = await manager.signApproval(principalKP, principal.keyId, challenge, 'approved');
129
+ // Tamper with the principal DID
130
+ approval.principalDid = agent.did;
131
+ const result = await manager.verifyApproval(approval);
132
+ expect(result.approved).toBe(false);
133
+ expect(result.error).toContain('mismatch');
134
+ });
135
+ });
136
+ });
137
+ //# sourceMappingURL=stepup.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stepup.test.js","sourceRoot":"","sources":["../../src/__tests__/stepup.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * @sentinel-atl/stepup — Step-Up Authentication for Sensitive Actions
3
+ *
4
+ * When an agent is about to do something high-sensitivity — authorize a
5
+ * large payment, delete data, modify permissions — the trust pipeline
6
+ * should PAUSE and ask the human principal to re-confirm.
7
+ *
8
+ * This is the "Are you sure?" for AI agents, but cryptographically backed.
9
+ *
10
+ * How it works:
11
+ *
12
+ * 1. Agent detects a sensitive action (via VC sensitivity level or policy rules)
13
+ * 2. Agent creates a `StepUpChallenge` describing what it wants to do
14
+ * 3. Challenge is sent to the human principal
15
+ * 4. Human signs an `StepUpApproval` (proving they reviewed + approved)
16
+ * 5. Agent proceeds only if the approval signature is valid and timely
17
+ *
18
+ * The challenge is time-bounded and single-use to prevent replay.
19
+ */
20
+ import { type KeyProvider, type SensitivityLevel } from '@sentinel-atl/core';
21
+ import { AuditLog } from '@sentinel-atl/audit';
22
+ export interface StepUpChallenge {
23
+ /** Unique challenge ID */
24
+ challengeId: string;
25
+ /** The agent requesting approval */
26
+ agentDid: string;
27
+ /** The human principal being asked to approve */
28
+ principalDid: string;
29
+ /** Human-readable description of the action */
30
+ actionDescription: string;
31
+ /** Machine-readable action identifier */
32
+ action: string;
33
+ /** Scope being requested */
34
+ scope: string[];
35
+ /** Why step-up was triggered */
36
+ triggerReason: StepUpTrigger;
37
+ /** When the challenge expires (ISO 8601) */
38
+ expiresAt: string;
39
+ /** One-time nonce */
40
+ nonce: string;
41
+ /** Created timestamp */
42
+ createdAt: string;
43
+ }
44
+ export interface StepUpApproval {
45
+ /** The challenge being approved */
46
+ challengeId: string;
47
+ /** The principal who approved it */
48
+ principalDid: string;
49
+ /** Approval or denial */
50
+ decision: 'approved' | 'denied';
51
+ /** When the decision was made */
52
+ decidedAt: string;
53
+ /** Ed25519 signature over the approval data (base64url) */
54
+ signature: string;
55
+ }
56
+ export type StepUpTrigger = 'sensitivity_high' | 'sensitivity_critical' | 'amount_threshold' | 'scope_escalation' | 'first_use' | 'anomaly_detected' | 'policy_rule';
57
+ export interface StepUpPolicy {
58
+ /** Actions that always require step-up */
59
+ alwaysRequireActions?: string[];
60
+ /** Sensitivity levels that trigger step-up (default: ['high', 'critical']) */
61
+ sensitivityLevels?: SensitivityLevel[];
62
+ /** Challenge timeout in ms (default: 5 minutes) */
63
+ challengeTimeoutMs?: number;
64
+ /** Maximum pending challenges per agent */
65
+ maxPendingChallenges?: number;
66
+ }
67
+ export interface StepUpResult {
68
+ approved: boolean;
69
+ error?: string;
70
+ challengeId?: string;
71
+ }
72
+ export declare class StepUpManager {
73
+ private pendingChallenges;
74
+ private usedNonces;
75
+ private policy;
76
+ private auditLog?;
77
+ constructor(policy?: StepUpPolicy, auditLog?: AuditLog);
78
+ /**
79
+ * Check if an action requires step-up authentication.
80
+ */
81
+ requiresStepUp(action: string, sensitivityLevel?: SensitivityLevel): {
82
+ required: boolean;
83
+ trigger?: StepUpTrigger;
84
+ };
85
+ /**
86
+ * Create a step-up challenge for the human principal to approve.
87
+ */
88
+ createChallenge(agentDid: string, principalDid: string, action: string, scope: string[], trigger: StepUpTrigger, actionDescription: string): StepUpChallenge;
89
+ /**
90
+ * Principal signs an approval for a challenge.
91
+ */
92
+ signApproval(keyProvider: KeyProvider, principalKeyId: string, challenge: StepUpChallenge, decision: 'approved' | 'denied'): Promise<StepUpApproval>;
93
+ /**
94
+ * Verify a step-up approval and consume the challenge.
95
+ *
96
+ * This is the critical gate: if the approval is invalid, expired,
97
+ * or replayed, the action MUST NOT proceed.
98
+ */
99
+ verifyApproval(approval: StepUpApproval): Promise<StepUpResult>;
100
+ /**
101
+ * Get a pending challenge by ID.
102
+ */
103
+ getChallenge(challengeId: string): StepUpChallenge | undefined;
104
+ /**
105
+ * Get count of pending challenges.
106
+ */
107
+ getPendingCount(): number;
108
+ /**
109
+ * Cancel a pending challenge.
110
+ */
111
+ cancelChallenge(challengeId: string): boolean;
112
+ }
113
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,186 @@
1
+ /**
2
+ * @sentinel-atl/stepup — Step-Up Authentication for Sensitive Actions
3
+ *
4
+ * When an agent is about to do something high-sensitivity — authorize a
5
+ * large payment, delete data, modify permissions — the trust pipeline
6
+ * should PAUSE and ask the human principal to re-confirm.
7
+ *
8
+ * This is the "Are you sure?" for AI agents, but cryptographically backed.
9
+ *
10
+ * How it works:
11
+ *
12
+ * 1. Agent detects a sensitive action (via VC sensitivity level or policy rules)
13
+ * 2. Agent creates a `StepUpChallenge` describing what it wants to do
14
+ * 3. Challenge is sent to the human principal
15
+ * 4. Human signs an `StepUpApproval` (proving they reviewed + approved)
16
+ * 5. Agent proceeds only if the approval signature is valid and timely
17
+ *
18
+ * The challenge is time-bounded and single-use to prevent replay.
19
+ */
20
+ import { toBase64Url, fromBase64Url, textToBytes, secureRandom, verify, toHex, didToPublicKey, } from '@sentinel-atl/core';
21
+ // ─── Canonicalization ────────────────────────────────────────────────
22
+ function canonicalizeChallenge(challenge) {
23
+ return textToBytes(`stepup:${challenge.challengeId}:${challenge.agentDid}:${challenge.principalDid}:${challenge.action}:${challenge.nonce}:${challenge.expiresAt}`);
24
+ }
25
+ // ─── Step-Up Manager ─────────────────────────────────────────────────
26
+ export class StepUpManager {
27
+ pendingChallenges = new Map();
28
+ usedNonces = new Set();
29
+ policy;
30
+ auditLog;
31
+ constructor(policy = {}, auditLog) {
32
+ this.policy = {
33
+ alwaysRequireActions: policy.alwaysRequireActions ?? [],
34
+ sensitivityLevels: policy.sensitivityLevels ?? ['high', 'critical'],
35
+ challengeTimeoutMs: policy.challengeTimeoutMs ?? 5 * 60_000,
36
+ maxPendingChallenges: policy.maxPendingChallenges ?? 10,
37
+ };
38
+ this.auditLog = auditLog;
39
+ }
40
+ /**
41
+ * Check if an action requires step-up authentication.
42
+ */
43
+ requiresStepUp(action, sensitivityLevel) {
44
+ // Check explicit action list
45
+ if (this.policy.alwaysRequireActions.includes(action)) {
46
+ return { required: true, trigger: 'policy_rule' };
47
+ }
48
+ // Check sensitivity level
49
+ if (sensitivityLevel &&
50
+ this.policy.sensitivityLevels.includes(sensitivityLevel)) {
51
+ const trigger = sensitivityLevel === 'critical' ? 'sensitivity_critical' : 'sensitivity_high';
52
+ return { required: true, trigger };
53
+ }
54
+ return { required: false };
55
+ }
56
+ /**
57
+ * Create a step-up challenge for the human principal to approve.
58
+ */
59
+ createChallenge(agentDid, principalDid, action, scope, trigger, actionDescription) {
60
+ // Enforce max pending limit
61
+ const agentPending = Array.from(this.pendingChallenges.values())
62
+ .filter(c => c.agentDid === agentDid).length;
63
+ if (agentPending >= this.policy.maxPendingChallenges) {
64
+ throw new Error(`Max pending challenges (${this.policy.maxPendingChallenges}) reached for agent`);
65
+ }
66
+ const nonce = toHex(secureRandom(16));
67
+ const challengeId = `stepup-${toHex(secureRandom(8))}`;
68
+ const now = new Date();
69
+ const challenge = {
70
+ challengeId,
71
+ agentDid,
72
+ principalDid,
73
+ actionDescription,
74
+ action,
75
+ scope,
76
+ triggerReason: trigger,
77
+ expiresAt: new Date(now.getTime() + this.policy.challengeTimeoutMs).toISOString(),
78
+ nonce,
79
+ createdAt: now.toISOString(),
80
+ };
81
+ this.pendingChallenges.set(challengeId, challenge);
82
+ return challenge;
83
+ }
84
+ /**
85
+ * Principal signs an approval for a challenge.
86
+ */
87
+ async signApproval(keyProvider, principalKeyId, challenge, decision) {
88
+ const approvalData = textToBytes(`stepup-approval:${challenge.challengeId}:${challenge.principalDid}:${decision}:${challenge.nonce}`);
89
+ const sig = await keyProvider.sign(principalKeyId, approvalData);
90
+ return {
91
+ challengeId: challenge.challengeId,
92
+ principalDid: challenge.principalDid,
93
+ decision,
94
+ decidedAt: new Date().toISOString(),
95
+ signature: toBase64Url(sig),
96
+ };
97
+ }
98
+ /**
99
+ * Verify a step-up approval and consume the challenge.
100
+ *
101
+ * This is the critical gate: if the approval is invalid, expired,
102
+ * or replayed, the action MUST NOT proceed.
103
+ */
104
+ async verifyApproval(approval) {
105
+ // Find the pending challenge
106
+ const challenge = this.pendingChallenges.get(approval.challengeId);
107
+ if (!challenge) {
108
+ return { approved: false, error: 'Challenge not found or already consumed' };
109
+ }
110
+ // Check nonce replay
111
+ if (this.usedNonces.has(challenge.nonce)) {
112
+ return { approved: false, error: 'Challenge nonce already used (replay)' };
113
+ }
114
+ // Check expiry
115
+ if (new Date(challenge.expiresAt) < new Date()) {
116
+ this.pendingChallenges.delete(approval.challengeId);
117
+ return { approved: false, error: 'Challenge expired' };
118
+ }
119
+ // Check principal matches
120
+ if (approval.principalDid !== challenge.principalDid) {
121
+ return { approved: false, error: 'Principal DID mismatch' };
122
+ }
123
+ // Verify signature
124
+ try {
125
+ const publicKey = didToPublicKey(approval.principalDid);
126
+ const approvalData = textToBytes(`stepup-approval:${challenge.challengeId}:${challenge.principalDid}:${approval.decision}:${challenge.nonce}`);
127
+ const sig = fromBase64Url(approval.signature);
128
+ const valid = await verify(sig, approvalData, publicKey);
129
+ if (!valid) {
130
+ return { approved: false, error: 'Invalid approval signature' };
131
+ }
132
+ }
133
+ catch (e) {
134
+ return { approved: false, error: `Signature verification failed: ${e.message}` };
135
+ }
136
+ // Consume the challenge (single-use)
137
+ this.pendingChallenges.delete(approval.challengeId);
138
+ this.usedNonces.add(challenge.nonce);
139
+ // Check the decision
140
+ if (approval.decision === 'denied') {
141
+ await this.auditLog?.log({
142
+ eventType: 'intent_rejected',
143
+ actorDid: approval.principalDid,
144
+ targetDid: challenge.agentDid,
145
+ result: 'failure',
146
+ reason: 'Step-up denied by principal',
147
+ metadata: {
148
+ challengeId: approval.challengeId,
149
+ action: challenge.action,
150
+ },
151
+ });
152
+ return { approved: false, error: 'Denied by principal', challengeId: approval.challengeId };
153
+ }
154
+ await this.auditLog?.log({
155
+ eventType: 'intent_validated',
156
+ actorDid: approval.principalDid,
157
+ targetDid: challenge.agentDid,
158
+ result: 'success',
159
+ metadata: {
160
+ type: 'step_up_approval',
161
+ challengeId: approval.challengeId,
162
+ action: challenge.action,
163
+ },
164
+ });
165
+ return { approved: true, challengeId: approval.challengeId };
166
+ }
167
+ /**
168
+ * Get a pending challenge by ID.
169
+ */
170
+ getChallenge(challengeId) {
171
+ return this.pendingChallenges.get(challengeId);
172
+ }
173
+ /**
174
+ * Get count of pending challenges.
175
+ */
176
+ getPendingCount() {
177
+ return this.pendingChallenges.size;
178
+ }
179
+ /**
180
+ * Cancel a pending challenge.
181
+ */
182
+ cancelChallenge(challengeId) {
183
+ return this.pendingChallenges.delete(challengeId);
184
+ }
185
+ }
186
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@sentinel-atl/stepup",
3
+ "version": "0.1.1",
4
+ "description": "Step-up authentication — re-prompt humans for sensitive agent actions",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "test": "vitest run",
17
+ "lint": "tsc --noEmit",
18
+ "clean": "rm -rf dist"
19
+ },
20
+ "dependencies": {
21
+ "@sentinel-atl/core": "*",
22
+ "@sentinel-atl/audit": "*"
23
+ },
24
+ "devDependencies": {
25
+ "vitest": "^3.2.4",
26
+ "typescript": "^5.7.0"
27
+ },
28
+ "license": "Apache-2.0",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/sentinel-atl/project-sentinel.git",
32
+ "directory": "packages/stepup"
33
+ },
34
+ "keywords": [
35
+ "ai-agent",
36
+ "trust",
37
+ "identity",
38
+ "did",
39
+ "verifiable-credentials",
40
+ "mcp",
41
+ "security"
42
+ ],
43
+ "homepage": "https://github.com/sentinel-atl/project-sentinel#readme",
44
+ "bugs": {
45
+ "url": "https://github.com/sentinel-atl/project-sentinel/issues"
46
+ },
47
+ "files": [
48
+ "dist",
49
+ "README.md"
50
+ ]
51
+ }