@sanctuary-framework/mcp-server 0.5.12 → 0.5.14
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/cli.cjs +722 -22
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +722 -22
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +937 -212
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +117 -1
- package/dist/index.d.ts +117 -1
- package/dist/index.js +935 -213
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -557,6 +557,18 @@ var init_hashing = __esm({
|
|
|
557
557
|
init_encoding();
|
|
558
558
|
}
|
|
559
559
|
});
|
|
560
|
+
|
|
561
|
+
// src/core/identity.ts
|
|
562
|
+
var identity_exports = {};
|
|
563
|
+
__export(identity_exports, {
|
|
564
|
+
createIdentity: () => createIdentity,
|
|
565
|
+
generateIdentityId: () => generateIdentityId,
|
|
566
|
+
generateKeypair: () => generateKeypair,
|
|
567
|
+
publicKeyToDid: () => publicKeyToDid,
|
|
568
|
+
rotateKeys: () => rotateKeys,
|
|
569
|
+
sign: () => sign,
|
|
570
|
+
verify: () => verify
|
|
571
|
+
});
|
|
560
572
|
function generateKeypair() {
|
|
561
573
|
const privateKey = randomBytes(32);
|
|
562
574
|
const publicKey = ed25519.getPublicKey(privateKey);
|
|
@@ -1344,7 +1356,9 @@ var init_tools = __esm({
|
|
|
1344
1356
|
"_bridge",
|
|
1345
1357
|
"_federation",
|
|
1346
1358
|
"_handshake",
|
|
1347
|
-
"_shr"
|
|
1359
|
+
"_shr",
|
|
1360
|
+
"_sovereignty_profile",
|
|
1361
|
+
"_context_gate_policies"
|
|
1348
1362
|
];
|
|
1349
1363
|
IdentityManager = class {
|
|
1350
1364
|
storage;
|
|
@@ -1623,6 +1637,8 @@ tier1_always_approve:
|
|
|
1623
1637
|
- reputation_import
|
|
1624
1638
|
- reputation_export
|
|
1625
1639
|
- bootstrap_provide_guarantee
|
|
1640
|
+
- reputation_publish
|
|
1641
|
+
- sovereignty_profile_update
|
|
1626
1642
|
|
|
1627
1643
|
# \u2500\u2500\u2500 Tier 2: Behavioral Anomaly Detection \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1628
1644
|
# Triggers approval when agent behavior deviates from its baseline.
|
|
@@ -1685,6 +1701,9 @@ tier3_always_allow:
|
|
|
1685
1701
|
- bridge_commit
|
|
1686
1702
|
- bridge_verify
|
|
1687
1703
|
- bridge_attest
|
|
1704
|
+
- dashboard_open
|
|
1705
|
+
- sovereignty_profile_get
|
|
1706
|
+
- sovereignty_profile_generate_prompt
|
|
1688
1707
|
|
|
1689
1708
|
# \u2500\u2500\u2500 Approval Channel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
|
|
1690
1709
|
# How Sanctuary reaches you when approval is needed.
|
|
@@ -1737,7 +1756,11 @@ var init_loader = __esm({
|
|
|
1737
1756
|
"reputation_import",
|
|
1738
1757
|
"reputation_export",
|
|
1739
1758
|
"bootstrap_provide_guarantee",
|
|
1740
|
-
"decommission_certificate"
|
|
1759
|
+
"decommission_certificate",
|
|
1760
|
+
"reputation_publish",
|
|
1761
|
+
// SEC-039: Explicit Tier 1 — sends data to external API
|
|
1762
|
+
"sovereignty_profile_update"
|
|
1763
|
+
// Changes enforcement behavior — always requires approval
|
|
1741
1764
|
],
|
|
1742
1765
|
tier2_anomaly: DEFAULT_TIER2,
|
|
1743
1766
|
tier3_always_allow: [
|
|
@@ -1789,7 +1812,11 @@ var init_loader = __esm({
|
|
|
1789
1812
|
"shr_gateway_export",
|
|
1790
1813
|
"bridge_commit",
|
|
1791
1814
|
"bridge_verify",
|
|
1792
|
-
"bridge_attest"
|
|
1815
|
+
"bridge_attest",
|
|
1816
|
+
"dashboard_open",
|
|
1817
|
+
// SEC-039: Explicit Tier 3 — only generates a URL
|
|
1818
|
+
"sovereignty_profile_get",
|
|
1819
|
+
"sovereignty_profile_generate_prompt"
|
|
1793
1820
|
],
|
|
1794
1821
|
approval_channel: DEFAULT_CHANNEL
|
|
1795
1822
|
};
|
|
@@ -3006,6 +3033,133 @@ function generateDashboardHTML(options) {
|
|
|
3006
3033
|
background-color: #e03c3c;
|
|
3007
3034
|
}
|
|
3008
3035
|
|
|
3036
|
+
/* Sovereignty Profile Panel */
|
|
3037
|
+
.profile-panel {
|
|
3038
|
+
background-color: var(--surface);
|
|
3039
|
+
border: 1px solid var(--border);
|
|
3040
|
+
border-radius: 8px;
|
|
3041
|
+
padding: 20px;
|
|
3042
|
+
}
|
|
3043
|
+
|
|
3044
|
+
.profile-panel .panel-header {
|
|
3045
|
+
display: flex;
|
|
3046
|
+
justify-content: space-between;
|
|
3047
|
+
align-items: center;
|
|
3048
|
+
margin-bottom: 16px;
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3051
|
+
.profile-panel .panel-title {
|
|
3052
|
+
font-size: 14px;
|
|
3053
|
+
font-weight: 600;
|
|
3054
|
+
color: var(--text-primary);
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
.profile-cards {
|
|
3058
|
+
display: grid;
|
|
3059
|
+
grid-template-columns: repeat(5, 1fr);
|
|
3060
|
+
gap: 12px;
|
|
3061
|
+
margin-bottom: 16px;
|
|
3062
|
+
}
|
|
3063
|
+
|
|
3064
|
+
.profile-card {
|
|
3065
|
+
background-color: var(--bg);
|
|
3066
|
+
border: 1px solid var(--border);
|
|
3067
|
+
border-radius: 6px;
|
|
3068
|
+
padding: 14px;
|
|
3069
|
+
display: flex;
|
|
3070
|
+
flex-direction: column;
|
|
3071
|
+
gap: 8px;
|
|
3072
|
+
}
|
|
3073
|
+
|
|
3074
|
+
.profile-card-name {
|
|
3075
|
+
font-size: 12px;
|
|
3076
|
+
font-weight: 600;
|
|
3077
|
+
color: var(--text-primary);
|
|
3078
|
+
}
|
|
3079
|
+
|
|
3080
|
+
.profile-card-desc {
|
|
3081
|
+
font-size: 11px;
|
|
3082
|
+
color: var(--text-secondary);
|
|
3083
|
+
line-height: 1.4;
|
|
3084
|
+
}
|
|
3085
|
+
|
|
3086
|
+
.profile-badge {
|
|
3087
|
+
display: inline-flex;
|
|
3088
|
+
align-items: center;
|
|
3089
|
+
gap: 4px;
|
|
3090
|
+
padding: 2px 8px;
|
|
3091
|
+
border-radius: 4px;
|
|
3092
|
+
font-size: 10px;
|
|
3093
|
+
font-weight: 600;
|
|
3094
|
+
width: fit-content;
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
.profile-badge.enabled {
|
|
3098
|
+
background-color: rgba(63, 185, 80, 0.15);
|
|
3099
|
+
color: var(--green);
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
.profile-badge.disabled {
|
|
3103
|
+
background-color: rgba(139, 148, 158, 0.15);
|
|
3104
|
+
color: var(--text-secondary);
|
|
3105
|
+
}
|
|
3106
|
+
|
|
3107
|
+
.prompt-section {
|
|
3108
|
+
margin-top: 12px;
|
|
3109
|
+
}
|
|
3110
|
+
|
|
3111
|
+
.prompt-textarea {
|
|
3112
|
+
width: 100%;
|
|
3113
|
+
min-height: 120px;
|
|
3114
|
+
background-color: var(--bg);
|
|
3115
|
+
border: 1px solid var(--border);
|
|
3116
|
+
border-radius: 6px;
|
|
3117
|
+
color: var(--text-primary);
|
|
3118
|
+
font-family: 'JetBrains Mono', monospace;
|
|
3119
|
+
font-size: 12px;
|
|
3120
|
+
padding: 12px;
|
|
3121
|
+
resize: vertical;
|
|
3122
|
+
margin-top: 8px;
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
.prompt-actions {
|
|
3126
|
+
display: flex;
|
|
3127
|
+
gap: 8px;
|
|
3128
|
+
margin-top: 8px;
|
|
3129
|
+
}
|
|
3130
|
+
|
|
3131
|
+
.prompt-btn {
|
|
3132
|
+
padding: 6px 12px;
|
|
3133
|
+
border: 1px solid var(--border);
|
|
3134
|
+
border-radius: 4px;
|
|
3135
|
+
background-color: var(--surface);
|
|
3136
|
+
color: var(--text-primary);
|
|
3137
|
+
font-size: 12px;
|
|
3138
|
+
cursor: pointer;
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
.prompt-btn:hover {
|
|
3142
|
+
background-color: var(--muted);
|
|
3143
|
+
}
|
|
3144
|
+
|
|
3145
|
+
.prompt-btn.primary {
|
|
3146
|
+
background-color: var(--blue);
|
|
3147
|
+
color: var(--bg);
|
|
3148
|
+
border-color: var(--blue);
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3151
|
+
@media (max-width: 900px) {
|
|
3152
|
+
.profile-cards {
|
|
3153
|
+
grid-template-columns: repeat(2, 1fr);
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
|
|
3157
|
+
@media (max-width: 500px) {
|
|
3158
|
+
.profile-cards {
|
|
3159
|
+
grid-template-columns: 1fr;
|
|
3160
|
+
}
|
|
3161
|
+
}
|
|
3162
|
+
|
|
3009
3163
|
/* Threat Panel */
|
|
3010
3164
|
.threat-panel {
|
|
3011
3165
|
background-color: var(--surface);
|
|
@@ -3344,6 +3498,48 @@ function generateDashboardHTML(options) {
|
|
|
3344
3498
|
</div>
|
|
3345
3499
|
</div>
|
|
3346
3500
|
|
|
3501
|
+
<!-- Sovereignty Profile Panel -->
|
|
3502
|
+
<div class="profile-panel" id="sovereignty-profile-panel">
|
|
3503
|
+
<div class="panel-header">
|
|
3504
|
+
<div class="panel-title">Sovereignty Profile</div>
|
|
3505
|
+
<span class="card-value" id="profile-updated-at" style="font-size: 11px; color: var(--text-secondary);">\u2014</span>
|
|
3506
|
+
</div>
|
|
3507
|
+
<div class="profile-cards" id="profile-cards">
|
|
3508
|
+
<div class="profile-card" data-feature="audit_logging">
|
|
3509
|
+
<div class="profile-card-name">Audit Logging</div>
|
|
3510
|
+
<div class="profile-badge disabled" id="badge-audit_logging">OFF</div>
|
|
3511
|
+
<div class="profile-card-desc">Encrypted audit trail of all tool calls</div>
|
|
3512
|
+
</div>
|
|
3513
|
+
<div class="profile-card" data-feature="injection_detection">
|
|
3514
|
+
<div class="profile-card-name">Injection Detection</div>
|
|
3515
|
+
<div class="profile-badge disabled" id="badge-injection_detection">OFF</div>
|
|
3516
|
+
<div class="profile-card-desc">Scans tool arguments for prompt injection</div>
|
|
3517
|
+
</div>
|
|
3518
|
+
<div class="profile-card" data-feature="context_gating">
|
|
3519
|
+
<div class="profile-card-name">Context Gating</div>
|
|
3520
|
+
<div class="profile-badge disabled" id="badge-context_gating">OFF</div>
|
|
3521
|
+
<div class="profile-card-desc">Controls context flow to remote providers</div>
|
|
3522
|
+
</div>
|
|
3523
|
+
<div class="profile-card" data-feature="approval_gate">
|
|
3524
|
+
<div class="profile-card-name">Approval Gates</div>
|
|
3525
|
+
<div class="profile-badge disabled" id="badge-approval_gate">OFF</div>
|
|
3526
|
+
<div class="profile-card-desc">Human approval for high-risk operations</div>
|
|
3527
|
+
</div>
|
|
3528
|
+
<div class="profile-card" data-feature="zk_proofs">
|
|
3529
|
+
<div class="profile-card-name">ZK Proofs</div>
|
|
3530
|
+
<div class="profile-badge disabled" id="badge-zk_proofs">OFF</div>
|
|
3531
|
+
<div class="profile-card-desc">Prove claims without revealing data</div>
|
|
3532
|
+
</div>
|
|
3533
|
+
</div>
|
|
3534
|
+
<div class="prompt-section">
|
|
3535
|
+
<div class="prompt-actions">
|
|
3536
|
+
<button class="prompt-btn primary" id="generate-prompt-btn">Generate System Prompt</button>
|
|
3537
|
+
<button class="prompt-btn" id="copy-prompt-btn" style="display:none;">Copy</button>
|
|
3538
|
+
</div>
|
|
3539
|
+
<textarea class="prompt-textarea" id="system-prompt-output" readonly style="display:none;" placeholder="Click 'Generate System Prompt' to create an agent instruction snippet..."></textarea>
|
|
3540
|
+
</div>
|
|
3541
|
+
</div>
|
|
3542
|
+
|
|
3347
3543
|
<!-- Threat Panel -->
|
|
3348
3544
|
<div class="threat-panel collapsed">
|
|
3349
3545
|
<div class="threat-header">
|
|
@@ -3365,7 +3561,9 @@ function generateDashboardHTML(options) {
|
|
|
3365
3561
|
|
|
3366
3562
|
<script>
|
|
3367
3563
|
// Constants
|
|
3368
|
-
|
|
3564
|
+
// SEC-038: Do NOT embed the long-lived auth token in page source.
|
|
3565
|
+
// Use only the session token stored in sessionStorage by the login flow.
|
|
3566
|
+
const AUTH_TOKEN = sessionStorage.getItem('authToken') || '';
|
|
3369
3567
|
const TIMEOUT_SECONDS = ${options.timeoutSeconds};
|
|
3370
3568
|
const API_BASE = '';
|
|
3371
3569
|
|
|
@@ -3376,6 +3574,7 @@ function generateDashboardHTML(options) {
|
|
|
3376
3574
|
handshakes: [],
|
|
3377
3575
|
shr: null,
|
|
3378
3576
|
status: null,
|
|
3577
|
+
systemPrompt: null,
|
|
3379
3578
|
};
|
|
3380
3579
|
|
|
3381
3580
|
let pendingRequests = new Map();
|
|
@@ -3828,6 +4027,10 @@ function generateDashboardHTML(options) {
|
|
|
3828
4027
|
removePendingRequest(data.requestId);
|
|
3829
4028
|
});
|
|
3830
4029
|
|
|
4030
|
+
eventSource.addEventListener('sovereignty-profile-update', () => {
|
|
4031
|
+
updateSovereigntyProfile();
|
|
4032
|
+
});
|
|
4033
|
+
|
|
3831
4034
|
eventSource.onerror = () => {
|
|
3832
4035
|
console.error('SSE error');
|
|
3833
4036
|
setTimeout(setupSSE, 5000);
|
|
@@ -3984,6 +4187,58 @@ function generateDashboardHTML(options) {
|
|
|
3984
4187
|
document.getElementById('pending-overlay').classList.toggle('show');
|
|
3985
4188
|
});
|
|
3986
4189
|
|
|
4190
|
+
// Sovereignty Profile
|
|
4191
|
+
async function updateSovereigntyProfile() {
|
|
4192
|
+
try {
|
|
4193
|
+
const data = await fetchAPI('/api/sovereignty-profile');
|
|
4194
|
+
if (data && data.profile) {
|
|
4195
|
+
const features = data.profile.features;
|
|
4196
|
+
for (const [key, value] of Object.entries(features)) {
|
|
4197
|
+
const badge = document.getElementById('badge-' + key);
|
|
4198
|
+
if (badge) {
|
|
4199
|
+
const enabled = value && value.enabled;
|
|
4200
|
+
badge.textContent = enabled ? 'ON' : 'OFF';
|
|
4201
|
+
badge.className = 'profile-badge ' + (enabled ? 'enabled' : 'disabled');
|
|
4202
|
+
}
|
|
4203
|
+
}
|
|
4204
|
+
const updatedEl = document.getElementById('profile-updated-at');
|
|
4205
|
+
if (updatedEl && data.profile.updated_at) {
|
|
4206
|
+
updatedEl.textContent = 'Updated: ' + new Date(data.profile.updated_at).toLocaleString();
|
|
4207
|
+
}
|
|
4208
|
+
// Cache the prompt
|
|
4209
|
+
if (data.system_prompt) {
|
|
4210
|
+
apiState.systemPrompt = data.system_prompt;
|
|
4211
|
+
}
|
|
4212
|
+
}
|
|
4213
|
+
} catch (e) {
|
|
4214
|
+
// Profile not available
|
|
4215
|
+
}
|
|
4216
|
+
}
|
|
4217
|
+
|
|
4218
|
+
document.getElementById('generate-prompt-btn').addEventListener('click', async () => {
|
|
4219
|
+
const data = await fetchAPI('/api/sovereignty-profile');
|
|
4220
|
+
if (data && data.system_prompt) {
|
|
4221
|
+
const textarea = document.getElementById('system-prompt-output');
|
|
4222
|
+
const copyBtn = document.getElementById('copy-prompt-btn');
|
|
4223
|
+
textarea.value = data.system_prompt;
|
|
4224
|
+
textarea.style.display = 'block';
|
|
4225
|
+
copyBtn.style.display = 'inline-flex';
|
|
4226
|
+
}
|
|
4227
|
+
});
|
|
4228
|
+
|
|
4229
|
+
document.getElementById('copy-prompt-btn').addEventListener('click', async () => {
|
|
4230
|
+
const textarea = document.getElementById('system-prompt-output');
|
|
4231
|
+
try {
|
|
4232
|
+
await navigator.clipboard.writeText(textarea.value);
|
|
4233
|
+
const btn = document.getElementById('copy-prompt-btn');
|
|
4234
|
+
const original = btn.textContent;
|
|
4235
|
+
btn.textContent = 'Copied!';
|
|
4236
|
+
setTimeout(() => { btn.textContent = original; }, 2000);
|
|
4237
|
+
} catch (err) {
|
|
4238
|
+
console.error('Copy failed:', err);
|
|
4239
|
+
}
|
|
4240
|
+
});
|
|
4241
|
+
|
|
3987
4242
|
// Initialize
|
|
3988
4243
|
async function initialize() {
|
|
3989
4244
|
if (!AUTH_TOKEN) {
|
|
@@ -3998,6 +4253,7 @@ function generateDashboardHTML(options) {
|
|
|
3998
4253
|
updateHandshakes(),
|
|
3999
4254
|
updateSHR(),
|
|
4000
4255
|
updateStatus(),
|
|
4256
|
+
updateSovereigntyProfile(),
|
|
4001
4257
|
]);
|
|
4002
4258
|
|
|
4003
4259
|
// Setup SSE for real-time updates
|
|
@@ -4017,12 +4273,92 @@ var init_dashboard_html = __esm({
|
|
|
4017
4273
|
"src/principal-policy/dashboard-html.ts"() {
|
|
4018
4274
|
}
|
|
4019
4275
|
});
|
|
4276
|
+
|
|
4277
|
+
// src/system-prompt-generator.ts
|
|
4278
|
+
function generateSystemPrompt(profile) {
|
|
4279
|
+
const activeFeatures = [];
|
|
4280
|
+
const inactiveFeatures = [];
|
|
4281
|
+
const featureKeys = [
|
|
4282
|
+
"audit_logging",
|
|
4283
|
+
"injection_detection",
|
|
4284
|
+
"context_gating",
|
|
4285
|
+
"approval_gate",
|
|
4286
|
+
"zk_proofs"
|
|
4287
|
+
];
|
|
4288
|
+
for (const key of featureKeys) {
|
|
4289
|
+
const featureConfig = profile.features[key];
|
|
4290
|
+
const info = FEATURE_INFO[key];
|
|
4291
|
+
if (featureConfig.enabled) {
|
|
4292
|
+
let desc = `- ${info.name}: ${info.activeDescription}`;
|
|
4293
|
+
if (key === "injection_detection" && "sensitivity" in featureConfig && featureConfig.sensitivity) {
|
|
4294
|
+
desc += ` Sensitivity: ${featureConfig.sensitivity}.`;
|
|
4295
|
+
}
|
|
4296
|
+
if (key === "context_gating" && "policy_id" in featureConfig && featureConfig.policy_id) {
|
|
4297
|
+
desc += ` Active policy: ${featureConfig.policy_id}.`;
|
|
4298
|
+
}
|
|
4299
|
+
activeFeatures.push(desc);
|
|
4300
|
+
} else {
|
|
4301
|
+
inactiveFeatures.push(info.disabledDescription);
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
const lines = [
|
|
4305
|
+
"You are protected by Sanctuary sovereignty infrastructure. The following protections are active:",
|
|
4306
|
+
""
|
|
4307
|
+
];
|
|
4308
|
+
if (activeFeatures.length > 0) {
|
|
4309
|
+
lines.push(...activeFeatures);
|
|
4310
|
+
} else {
|
|
4311
|
+
lines.push("- No features are currently enabled. Contact your operator to configure protections.");
|
|
4312
|
+
}
|
|
4313
|
+
if (inactiveFeatures.length > 0) {
|
|
4314
|
+
lines.push("");
|
|
4315
|
+
lines.push(
|
|
4316
|
+
`Optional tools available but not currently enabled: ${inactiveFeatures.join(", ")}.`
|
|
4317
|
+
);
|
|
4318
|
+
}
|
|
4319
|
+
return lines.join("\n");
|
|
4320
|
+
}
|
|
4321
|
+
var FEATURE_INFO;
|
|
4322
|
+
var init_system_prompt_generator = __esm({
|
|
4323
|
+
"src/system-prompt-generator.ts"() {
|
|
4324
|
+
FEATURE_INFO = {
|
|
4325
|
+
audit_logging: {
|
|
4326
|
+
name: "Audit Logging",
|
|
4327
|
+
activeDescription: "All your tool calls are logged to an encrypted audit trail. No action needed \u2014 this is automatic.",
|
|
4328
|
+
disabledDescription: "audit logging (sanctuary/monitor_audit_log)"
|
|
4329
|
+
},
|
|
4330
|
+
injection_detection: {
|
|
4331
|
+
name: "Injection Detection",
|
|
4332
|
+
activeDescription: "Your tool call arguments are scanned for prompt injection attempts. No action needed \u2014 this is automatic.",
|
|
4333
|
+
disabledDescription: "injection detection"
|
|
4334
|
+
},
|
|
4335
|
+
context_gating: {
|
|
4336
|
+
name: "Context Gating",
|
|
4337
|
+
activeDescription: "Before making outbound calls to remote providers, filter your context through sanctuary/context_gate_filter to ensure minimum-necessary disclosure.",
|
|
4338
|
+
toolNames: ["sanctuary/context_gate_filter", "sanctuary/context_gate_set_policy"],
|
|
4339
|
+
disabledDescription: "context gating (sanctuary/context_gate_filter)"
|
|
4340
|
+
},
|
|
4341
|
+
approval_gate: {
|
|
4342
|
+
name: "Approval Gates",
|
|
4343
|
+
activeDescription: "High-risk operations require human approval before execution. Tier 1 operations always require approval; Tier 2 operations trigger approval on anomaly detection.",
|
|
4344
|
+
disabledDescription: "approval gates"
|
|
4345
|
+
},
|
|
4346
|
+
zk_proofs: {
|
|
4347
|
+
name: "Zero-Knowledge Proofs",
|
|
4348
|
+
activeDescription: "You can prove claims about your data without revealing the underlying values. Use sanctuary/zk_commit to create commitments, sanctuary/zk_prove for proofs of knowledge, and sanctuary/zk_range_prove for range proofs.",
|
|
4349
|
+
toolNames: ["sanctuary/zk_commit", "sanctuary/zk_prove", "sanctuary/zk_range_prove"],
|
|
4350
|
+
disabledDescription: "zero-knowledge proofs (sanctuary/zk_commit, sanctuary/zk_prove)"
|
|
4351
|
+
}
|
|
4352
|
+
};
|
|
4353
|
+
}
|
|
4354
|
+
});
|
|
4020
4355
|
var SESSION_TTL_REMOTE_MS, SESSION_TTL_LOCAL_MS, MAX_SESSIONS, RATE_LIMIT_WINDOW_MS, RATE_LIMIT_GENERAL, RATE_LIMIT_DECISIONS, MAX_RATE_LIMIT_ENTRIES, DashboardApprovalChannel;
|
|
4021
4356
|
var init_dashboard = __esm({
|
|
4022
4357
|
"src/principal-policy/dashboard.ts"() {
|
|
4023
4358
|
init_config();
|
|
4024
4359
|
init_generator();
|
|
4025
4360
|
init_dashboard_html();
|
|
4361
|
+
init_system_prompt_generator();
|
|
4026
4362
|
SESSION_TTL_REMOTE_MS = 5 * 60 * 1e3;
|
|
4027
4363
|
SESSION_TTL_LOCAL_MS = 24 * 60 * 60 * 1e3;
|
|
4028
4364
|
MAX_SESSIONS = 1e3;
|
|
@@ -4042,6 +4378,7 @@ var init_dashboard = __esm({
|
|
|
4042
4378
|
handshakeResults = null;
|
|
4043
4379
|
shrOpts = null;
|
|
4044
4380
|
_sanctuaryConfig = null;
|
|
4381
|
+
profileStore = null;
|
|
4045
4382
|
dashboardHTML;
|
|
4046
4383
|
loginHTML;
|
|
4047
4384
|
authToken;
|
|
@@ -4081,6 +4418,7 @@ var init_dashboard = __esm({
|
|
|
4081
4418
|
if (deps.handshakeResults) this.handshakeResults = deps.handshakeResults;
|
|
4082
4419
|
if (deps.shrOpts) this.shrOpts = deps.shrOpts;
|
|
4083
4420
|
if (deps.sanctuaryConfig) this._sanctuaryConfig = deps.sanctuaryConfig;
|
|
4421
|
+
if (deps.profileStore) this.profileStore = deps.profileStore;
|
|
4084
4422
|
}
|
|
4085
4423
|
/**
|
|
4086
4424
|
* Mark this dashboard as running in standalone mode.
|
|
@@ -4428,6 +4766,10 @@ var init_dashboard = __esm({
|
|
|
4428
4766
|
this.handleHandshakes(res);
|
|
4429
4767
|
} else if (method === "GET" && url.pathname === "/api/shr") {
|
|
4430
4768
|
this.handleSHR(res);
|
|
4769
|
+
} else if (method === "GET" && url.pathname === "/api/sovereignty-profile") {
|
|
4770
|
+
this.handleSovereigntyProfileGet(res);
|
|
4771
|
+
} else if (method === "POST" && url.pathname === "/api/sovereignty-profile") {
|
|
4772
|
+
this.handleSovereigntyProfileUpdate(req, res);
|
|
4431
4773
|
} else if (method === "POST" && url.pathname.startsWith("/api/approve/")) {
|
|
4432
4774
|
if (!this.checkRateLimit(req, res, "decisions")) return;
|
|
4433
4775
|
const id = url.pathname.slice("/api/approve/".length);
|
|
@@ -4719,6 +5061,61 @@ data: ${JSON.stringify(initData)}
|
|
|
4719
5061
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
4720
5062
|
res.end(JSON.stringify(shr));
|
|
4721
5063
|
}
|
|
5064
|
+
// ── Sovereignty Profile API ─────────────────────────────────────────
|
|
5065
|
+
handleSovereigntyProfileGet(res) {
|
|
5066
|
+
if (!this.profileStore) {
|
|
5067
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5068
|
+
res.end(JSON.stringify({ error: "Sovereignty Profile not available" }));
|
|
5069
|
+
return;
|
|
5070
|
+
}
|
|
5071
|
+
try {
|
|
5072
|
+
const profile = this.profileStore.get();
|
|
5073
|
+
const prompt = generateSystemPrompt(profile);
|
|
5074
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5075
|
+
res.end(JSON.stringify({ profile, system_prompt: prompt }));
|
|
5076
|
+
} catch {
|
|
5077
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
5078
|
+
res.end(JSON.stringify({ error: "Failed to read sovereignty profile" }));
|
|
5079
|
+
}
|
|
5080
|
+
}
|
|
5081
|
+
handleSovereigntyProfileUpdate(req, res) {
|
|
5082
|
+
if (!this.profileStore) {
|
|
5083
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
5084
|
+
res.end(JSON.stringify({ error: "Sovereignty Profile not available" }));
|
|
5085
|
+
return;
|
|
5086
|
+
}
|
|
5087
|
+
let body = "";
|
|
5088
|
+
let destroyed = false;
|
|
5089
|
+
req.on("data", (chunk) => {
|
|
5090
|
+
body += chunk.toString();
|
|
5091
|
+
if (body.length > 16384) {
|
|
5092
|
+
destroyed = true;
|
|
5093
|
+
res.writeHead(413, { "Content-Type": "application/json" });
|
|
5094
|
+
res.end(JSON.stringify({ error: "Request body too large" }));
|
|
5095
|
+
req.destroy();
|
|
5096
|
+
}
|
|
5097
|
+
});
|
|
5098
|
+
req.on("end", async () => {
|
|
5099
|
+
if (destroyed) return;
|
|
5100
|
+
try {
|
|
5101
|
+
const updates = JSON.parse(body);
|
|
5102
|
+
const updated = await this.profileStore.update(updates);
|
|
5103
|
+
const prompt = generateSystemPrompt(updated);
|
|
5104
|
+
if (this.auditLog) {
|
|
5105
|
+
this.auditLog.append("l2", "sovereignty_profile_update_dashboard", "dashboard", {
|
|
5106
|
+
changes: updates,
|
|
5107
|
+
features_enabled: Object.entries(updated.features).filter(([, v]) => v.enabled).map(([k]) => k)
|
|
5108
|
+
});
|
|
5109
|
+
}
|
|
5110
|
+
this.broadcastSSE("sovereignty-profile-update", { profile: updated, system_prompt: prompt });
|
|
5111
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
5112
|
+
res.end(JSON.stringify({ profile: updated, system_prompt: prompt }));
|
|
5113
|
+
} catch {
|
|
5114
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
5115
|
+
res.end(JSON.stringify({ error: "Invalid JSON body" }));
|
|
5116
|
+
}
|
|
5117
|
+
});
|
|
5118
|
+
}
|
|
4722
5119
|
// ── SSE Broadcasting ────────────────────────────────────────────────
|
|
4723
5120
|
broadcastSSE(event, data) {
|
|
4724
5121
|
const message = `event: ${event}
|
|
@@ -4821,6 +5218,148 @@ data: ${JSON.stringify(data)}
|
|
|
4821
5218
|
}
|
|
4822
5219
|
});
|
|
4823
5220
|
|
|
5221
|
+
// src/sovereignty-profile.ts
|
|
5222
|
+
function createDefaultProfile() {
|
|
5223
|
+
return {
|
|
5224
|
+
version: 1,
|
|
5225
|
+
features: {
|
|
5226
|
+
audit_logging: { enabled: true },
|
|
5227
|
+
injection_detection: { enabled: true },
|
|
5228
|
+
context_gating: { enabled: false },
|
|
5229
|
+
approval_gate: { enabled: false },
|
|
5230
|
+
zk_proofs: { enabled: false }
|
|
5231
|
+
},
|
|
5232
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
5233
|
+
};
|
|
5234
|
+
}
|
|
5235
|
+
var NAMESPACE, PROFILE_KEY, HKDF_DOMAIN, SovereigntyProfileStore;
|
|
5236
|
+
var init_sovereignty_profile = __esm({
|
|
5237
|
+
"src/sovereignty-profile.ts"() {
|
|
5238
|
+
init_encryption();
|
|
5239
|
+
init_key_derivation();
|
|
5240
|
+
init_encoding();
|
|
5241
|
+
NAMESPACE = "_sovereignty_profile";
|
|
5242
|
+
PROFILE_KEY = "active";
|
|
5243
|
+
HKDF_DOMAIN = "sovereignty-profile";
|
|
5244
|
+
SovereigntyProfileStore = class {
|
|
5245
|
+
storage;
|
|
5246
|
+
encryptionKey;
|
|
5247
|
+
profile = null;
|
|
5248
|
+
constructor(storage, masterKey) {
|
|
5249
|
+
this.storage = storage;
|
|
5250
|
+
this.encryptionKey = derivePurposeKey(masterKey, HKDF_DOMAIN);
|
|
5251
|
+
}
|
|
5252
|
+
/**
|
|
5253
|
+
* Load the active sovereignty profile from encrypted storage.
|
|
5254
|
+
* Creates the default profile on first run.
|
|
5255
|
+
*/
|
|
5256
|
+
async load() {
|
|
5257
|
+
if (this.profile) return this.profile;
|
|
5258
|
+
const raw = await this.storage.read(NAMESPACE, PROFILE_KEY);
|
|
5259
|
+
if (raw) {
|
|
5260
|
+
try {
|
|
5261
|
+
const encrypted = JSON.parse(bytesToString(raw));
|
|
5262
|
+
const decrypted = decrypt(encrypted, this.encryptionKey);
|
|
5263
|
+
this.profile = JSON.parse(bytesToString(decrypted));
|
|
5264
|
+
return this.profile;
|
|
5265
|
+
} catch {
|
|
5266
|
+
}
|
|
5267
|
+
}
|
|
5268
|
+
this.profile = createDefaultProfile();
|
|
5269
|
+
await this.persist();
|
|
5270
|
+
return this.profile;
|
|
5271
|
+
}
|
|
5272
|
+
/**
|
|
5273
|
+
* Get the current profile. Must call load() first.
|
|
5274
|
+
*/
|
|
5275
|
+
get() {
|
|
5276
|
+
if (!this.profile) {
|
|
5277
|
+
throw new Error("SovereigntyProfileStore: call load() before get()");
|
|
5278
|
+
}
|
|
5279
|
+
return this.profile;
|
|
5280
|
+
}
|
|
5281
|
+
/**
|
|
5282
|
+
* Apply a partial update to the profile.
|
|
5283
|
+
* Returns the updated profile.
|
|
5284
|
+
*/
|
|
5285
|
+
async update(updates) {
|
|
5286
|
+
if (!this.profile) {
|
|
5287
|
+
await this.load();
|
|
5288
|
+
}
|
|
5289
|
+
const features = this.profile.features;
|
|
5290
|
+
if (updates.audit_logging !== void 0) {
|
|
5291
|
+
if (updates.audit_logging.enabled !== void 0) {
|
|
5292
|
+
if (typeof updates.audit_logging.enabled !== "boolean") {
|
|
5293
|
+
throw new Error("audit_logging.enabled must be a boolean");
|
|
5294
|
+
}
|
|
5295
|
+
features.audit_logging.enabled = updates.audit_logging.enabled;
|
|
5296
|
+
}
|
|
5297
|
+
}
|
|
5298
|
+
if (updates.injection_detection !== void 0) {
|
|
5299
|
+
if (updates.injection_detection.enabled !== void 0) {
|
|
5300
|
+
if (typeof updates.injection_detection.enabled !== "boolean") {
|
|
5301
|
+
throw new Error("injection_detection.enabled must be a boolean");
|
|
5302
|
+
}
|
|
5303
|
+
features.injection_detection.enabled = updates.injection_detection.enabled;
|
|
5304
|
+
}
|
|
5305
|
+
if (updates.injection_detection.sensitivity !== void 0) {
|
|
5306
|
+
const valid = ["low", "medium", "high"];
|
|
5307
|
+
if (!valid.includes(updates.injection_detection.sensitivity)) {
|
|
5308
|
+
throw new Error("injection_detection.sensitivity must be low, medium, or high");
|
|
5309
|
+
}
|
|
5310
|
+
features.injection_detection.sensitivity = updates.injection_detection.sensitivity;
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
if (updates.context_gating !== void 0) {
|
|
5314
|
+
if (updates.context_gating.enabled !== void 0) {
|
|
5315
|
+
if (typeof updates.context_gating.enabled !== "boolean") {
|
|
5316
|
+
throw new Error("context_gating.enabled must be a boolean");
|
|
5317
|
+
}
|
|
5318
|
+
features.context_gating.enabled = updates.context_gating.enabled;
|
|
5319
|
+
}
|
|
5320
|
+
if (updates.context_gating.policy_id !== void 0) {
|
|
5321
|
+
if (typeof updates.context_gating.policy_id !== "string" || updates.context_gating.policy_id.length > 256) {
|
|
5322
|
+
throw new Error("context_gating.policy_id must be a string of 256 characters or fewer");
|
|
5323
|
+
}
|
|
5324
|
+
features.context_gating.policy_id = updates.context_gating.policy_id;
|
|
5325
|
+
}
|
|
5326
|
+
}
|
|
5327
|
+
if (updates.approval_gate !== void 0) {
|
|
5328
|
+
if (updates.approval_gate.enabled !== void 0) {
|
|
5329
|
+
if (typeof updates.approval_gate.enabled !== "boolean") {
|
|
5330
|
+
throw new Error("approval_gate.enabled must be a boolean");
|
|
5331
|
+
}
|
|
5332
|
+
features.approval_gate.enabled = updates.approval_gate.enabled;
|
|
5333
|
+
}
|
|
5334
|
+
}
|
|
5335
|
+
if (updates.zk_proofs !== void 0) {
|
|
5336
|
+
if (updates.zk_proofs.enabled !== void 0) {
|
|
5337
|
+
if (typeof updates.zk_proofs.enabled !== "boolean") {
|
|
5338
|
+
throw new Error("zk_proofs.enabled must be a boolean");
|
|
5339
|
+
}
|
|
5340
|
+
features.zk_proofs.enabled = updates.zk_proofs.enabled;
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5343
|
+
this.profile.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
5344
|
+
await this.persist();
|
|
5345
|
+
return this.profile;
|
|
5346
|
+
}
|
|
5347
|
+
/**
|
|
5348
|
+
* Persist the current profile to encrypted storage.
|
|
5349
|
+
*/
|
|
5350
|
+
async persist() {
|
|
5351
|
+
const serialized = stringToBytes(JSON.stringify(this.profile));
|
|
5352
|
+
const encrypted = encrypt(serialized, this.encryptionKey);
|
|
5353
|
+
await this.storage.write(
|
|
5354
|
+
NAMESPACE,
|
|
5355
|
+
PROFILE_KEY,
|
|
5356
|
+
stringToBytes(JSON.stringify(encrypted))
|
|
5357
|
+
);
|
|
5358
|
+
}
|
|
5359
|
+
};
|
|
5360
|
+
}
|
|
5361
|
+
});
|
|
5362
|
+
|
|
4824
5363
|
// src/dashboard-standalone.ts
|
|
4825
5364
|
var dashboard_standalone_exports = {};
|
|
4826
5365
|
__export(dashboard_standalone_exports, {
|
|
@@ -4930,6 +5469,8 @@ async function startStandaloneDashboard(options = {}) {
|
|
|
4930
5469
|
const loadResult = await identityManager.load();
|
|
4931
5470
|
const shrOpts = { config, identityManager, masterKey };
|
|
4932
5471
|
const handshakeResults = /* @__PURE__ */ new Map();
|
|
5472
|
+
const profileStore = new SovereigntyProfileStore(storage, masterKey);
|
|
5473
|
+
await profileStore.load();
|
|
4933
5474
|
dashboard.setDependencies({
|
|
4934
5475
|
policy,
|
|
4935
5476
|
baseline,
|
|
@@ -4937,7 +5478,8 @@ async function startStandaloneDashboard(options = {}) {
|
|
|
4937
5478
|
identityManager,
|
|
4938
5479
|
handshakeResults,
|
|
4939
5480
|
shrOpts,
|
|
4940
|
-
sanctuaryConfig: config
|
|
5481
|
+
sanctuaryConfig: config,
|
|
5482
|
+
profileStore
|
|
4941
5483
|
});
|
|
4942
5484
|
dashboard.setStandaloneMode(true);
|
|
4943
5485
|
await dashboard.start();
|
|
@@ -4988,6 +5530,7 @@ var init_dashboard_standalone = __esm({
|
|
|
4988
5530
|
init_random();
|
|
4989
5531
|
init_encoding();
|
|
4990
5532
|
init_tools();
|
|
5533
|
+
init_sovereignty_profile();
|
|
4991
5534
|
}
|
|
4992
5535
|
});
|
|
4993
5536
|
|
|
@@ -5014,7 +5557,9 @@ var RESERVED_NAMESPACE_PREFIXES = [
|
|
|
5014
5557
|
"_bridge",
|
|
5015
5558
|
"_federation",
|
|
5016
5559
|
"_handshake",
|
|
5017
|
-
"_shr"
|
|
5560
|
+
"_shr",
|
|
5561
|
+
"_sovereignty_profile",
|
|
5562
|
+
"_context_gate_policies"
|
|
5018
5563
|
];
|
|
5019
5564
|
var StateStore = class {
|
|
5020
5565
|
storage;
|
|
@@ -7176,6 +7721,24 @@ function createL4Tools(storage, masterKey, identityManager, auditLog, handshakeR
|
|
|
7176
7721
|
}
|
|
7177
7722
|
const publishType = args.type;
|
|
7178
7723
|
const veracoreUrl = args.verascore_url || "https://verascore.ai";
|
|
7724
|
+
const ALLOWED_VERASCORE_HOSTS = ["verascore.ai", "www.verascore.ai", "api.verascore.ai"];
|
|
7725
|
+
try {
|
|
7726
|
+
const parsed = new URL(veracoreUrl);
|
|
7727
|
+
if (parsed.protocol !== "https:") {
|
|
7728
|
+
return toolResult({
|
|
7729
|
+
error: `verascore_url must use HTTPS. Got: ${parsed.protocol}`
|
|
7730
|
+
});
|
|
7731
|
+
}
|
|
7732
|
+
if (!ALLOWED_VERASCORE_HOSTS.includes(parsed.hostname)) {
|
|
7733
|
+
return toolResult({
|
|
7734
|
+
error: `verascore_url must point to a known Verascore domain (${ALLOWED_VERASCORE_HOSTS.join(", ")}). Got: ${parsed.hostname}`
|
|
7735
|
+
});
|
|
7736
|
+
}
|
|
7737
|
+
} catch {
|
|
7738
|
+
return toolResult({
|
|
7739
|
+
error: `verascore_url is not a valid URL: ${veracoreUrl}`
|
|
7740
|
+
});
|
|
7741
|
+
}
|
|
7179
7742
|
const agentId = args.verascore_agent_id || identity.did.replace(/[^a-zA-Z0-9-]/g, "-").toLowerCase();
|
|
7180
7743
|
let publishData;
|
|
7181
7744
|
if (args.data) {
|
|
@@ -7205,24 +7768,21 @@ function createL4Tools(storage, masterKey, identityManager, auditLog, handshakeR
|
|
|
7205
7768
|
return toolResult({ error: `Unknown publish type: ${publishType}` });
|
|
7206
7769
|
}
|
|
7207
7770
|
}
|
|
7208
|
-
const { sign:
|
|
7209
|
-
const payloadBytes =
|
|
7771
|
+
const { sign: identitySign } = await Promise.resolve().then(() => (init_identity(), identity_exports));
|
|
7772
|
+
const payloadBytes = new TextEncoder().encode(JSON.stringify(publishData));
|
|
7210
7773
|
let signatureB64;
|
|
7211
7774
|
try {
|
|
7212
|
-
const
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
]),
|
|
7219
|
-
format: "der",
|
|
7220
|
-
type: "pkcs8"
|
|
7221
|
-
});
|
|
7222
|
-
const sig = sign2(null, payloadBytes, privateKey);
|
|
7223
|
-
signatureB64 = sig.toString("base64url");
|
|
7775
|
+
const signingBytes = identitySign(
|
|
7776
|
+
payloadBytes,
|
|
7777
|
+
identity.encrypted_private_key,
|
|
7778
|
+
identityEncryptionKey
|
|
7779
|
+
);
|
|
7780
|
+
signatureB64 = toBase64url(signingBytes);
|
|
7224
7781
|
} catch (signError) {
|
|
7225
|
-
|
|
7782
|
+
return toolResult({
|
|
7783
|
+
error: "Failed to sign publish payload. Identity key may be corrupted.",
|
|
7784
|
+
details: signError instanceof Error ? signError.message : String(signError)
|
|
7785
|
+
});
|
|
7226
7786
|
}
|
|
7227
7787
|
const requestBody = {
|
|
7228
7788
|
agentId,
|
|
@@ -12938,12 +13498,147 @@ function createL2HardeningTools(storagePath, auditLog) {
|
|
|
12938
13498
|
];
|
|
12939
13499
|
}
|
|
12940
13500
|
|
|
13501
|
+
// src/index.ts
|
|
13502
|
+
init_sovereignty_profile();
|
|
13503
|
+
|
|
13504
|
+
// src/sovereignty-profile-tools.ts
|
|
13505
|
+
init_router();
|
|
13506
|
+
init_system_prompt_generator();
|
|
13507
|
+
function createSovereigntyProfileTools(profileStore, auditLog) {
|
|
13508
|
+
const tools = [
|
|
13509
|
+
// ── Get Profile ──────────────────────────────────────────────────
|
|
13510
|
+
{
|
|
13511
|
+
name: "sanctuary/sovereignty_profile_get",
|
|
13512
|
+
description: "Get the current Sovereignty Profile \u2014 shows which Sanctuary features are active (audit logging, injection detection, context gating, approval gates, ZK proofs) and their configuration.",
|
|
13513
|
+
inputSchema: {
|
|
13514
|
+
type: "object",
|
|
13515
|
+
properties: {}
|
|
13516
|
+
},
|
|
13517
|
+
handler: async () => {
|
|
13518
|
+
const profile = profileStore.get();
|
|
13519
|
+
auditLog.append("l2", "sovereignty_profile_get", "system", {
|
|
13520
|
+
features_enabled: Object.entries(profile.features).filter(([, v]) => v.enabled).map(([k]) => k)
|
|
13521
|
+
});
|
|
13522
|
+
return toolResult({
|
|
13523
|
+
profile,
|
|
13524
|
+
message: "Current Sovereignty Profile. Use sovereignty_profile_update to change settings."
|
|
13525
|
+
});
|
|
13526
|
+
}
|
|
13527
|
+
},
|
|
13528
|
+
// ── Update Profile ───────────────────────────────────────────────
|
|
13529
|
+
{
|
|
13530
|
+
name: "sanctuary/sovereignty_profile_update",
|
|
13531
|
+
description: "Update the Sovereignty Profile feature toggles. This changes which Sanctuary protections are active. Requires human approval (Tier 1) because it modifies enforcement behavior. Pass only the features you want to change \u2014 unspecified features remain unchanged.",
|
|
13532
|
+
inputSchema: {
|
|
13533
|
+
type: "object",
|
|
13534
|
+
properties: {
|
|
13535
|
+
audit_logging: {
|
|
13536
|
+
type: "object",
|
|
13537
|
+
properties: {
|
|
13538
|
+
enabled: { type: "boolean" }
|
|
13539
|
+
},
|
|
13540
|
+
description: "Toggle audit logging on/off"
|
|
13541
|
+
},
|
|
13542
|
+
injection_detection: {
|
|
13543
|
+
type: "object",
|
|
13544
|
+
properties: {
|
|
13545
|
+
enabled: { type: "boolean" },
|
|
13546
|
+
sensitivity: {
|
|
13547
|
+
type: "string",
|
|
13548
|
+
enum: ["low", "medium", "high"],
|
|
13549
|
+
description: "Detection sensitivity threshold"
|
|
13550
|
+
}
|
|
13551
|
+
},
|
|
13552
|
+
description: "Toggle injection detection and set sensitivity"
|
|
13553
|
+
},
|
|
13554
|
+
context_gating: {
|
|
13555
|
+
type: "object",
|
|
13556
|
+
properties: {
|
|
13557
|
+
enabled: { type: "boolean" },
|
|
13558
|
+
policy_id: {
|
|
13559
|
+
type: "string",
|
|
13560
|
+
description: "ID of the context-gating policy to use"
|
|
13561
|
+
}
|
|
13562
|
+
},
|
|
13563
|
+
description: "Toggle context gating and set active policy"
|
|
13564
|
+
},
|
|
13565
|
+
approval_gate: {
|
|
13566
|
+
type: "object",
|
|
13567
|
+
properties: {
|
|
13568
|
+
enabled: { type: "boolean" }
|
|
13569
|
+
},
|
|
13570
|
+
description: "Toggle approval gates on/off"
|
|
13571
|
+
},
|
|
13572
|
+
zk_proofs: {
|
|
13573
|
+
type: "object",
|
|
13574
|
+
properties: {
|
|
13575
|
+
enabled: { type: "boolean" }
|
|
13576
|
+
},
|
|
13577
|
+
description: "Toggle zero-knowledge proofs on/off"
|
|
13578
|
+
}
|
|
13579
|
+
}
|
|
13580
|
+
},
|
|
13581
|
+
handler: async (args) => {
|
|
13582
|
+
const updates = {};
|
|
13583
|
+
if (args.audit_logging !== void 0) {
|
|
13584
|
+
updates.audit_logging = args.audit_logging;
|
|
13585
|
+
}
|
|
13586
|
+
if (args.injection_detection !== void 0) {
|
|
13587
|
+
updates.injection_detection = args.injection_detection;
|
|
13588
|
+
}
|
|
13589
|
+
if (args.context_gating !== void 0) {
|
|
13590
|
+
updates.context_gating = args.context_gating;
|
|
13591
|
+
}
|
|
13592
|
+
if (args.approval_gate !== void 0) {
|
|
13593
|
+
updates.approval_gate = args.approval_gate;
|
|
13594
|
+
}
|
|
13595
|
+
if (args.zk_proofs !== void 0) {
|
|
13596
|
+
updates.zk_proofs = args.zk_proofs;
|
|
13597
|
+
}
|
|
13598
|
+
const updated = await profileStore.update(updates);
|
|
13599
|
+
auditLog.append("l2", "sovereignty_profile_update", "system", {
|
|
13600
|
+
changes: updates,
|
|
13601
|
+
features_enabled: Object.entries(updated.features).filter(([, v]) => v.enabled).map(([k]) => k)
|
|
13602
|
+
});
|
|
13603
|
+
return toolResult({
|
|
13604
|
+
profile: updated,
|
|
13605
|
+
message: "Sovereignty Profile updated. Changes take effect immediately."
|
|
13606
|
+
});
|
|
13607
|
+
}
|
|
13608
|
+
},
|
|
13609
|
+
// ── Generate System Prompt ───────────────────────────────────────
|
|
13610
|
+
{
|
|
13611
|
+
name: "sanctuary/sovereignty_profile_generate_prompt",
|
|
13612
|
+
description: "Generate a system prompt snippet based on the active Sovereignty Profile. The snippet instructs an agent on which Sanctuary features are active and how to use them. Copy and paste this into your agent's system configuration.",
|
|
13613
|
+
inputSchema: {
|
|
13614
|
+
type: "object",
|
|
13615
|
+
properties: {}
|
|
13616
|
+
},
|
|
13617
|
+
handler: async () => {
|
|
13618
|
+
const profile = profileStore.get();
|
|
13619
|
+
const prompt = generateSystemPrompt(profile);
|
|
13620
|
+
auditLog.append("l2", "sovereignty_profile_generate_prompt", "system", {
|
|
13621
|
+
features_enabled: Object.entries(profile.features).filter(([, v]) => v.enabled).map(([k]) => k)
|
|
13622
|
+
});
|
|
13623
|
+
return toolResult({
|
|
13624
|
+
system_prompt: prompt,
|
|
13625
|
+
token_estimate: Math.ceil(prompt.length / 4),
|
|
13626
|
+
message: "Copy the system_prompt text above and paste it into your agent's system configuration. It will update dynamically as you toggle features."
|
|
13627
|
+
});
|
|
13628
|
+
}
|
|
13629
|
+
}
|
|
13630
|
+
];
|
|
13631
|
+
return { tools };
|
|
13632
|
+
}
|
|
13633
|
+
|
|
12941
13634
|
// src/index.ts
|
|
12942
13635
|
init_key_derivation();
|
|
12943
13636
|
init_random();
|
|
12944
13637
|
init_encoding();
|
|
12945
13638
|
init_config();
|
|
12946
13639
|
init_audit_log();
|
|
13640
|
+
init_sovereignty_profile();
|
|
13641
|
+
init_system_prompt_generator();
|
|
12947
13642
|
init_filesystem();
|
|
12948
13643
|
init_baseline();
|
|
12949
13644
|
init_loader();
|
|
@@ -13304,6 +13999,9 @@ async function createSanctuaryServer(options) {
|
|
|
13304
13999
|
const { tools: auditTools } = createAuditTools(config);
|
|
13305
14000
|
const { tools: contextGateTools, enforcer: contextGateEnforcer } = createContextGateTools(storage, masterKey, auditLog);
|
|
13306
14001
|
const hardeningTools = createL2HardeningTools(config.storage_path, auditLog);
|
|
14002
|
+
const profileStore = new SovereigntyProfileStore(storage, masterKey);
|
|
14003
|
+
await profileStore.load();
|
|
14004
|
+
const { tools: profileTools } = createSovereigntyProfileTools(profileStore, auditLog);
|
|
13307
14005
|
const policy = await loadPrincipalPolicy(config.storage_path);
|
|
13308
14006
|
const baseline = new BaselineTracker(storage, masterKey);
|
|
13309
14007
|
await baseline.load();
|
|
@@ -13331,7 +14029,8 @@ async function createSanctuaryServer(options) {
|
|
|
13331
14029
|
identityManager,
|
|
13332
14030
|
handshakeResults,
|
|
13333
14031
|
shrOpts: { config, identityManager, masterKey },
|
|
13334
|
-
sanctuaryConfig: config
|
|
14032
|
+
sanctuaryConfig: config,
|
|
14033
|
+
profileStore
|
|
13335
14034
|
});
|
|
13336
14035
|
await dashboard.start();
|
|
13337
14036
|
approvalChannel = dashboard;
|
|
@@ -13408,6 +14107,7 @@ async function createSanctuaryServer(options) {
|
|
|
13408
14107
|
...auditTools,
|
|
13409
14108
|
...contextGateTools,
|
|
13410
14109
|
...hardeningTools,
|
|
14110
|
+
...profileTools,
|
|
13411
14111
|
...dashboardTools,
|
|
13412
14112
|
manifestTool
|
|
13413
14113
|
];
|