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