@id-wispera/mcp-server 0.1.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/README.md +161 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +196 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/auth.d.ts +24 -0
- package/dist/middleware/auth.d.ts.map +1 -0
- package/dist/middleware/auth.js +47 -0
- package/dist/middleware/auth.js.map +1 -0
- package/dist/middleware/policy-enforce.d.ts +26 -0
- package/dist/middleware/policy-enforce.d.ts.map +1 -0
- package/dist/middleware/policy-enforce.js +53 -0
- package/dist/middleware/policy-enforce.js.map +1 -0
- package/dist/resources/audit-resource.d.ts +35 -0
- package/dist/resources/audit-resource.d.ts.map +1 -0
- package/dist/resources/audit-resource.js +46 -0
- package/dist/resources/audit-resource.js.map +1 -0
- package/dist/resources/passport-resource.d.ts +42 -0
- package/dist/resources/passport-resource.d.ts.map +1 -0
- package/dist/resources/passport-resource.js +54 -0
- package/dist/resources/passport-resource.js.map +1 -0
- package/dist/tools/check-policy.d.ts +43 -0
- package/dist/tools/check-policy.d.ts.map +1 -0
- package/dist/tools/check-policy.js +47 -0
- package/dist/tools/check-policy.js.map +1 -0
- package/dist/tools/get-credential.d.ts +39 -0
- package/dist/tools/get-credential.d.ts.map +1 -0
- package/dist/tools/get-credential.js +53 -0
- package/dist/tools/get-credential.js.map +1 -0
- package/dist/tools/handler.d.ts +12 -0
- package/dist/tools/handler.d.ts.map +1 -0
- package/dist/tools/handler.js +20 -0
- package/dist/tools/handler.js.map +1 -0
- package/dist/tools/list-passports.d.ts +64 -0
- package/dist/tools/list-passports.d.ts.map +1 -0
- package/dist/tools/list-passports.js +68 -0
- package/dist/tools/list-passports.js.map +1 -0
- package/dist/tools/request-access.d.ts +44 -0
- package/dist/tools/request-access.d.ts.map +1 -0
- package/dist/tools/request-access.js +85 -0
- package/dist/tools/request-access.js.map +1 -0
- package/dist/tools/revoke.d.ts +35 -0
- package/dist/tools/revoke.d.ts.map +1 -0
- package/dist/tools/revoke.js +40 -0
- package/dist/tools/revoke.js.map +1 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @id-wispera/mcp-server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for ID Wispera credential governance.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides an MCP server that allows AI agents (like Claude) to securely access governed credentials through the Model Context Protocol.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @id-wispera/mcp-server
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
### Starting the Server
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Start the MCP server
|
|
21
|
+
npx @id-wispera/mcp-server
|
|
22
|
+
|
|
23
|
+
# With custom vault path
|
|
24
|
+
IDW_VAULT_PATH=~/.my-vault/vault.json npx @id-wispera/mcp-server
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Configuration with Claude Desktop
|
|
28
|
+
|
|
29
|
+
Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_desktop_config.json`):
|
|
30
|
+
|
|
31
|
+
```json
|
|
32
|
+
{
|
|
33
|
+
"mcpServers": {
|
|
34
|
+
"id-wispera": {
|
|
35
|
+
"command": "npx",
|
|
36
|
+
"args": ["@id-wispera/mcp-server"],
|
|
37
|
+
"env": {
|
|
38
|
+
"IDW_VAULT_PATH": "/path/to/vault.json",
|
|
39
|
+
"IDW_SESSION_TOKEN": "idw_st_..."
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Authentication**: Generate a scoped session token with `idw auth token create --name "claude-desktop" --scope read,list --ttl 7d` and set it as `IDW_SESSION_TOKEN`. This avoids storing a plaintext passphrase in your config file.
|
|
47
|
+
|
|
48
|
+
> **Deprecated**: `IDW_PASSPHRASE` is still accepted for backward compatibility but will be removed in a future release. Migrate to `IDW_SESSION_TOKEN`.
|
|
49
|
+
|
|
50
|
+
## Available Tools
|
|
51
|
+
|
|
52
|
+
### get_credential
|
|
53
|
+
|
|
54
|
+
Retrieve a credential by passport ID.
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"name": "get_credential",
|
|
59
|
+
"arguments": {
|
|
60
|
+
"passport_id": "uuid-of-passport",
|
|
61
|
+
"purpose": "Making API call to OpenAI"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### list_passports
|
|
67
|
+
|
|
68
|
+
List available passports with optional filters.
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"name": "list_passports",
|
|
73
|
+
"arguments": {
|
|
74
|
+
"status": "active",
|
|
75
|
+
"platform": "openai"
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### request_access
|
|
81
|
+
|
|
82
|
+
Request access to a credential (creates audit entry, may require approval).
|
|
83
|
+
|
|
84
|
+
```json
|
|
85
|
+
{
|
|
86
|
+
"name": "request_access",
|
|
87
|
+
"arguments": {
|
|
88
|
+
"passport_id": "uuid-of-passport",
|
|
89
|
+
"purpose": "Executing user-requested API call",
|
|
90
|
+
"scope": ["chat", "completions"]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### check_policy
|
|
96
|
+
|
|
97
|
+
Check if an action is permitted by policy.
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"name": "check_policy",
|
|
102
|
+
"arguments": {
|
|
103
|
+
"passport_id": "uuid-of-passport",
|
|
104
|
+
"action": "access"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### revoke_passport
|
|
110
|
+
|
|
111
|
+
Revoke a passport (requires confirmation).
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"name": "revoke_passport",
|
|
116
|
+
"arguments": {
|
|
117
|
+
"passport_id": "uuid-of-passport",
|
|
118
|
+
"reason": "Credential exposed in logs"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Available Resources
|
|
124
|
+
|
|
125
|
+
### passport://{id}
|
|
126
|
+
|
|
127
|
+
Access passport metadata as a resource.
|
|
128
|
+
|
|
129
|
+
```
|
|
130
|
+
passport://a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### audit://{passport_id}
|
|
134
|
+
|
|
135
|
+
Access audit trail for a passport.
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
audit://a1b2c3d4-e5f6-7890-abcd-ef1234567890
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Security
|
|
142
|
+
|
|
143
|
+
- All credential access is logged to the audit trail
|
|
144
|
+
- Policy rules are evaluated before credential retrieval
|
|
145
|
+
- The server runs locally and communicates via stdio
|
|
146
|
+
- Credentials are never sent to external services
|
|
147
|
+
|
|
148
|
+
## Environment Variables
|
|
149
|
+
|
|
150
|
+
| Variable | Description | Default |
|
|
151
|
+
|----------|-------------|---------|
|
|
152
|
+
| `IDW_SESSION_TOKEN` | Scoped session token (recommended) | |
|
|
153
|
+
| `IDW_VAULT_PATH` | Path to vault file | `~/.id-wispera/vault.json` |
|
|
154
|
+
| `IDW_LOG_LEVEL` | Logging level | `info` |
|
|
155
|
+
| `IDW_PASSPHRASE` | Vault passphrase | **Deprecated** -- use `IDW_SESSION_TOKEN` instead |
|
|
156
|
+
|
|
157
|
+
The server resolves authentication in order: `IDW_SESSION_TOKEN` > OS keychain > `IDW_PASSPHRASE`.
|
|
158
|
+
|
|
159
|
+
## License
|
|
160
|
+
|
|
161
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ID Wispera MCP Server
|
|
4
|
+
* Model Context Protocol server for credential governance
|
|
5
|
+
*/
|
|
6
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
8
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
9
|
+
import { getVault, getActor } from './middleware/auth.js';
|
|
10
|
+
import { getCredentialTool, handleGetCredential, } from './tools/get-credential.js';
|
|
11
|
+
import { listPassportsTool, handleListPassports, } from './tools/list-passports.js';
|
|
12
|
+
import { requestAccessTool, handleRequestAccess, } from './tools/request-access.js';
|
|
13
|
+
import { checkPolicyTool, handleCheckPolicy, } from './tools/check-policy.js';
|
|
14
|
+
import { revokePassportTool, handleRevokePassport, } from './tools/revoke.js';
|
|
15
|
+
import { getPassportResource, listPassportResources, } from './resources/passport-resource.js';
|
|
16
|
+
import { getAuditResource, listAuditResources, } from './resources/audit-resource.js';
|
|
17
|
+
const VERSION = '0.1.0';
|
|
18
|
+
/**
|
|
19
|
+
* Create and configure the MCP server
|
|
20
|
+
*/
|
|
21
|
+
async function createServer() {
|
|
22
|
+
const server = new Server({
|
|
23
|
+
name: 'id-wispera',
|
|
24
|
+
version: VERSION,
|
|
25
|
+
}, {
|
|
26
|
+
capabilities: {
|
|
27
|
+
tools: {},
|
|
28
|
+
resources: {},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
// List available tools
|
|
32
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
33
|
+
return {
|
|
34
|
+
tools: [
|
|
35
|
+
getCredentialTool,
|
|
36
|
+
listPassportsTool,
|
|
37
|
+
requestAccessTool,
|
|
38
|
+
checkPolicyTool,
|
|
39
|
+
revokePassportTool,
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
// Handle tool calls
|
|
44
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
45
|
+
const { name, arguments: args } = request.params;
|
|
46
|
+
try {
|
|
47
|
+
const vault = await getVault();
|
|
48
|
+
const actor = getActor();
|
|
49
|
+
let result;
|
|
50
|
+
switch (name) {
|
|
51
|
+
case 'get_credential':
|
|
52
|
+
result = await handleGetCredential(vault, args, actor);
|
|
53
|
+
break;
|
|
54
|
+
case 'list_passports':
|
|
55
|
+
result = await handleListPassports(vault, args);
|
|
56
|
+
break;
|
|
57
|
+
case 'request_access':
|
|
58
|
+
result = await handleRequestAccess(vault, args, actor);
|
|
59
|
+
break;
|
|
60
|
+
case 'check_policy':
|
|
61
|
+
result = await handleCheckPolicy(vault, args);
|
|
62
|
+
break;
|
|
63
|
+
case 'revoke_passport':
|
|
64
|
+
result = await handleRevokePassport(vault, args, actor);
|
|
65
|
+
break;
|
|
66
|
+
default:
|
|
67
|
+
return {
|
|
68
|
+
content: [
|
|
69
|
+
{
|
|
70
|
+
type: 'text',
|
|
71
|
+
text: JSON.stringify({ error: `Unknown tool: ${name}` }),
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
isError: true,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
content: [
|
|
79
|
+
{
|
|
80
|
+
type: 'text',
|
|
81
|
+
text: JSON.stringify(result, null, 2),
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return {
|
|
88
|
+
content: [
|
|
89
|
+
{
|
|
90
|
+
type: 'text',
|
|
91
|
+
text: JSON.stringify({
|
|
92
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
93
|
+
}),
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
isError: true,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
// List available resources
|
|
101
|
+
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
102
|
+
try {
|
|
103
|
+
const vault = await getVault();
|
|
104
|
+
const passportResources = await listPassportResources(vault);
|
|
105
|
+
const auditResources = await listAuditResources(vault);
|
|
106
|
+
return {
|
|
107
|
+
resources: [...passportResources, ...auditResources],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
return {
|
|
112
|
+
resources: [],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
// Read resource
|
|
117
|
+
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
118
|
+
const { uri } = request.params;
|
|
119
|
+
try {
|
|
120
|
+
const vault = await getVault();
|
|
121
|
+
// Parse URI
|
|
122
|
+
const url = new URL(uri);
|
|
123
|
+
const scheme = url.protocol.replace(':', '');
|
|
124
|
+
const id = url.hostname;
|
|
125
|
+
let content;
|
|
126
|
+
switch (scheme) {
|
|
127
|
+
case 'passport':
|
|
128
|
+
content = await getPassportResource(vault, id);
|
|
129
|
+
break;
|
|
130
|
+
case 'audit':
|
|
131
|
+
content = await getAuditResource(vault, id);
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
return {
|
|
135
|
+
contents: [
|
|
136
|
+
{
|
|
137
|
+
uri,
|
|
138
|
+
mimeType: 'application/json',
|
|
139
|
+
text: JSON.stringify({ error: `Unknown resource scheme: ${scheme}` }),
|
|
140
|
+
},
|
|
141
|
+
],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (!content) {
|
|
145
|
+
return {
|
|
146
|
+
contents: [
|
|
147
|
+
{
|
|
148
|
+
uri,
|
|
149
|
+
mimeType: 'application/json',
|
|
150
|
+
text: JSON.stringify({ error: 'Resource not found' }),
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
return {
|
|
156
|
+
contents: [
|
|
157
|
+
{
|
|
158
|
+
uri,
|
|
159
|
+
mimeType: 'application/json',
|
|
160
|
+
text: JSON.stringify(content, null, 2),
|
|
161
|
+
},
|
|
162
|
+
],
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
return {
|
|
167
|
+
contents: [
|
|
168
|
+
{
|
|
169
|
+
uri,
|
|
170
|
+
mimeType: 'application/json',
|
|
171
|
+
text: JSON.stringify({
|
|
172
|
+
error: err instanceof Error ? err.message : 'Unknown error',
|
|
173
|
+
}),
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
return server;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Main entry point
|
|
183
|
+
*/
|
|
184
|
+
async function main() {
|
|
185
|
+
const server = await createServer();
|
|
186
|
+
const transport = new StdioServerTransport();
|
|
187
|
+
await server.connect(transport);
|
|
188
|
+
// Log to stderr (stdout is for MCP communication)
|
|
189
|
+
console.error('ID Wispera MCP Server started');
|
|
190
|
+
console.error(`Version: ${VERSION}`);
|
|
191
|
+
}
|
|
192
|
+
main().catch((err) => {
|
|
193
|
+
console.error('Failed to start MCP server:', err);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
});
|
|
196
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication middleware for MCP requests
|
|
3
|
+
*
|
|
4
|
+
* Uses PassphraseProvider with allowInteractive: false so the MCP server
|
|
5
|
+
* resolves the passphrase via session token, OS keychain, or IDW_PASSPHRASE
|
|
6
|
+
* env var / .env file — it will never prompt.
|
|
7
|
+
*/
|
|
8
|
+
import type { Vault } from '@id-wispera/core';
|
|
9
|
+
/**
|
|
10
|
+
* Get or create an authenticated vault instance
|
|
11
|
+
*/
|
|
12
|
+
export declare function getVault(): Promise<Vault>;
|
|
13
|
+
/**
|
|
14
|
+
* Get the actor identifier for audit logging
|
|
15
|
+
*/
|
|
16
|
+
export declare function getActor(): string;
|
|
17
|
+
/**
|
|
18
|
+
* Clear cached vault (for testing).
|
|
19
|
+
*
|
|
20
|
+
* NOTE: Currently unused -- intended for test teardown. Wire up in test
|
|
21
|
+
* setup/teardown when vault integration tests are added.
|
|
22
|
+
*/
|
|
23
|
+
export declare function clearVaultCache(): void;
|
|
24
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAK9C;;GAEG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,CAmB/C;AAED;;GAEG;AACH,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication middleware for MCP requests
|
|
3
|
+
*
|
|
4
|
+
* Uses PassphraseProvider with allowInteractive: false so the MCP server
|
|
5
|
+
* resolves the passphrase via session token, OS keychain, or IDW_PASSPHRASE
|
|
6
|
+
* env var / .env file — it will never prompt.
|
|
7
|
+
*/
|
|
8
|
+
import { unlockVault, vaultExists, getDefaultVaultPath, PassphraseProvider } from '@id-wispera/core';
|
|
9
|
+
let cachedVault = null;
|
|
10
|
+
/**
|
|
11
|
+
* Get or create an authenticated vault instance
|
|
12
|
+
*/
|
|
13
|
+
export async function getVault() {
|
|
14
|
+
if (cachedVault && cachedVault.isUnlocked) {
|
|
15
|
+
return cachedVault;
|
|
16
|
+
}
|
|
17
|
+
const vaultPath = process.env.IDW_VAULT_PATH ?? getDefaultVaultPath();
|
|
18
|
+
if (!(await vaultExists(vaultPath))) {
|
|
19
|
+
throw new Error(`Vault not found at ${vaultPath}. Initialize with 'idw init' first.`);
|
|
20
|
+
}
|
|
21
|
+
const provider = new PassphraseProvider({
|
|
22
|
+
allowInteractive: false,
|
|
23
|
+
allowEnvVar: true,
|
|
24
|
+
});
|
|
25
|
+
const passphrase = await provider.getPassphrase();
|
|
26
|
+
cachedVault = await unlockVault(passphrase, vaultPath);
|
|
27
|
+
return cachedVault;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Get the actor identifier for audit logging
|
|
31
|
+
*/
|
|
32
|
+
export function getActor() {
|
|
33
|
+
return process.env.IDW_ACTOR ?? 'mcp-agent';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Clear cached vault (for testing).
|
|
37
|
+
*
|
|
38
|
+
* NOTE: Currently unused -- intended for test teardown. Wire up in test
|
|
39
|
+
* setup/teardown when vault integration tests are added.
|
|
40
|
+
*/
|
|
41
|
+
export function clearVaultCache() {
|
|
42
|
+
if (cachedVault) {
|
|
43
|
+
cachedVault.lock();
|
|
44
|
+
cachedVault = null;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAErG,IAAI,WAAW,GAAiB,IAAI,CAAC;AAErC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,IAAI,WAAW,IAAI,WAAW,CAAC,UAAU,EAAE,CAAC;QAC1C,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,mBAAmB,EAAE,CAAC;IAEtE,IAAI,CAAC,CAAC,MAAM,WAAW,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,qCAAqC,CAAC,CAAC;IACxF,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,kBAAkB,CAAC;QACtC,gBAAgB,EAAE,KAAK;QACvB,WAAW,EAAE,IAAI;KAClB,CAAC,CAAC;IAEH,MAAM,UAAU,GAAG,MAAM,QAAQ,CAAC,aAAa,EAAE,CAAC;IAClD,WAAW,GAAG,MAAM,WAAW,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;IACvD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,WAAW,CAAC;AAC9C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,WAAW,EAAE,CAAC;QAChB,WAAW,CAAC,IAAI,EAAE,CAAC;QACnB,WAAW,GAAG,IAAI,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy enforcement middleware
|
|
3
|
+
*/
|
|
4
|
+
import type { Vault, Passport, PolicyDecision } from '@id-wispera/core';
|
|
5
|
+
export interface EnforcementResult {
|
|
6
|
+
allowed: boolean;
|
|
7
|
+
decision: PolicyDecision;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Enforce policy before credential access.
|
|
11
|
+
*
|
|
12
|
+
* NOTE: Currently unused -- available for future use when tools delegate
|
|
13
|
+
* policy checks to shared middleware instead of calling evaluatePolicy directly.
|
|
14
|
+
*/
|
|
15
|
+
export declare function enforcePolicy(vault: Vault, passport: Passport, action: string, actor: string, context?: Record<string, unknown>): Promise<EnforcementResult>;
|
|
16
|
+
/**
|
|
17
|
+
* Check if passport status allows access.
|
|
18
|
+
*
|
|
19
|
+
* NOTE: Currently unused -- available for future use when tools delegate
|
|
20
|
+
* status checks to shared middleware instead of checking passport.status inline.
|
|
21
|
+
*/
|
|
22
|
+
export declare function isPassportUsable(passport: Passport): {
|
|
23
|
+
usable: boolean;
|
|
24
|
+
reason?: string;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=policy-enforce.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-enforce.d.ts","sourceRoot":"","sources":["../../src/middleware/policy-enforce.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGxE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,QAAQ,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,iBAAiB,CAAC,CAsB5B;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,GAAG;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAczF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy enforcement middleware
|
|
3
|
+
*/
|
|
4
|
+
import { evaluatePolicy, DEFAULT_POLICY_RULES, logAction } from '@id-wispera/core';
|
|
5
|
+
/**
|
|
6
|
+
* Enforce policy before credential access.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: Currently unused -- available for future use when tools delegate
|
|
9
|
+
* policy checks to shared middleware instead of calling evaluatePolicy directly.
|
|
10
|
+
*/
|
|
11
|
+
export async function enforcePolicy(vault, passport, action, actor, context) {
|
|
12
|
+
const decision = evaluatePolicy(passport, action, DEFAULT_POLICY_RULES);
|
|
13
|
+
// Log the policy check
|
|
14
|
+
await logAction(vault, {
|
|
15
|
+
passportId: passport.id,
|
|
16
|
+
action: 'policy-checked',
|
|
17
|
+
actor,
|
|
18
|
+
platform: 'mcp',
|
|
19
|
+
details: `Policy ${decision.effect} for action "${action}"`,
|
|
20
|
+
metadata: {
|
|
21
|
+
action,
|
|
22
|
+
effect: decision.effect,
|
|
23
|
+
matchedRules: decision.matchedRules.map(r => r.id),
|
|
24
|
+
context,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
return {
|
|
28
|
+
allowed: decision.allowed,
|
|
29
|
+
decision,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check if passport status allows access.
|
|
34
|
+
*
|
|
35
|
+
* NOTE: Currently unused -- available for future use when tools delegate
|
|
36
|
+
* status checks to shared middleware instead of checking passport.status inline.
|
|
37
|
+
*/
|
|
38
|
+
export function isPassportUsable(passport) {
|
|
39
|
+
switch (passport.status) {
|
|
40
|
+
case 'revoked':
|
|
41
|
+
return { usable: false, reason: 'Passport has been revoked' };
|
|
42
|
+
case 'expired':
|
|
43
|
+
return { usable: false, reason: 'Passport has expired' };
|
|
44
|
+
case 'suspended':
|
|
45
|
+
return { usable: false, reason: 'Passport is suspended' };
|
|
46
|
+
case 'expiring':
|
|
47
|
+
case 'active':
|
|
48
|
+
return { usable: true };
|
|
49
|
+
default:
|
|
50
|
+
return { usable: false, reason: 'Unknown passport status' };
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=policy-enforce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"policy-enforce.js","sourceRoot":"","sources":["../../src/middleware/policy-enforce.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAOnF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,KAAY,EACZ,QAAkB,EAClB,MAAc,EACd,KAAa,EACb,OAAiC;IAEjC,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,oBAAoB,CAAC,CAAC;IAExE,uBAAuB;IACvB,MAAM,SAAS,CAAC,KAAK,EAAE;QACrB,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,MAAM,EAAE,gBAAgB;QACxB,KAAK;QACL,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,UAAU,QAAQ,CAAC,MAAM,gBAAgB,MAAM,GAAG;QAC3D,QAAQ,EAAE;YACR,MAAM;YACN,MAAM,EAAE,QAAQ,CAAC,MAAM;YACvB,YAAY,EAAE,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAClD,OAAO;SACR;KACF,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,QAAQ;KACT,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAkB;IACjD,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,SAAS;YACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,EAAE,CAAC;QAChE,KAAK,SAAS;YACZ,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,sBAAsB,EAAE,CAAC;QAC3D,KAAK,WAAW;YACd,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QAC5D,KAAK,UAAU,CAAC;QAChB,KAAK,QAAQ;YACX,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC1B;YACE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAChE,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resource: audit://{passport_id}
|
|
3
|
+
* Access audit trail as a resource
|
|
4
|
+
*/
|
|
5
|
+
import type { Vault } from '@id-wispera/core';
|
|
6
|
+
export interface AuditResourceContent {
|
|
7
|
+
passport_id: string;
|
|
8
|
+
entries: Array<{
|
|
9
|
+
id: string;
|
|
10
|
+
action: string;
|
|
11
|
+
actor: string;
|
|
12
|
+
timestamp: string;
|
|
13
|
+
platform?: string;
|
|
14
|
+
details?: string;
|
|
15
|
+
}>;
|
|
16
|
+
stats: {
|
|
17
|
+
total_actions: number;
|
|
18
|
+
actions_last_24h: number;
|
|
19
|
+
actions_last_7d: number;
|
|
20
|
+
last_access?: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Get audit resource for a passport
|
|
25
|
+
*/
|
|
26
|
+
export declare function getAuditResource(vault: Vault, passportId: string): Promise<AuditResourceContent | null>;
|
|
27
|
+
/**
|
|
28
|
+
* List audit resources
|
|
29
|
+
*/
|
|
30
|
+
export declare function listAuditResources(vault: Vault): Promise<Array<{
|
|
31
|
+
uri: string;
|
|
32
|
+
name: string;
|
|
33
|
+
description: string;
|
|
34
|
+
}>>;
|
|
35
|
+
//# sourceMappingURL=audit-resource.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-resource.d.ts","sourceRoot":"","sources":["../../src/resources/audit-resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAG9C,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC,CAAC;IACH,KAAK,EAAE;QACL,aAAa,EAAE,MAAM,CAAC;QACtB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,KAAK,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAyBtC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAQpE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Resource: audit://{passport_id}
|
|
3
|
+
* Access audit trail as a resource
|
|
4
|
+
*/
|
|
5
|
+
import { getAuditLog, getAuditStats } from '@id-wispera/core';
|
|
6
|
+
/**
|
|
7
|
+
* Get audit resource for a passport
|
|
8
|
+
*/
|
|
9
|
+
export async function getAuditResource(vault, passportId) {
|
|
10
|
+
try {
|
|
11
|
+
const entries = await getAuditLog(vault, passportId);
|
|
12
|
+
const stats = await getAuditStats(vault, passportId);
|
|
13
|
+
return {
|
|
14
|
+
passport_id: passportId,
|
|
15
|
+
entries: entries.slice(0, 50).map(e => ({
|
|
16
|
+
id: e.id,
|
|
17
|
+
action: e.action,
|
|
18
|
+
actor: e.actor,
|
|
19
|
+
timestamp: e.timestamp,
|
|
20
|
+
platform: e.platform,
|
|
21
|
+
details: e.details,
|
|
22
|
+
})),
|
|
23
|
+
stats: {
|
|
24
|
+
total_actions: stats.totalActions,
|
|
25
|
+
actions_last_24h: stats.actionsLast24h,
|
|
26
|
+
actions_last_7d: stats.actionsLast7d,
|
|
27
|
+
last_access: stats.lastAction?.timestamp,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* List audit resources
|
|
37
|
+
*/
|
|
38
|
+
export async function listAuditResources(vault) {
|
|
39
|
+
const passports = await vault.getAllPassports();
|
|
40
|
+
return passports.map(p => ({
|
|
41
|
+
uri: `audit://${p.id}`,
|
|
42
|
+
name: `Audit: ${p.name}`,
|
|
43
|
+
description: `Audit trail for ${p.name}`,
|
|
44
|
+
}));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=audit-resource.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-resource.js","sourceRoot":"","sources":["../../src/resources/audit-resource.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAoB9D;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAY,EACZ,UAAkB;IAElB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAErD,OAAO;YACL,WAAW,EAAE,UAAU;YACvB,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtC,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,OAAO,EAAE,CAAC,CAAC,OAAO;aACnB,CAAC,CAAC;YACH,KAAK,EAAE;gBACL,aAAa,EAAE,KAAK,CAAC,YAAY;gBACjC,gBAAgB,EAAE,KAAK,CAAC,cAAc;gBACtC,eAAe,EAAE,KAAK,CAAC,aAAa;gBACpC,WAAW,EAAE,KAAK,CAAC,UAAU,EAAE,SAAS;aACzC;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAY;IAEZ,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,eAAe,EAAE,CAAC;IAEhD,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzB,GAAG,EAAE,WAAW,CAAC,CAAC,EAAE,EAAE;QACtB,IAAI,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE;QACxB,WAAW,EAAE,mBAAmB,CAAC,CAAC,IAAI,EAAE;KACzC,CAAC,CAAC,CAAC;AACN,CAAC"}
|