@suveren/gateway 0.12.0 → 0.13.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 +34 -0
- package/bin/suveren-gateway.js +128 -12
- package/dist/control-plane/index.mjs +555 -122
- package/dist/mcp-server/http.mjs +487 -157
- package/dist/ui/assets/{index-BzcgeHlq.js → index-CmLqzgqA.js} +21 -21
- package/dist/ui/assets/{index-BFOprnFZ.css → index-y1OFeYnS.css} +1 -1
- package/dist/ui/index.html +2 -2
- package/lib/autostart-templates.d.mts +6 -0
- package/lib/autostart-templates.mjs +21 -4
- package/lib/config.d.mts +10 -0
- package/lib/config.mjs +79 -18
- package/lib/policy.d.mts +34 -0
- package/lib/policy.mjs +369 -0
- package/package.json +1 -1
- package/server.js +51 -8
package/README.md
CHANGED
|
@@ -185,6 +185,40 @@ See `suveren-gateway config help` for the full command reference.
|
|
|
185
185
|
|
|
186
186
|
---
|
|
187
187
|
|
|
188
|
+
## Behind a company proxy
|
|
189
|
+
|
|
190
|
+
On a company laptop that routes all internet traffic through an HTTP(S) proxy, the gateway needs two things: the proxy address, and — if that proxy does TLS inspection — the company's root certificate.
|
|
191
|
+
|
|
192
|
+
**The proxy.** Set the standard environment variables (upper or lower case both work) before starting the gateway, or save one with the CLI:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
export HTTPS_PROXY=http://proxy.corp.example:8080
|
|
196
|
+
export HTTP_PROXY=http://proxy.corp.example:8080 # usually the same value
|
|
197
|
+
export NO_PROXY=internal.example.com # optional: hosts to reach directly
|
|
198
|
+
suveren-gateway start
|
|
199
|
+
|
|
200
|
+
# or, to save it so every future start picks it up without re-exporting:
|
|
201
|
+
suveren-gateway config set proxy http://proxy.corp.example:8080
|
|
202
|
+
suveren-gateway restart
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Every outbound call this applies to — the Authority Server, the update checker, and a remote AI assistant endpoint — honours the proxy. A loopback target (the control plane and MCP server talking to each other, or a local AI assistant such as Ollama) is **never** proxied, no matter what is set — a corporate proxy has no route back to the machine it's running on.
|
|
206
|
+
|
|
207
|
+
**TLS inspection.** Many corporate proxies intercept HTTPS by re-signing every certificate with their own root — that includes the Authority Server's. If you see a certificate error mentioning an untrusted issuer, trust the company's root the same way you would for a self-hosted Authority Server:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
suveren-gateway config set ca-file /path/to/company-root-ca.pem
|
|
211
|
+
suveren-gateway restart
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
This works through the proxy exactly like it works directly — `--ca-file` applies to the certificate the gateway actually sees, proxied or not.
|
|
215
|
+
|
|
216
|
+
**The one combination that still refuses, on purpose:** [TLS pinning](#pinning-the-authority-servers-tls-certificate) (opt-in, off by default) together with a TLS-inspecting proxy. Pinning checks the certificate the gateway sees *through* the proxy — if that's the proxy's own re-signed one rather than the real Authority Server's, the pin will not match, and the gateway refuses the connection and says so, even with the company root trusted via `--ca-file`. That refusal is correct: ask network/IT to exempt the Authority Server's host from TLS inspection, the same request you'd make for any pinned certificate on that network.
|
|
217
|
+
|
|
218
|
+
**On a company-managed machine, IT can set the proxy centrally** instead of relying on `HTTPS_PROXY` being exported in every shell — see [Managed settings](docs/managed-settings.md). A policy-set `Proxy` (Windows registry or a JSON policy file) **overrides** an already-set `HTTP_PROXY`/`HTTPS_PROXY` rather than merely filling it in, and `config set proxy` / `--proxy` refuse with "set by your IT" when it's locked. A loopback target is still never proxied, regardless.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
188
222
|
## Simulation mode — block every real system
|
|
189
223
|
|
|
190
224
|
A mandate is bound to a *profile* (e.g. "sales"), not to a specific connector. If a real
|
package/bin/suveren-gateway.js
CHANGED
|
@@ -17,10 +17,11 @@ import { homedir, platform, userInfo } from 'node:os';
|
|
|
17
17
|
import { dirname, join, resolve } from 'node:path';
|
|
18
18
|
import { fileURLToPath } from 'node:url';
|
|
19
19
|
import { buildLaunchAgentPlist, buildMacLauncher, buildSystemdUnit, buildWindowsTaskXml } from '../lib/autostart-templates.mjs';
|
|
20
|
-
import { DEFAULT_AS_URL, readConfig, writeConfig, validateAsUrl, validateCaFile, validatePinTls, resolveAsUrl, resolvePinTls, resolvePinTlsExpectedFingerprint, resolveSimulation } from '../lib/config.mjs';
|
|
20
|
+
import { DEFAULT_AS_URL, readConfig, writeConfig, validateAsUrl, validateCaFile, validateProxyUrl, validatePinTls, resolveAsUrl, resolvePinTls, resolvePinTlsExpectedFingerprint, resolveSimulation } from '../lib/config.mjs';
|
|
21
21
|
import { createInterface } from 'node:readline/promises';
|
|
22
22
|
import { readPairing as readAsPairing, recordTlsPin, formatFingerprint, normalizeFingerprint } from '../lib/as-pairing.mjs';
|
|
23
23
|
import { unsupportedNodeReason } from '../lib/node-version.mjs';
|
|
24
|
+
import { readPolicy, isPolicyLocked } from '../lib/policy.mjs';
|
|
24
25
|
|
|
25
26
|
// Before any command: on an unsupported Node the connectors cannot run (see
|
|
26
27
|
// lib/node-version.mjs), so refuse with the reason instead of starting.
|
|
@@ -199,6 +200,18 @@ async function start(args) {
|
|
|
199
200
|
caFileToSave = v.path;
|
|
200
201
|
}
|
|
201
202
|
|
|
203
|
+
const proxyFlag = flagValue(args, '--proxy');
|
|
204
|
+
let proxyToSave = null;
|
|
205
|
+
if (proxyFlag) {
|
|
206
|
+
refuseIfLockedByPolicy('proxy', 'proxy');
|
|
207
|
+
const v = validateProxyUrl(proxyFlag);
|
|
208
|
+
if (!v.ok) {
|
|
209
|
+
console.error(`Invalid --proxy: ${v.error}`);
|
|
210
|
+
process.exit(1);
|
|
211
|
+
}
|
|
212
|
+
proxyToSave = v.url;
|
|
213
|
+
}
|
|
214
|
+
|
|
202
215
|
// --pin-tls: a boolean flag (turns TLS certificate pinning ON — there is
|
|
203
216
|
// no `start --pin-tls off`; use `config set pin-tls off` for that).
|
|
204
217
|
// Validated against the EFFECTIVE as-url for this very start (the flag
|
|
@@ -275,6 +288,12 @@ async function start(args) {
|
|
|
275
288
|
writeConfig(DATA_DIR, { caFile: caFileToSave });
|
|
276
289
|
console.log(`CA file: ${caFileToSave} (saved — applied to every process this gateway starts)`);
|
|
277
290
|
}
|
|
291
|
+
if (proxyToSave) {
|
|
292
|
+
writeConfig(DATA_DIR, { proxyUrl: proxyToSave });
|
|
293
|
+
process.env.HTTP_PROXY ??= proxyToSave;
|
|
294
|
+
process.env.HTTPS_PROXY ??= proxyToSave;
|
|
295
|
+
console.log(`Proxy: ${proxyToSave} (saved — applied to every process this gateway starts, unless HTTP_PROXY/HTTPS_PROXY is already set)`);
|
|
296
|
+
}
|
|
278
297
|
if (pinTlsToSave) {
|
|
279
298
|
const effectiveAsUrl = asUrlToSave ?? resolveAsUrl(DATA_DIR);
|
|
280
299
|
const committed = commitConfirmedFingerprint(DATA_DIR, effectiveAsUrl, confirmedFingerprintHex);
|
|
@@ -519,16 +538,36 @@ function printConfigHelp() {
|
|
|
519
538
|
console.log(`suveren-gateway config — read or save gateway settings
|
|
520
539
|
|
|
521
540
|
Usage:
|
|
522
|
-
suveren-gateway config get [as-url|ca-file|pin-tls] Print the resolved value(s)
|
|
541
|
+
suveren-gateway config get [as-url|ca-file|pin-tls|proxy] Print the resolved value(s)
|
|
523
542
|
suveren-gateway config set as-url <url> Save the Authority Server URL
|
|
524
543
|
suveren-gateway config set ca-file <path> Save a CA bundle for internal TLS
|
|
525
544
|
suveren-gateway config set pin-tls on --expect-fingerprint <sha256-hex>
|
|
526
545
|
Pin the Authority Server's TLS certificate
|
|
527
546
|
suveren-gateway config set pin-tls off Stop enforcing the TLS certificate pin
|
|
547
|
+
suveren-gateway config set proxy <url> Save an HTTP(S) proxy (http(s)://host:port)
|
|
528
548
|
|
|
529
549
|
Saved in ${join(DATA_DIR, 'config.json')}.
|
|
530
|
-
Precedence at start: --as-url flag > env SUVEREN_AS_URL > saved
|
|
531
|
-
default (${DEFAULT_AS_URL}).
|
|
550
|
+
Precedence at start: IT policy > --as-url flag > env SUVEREN_AS_URL > saved
|
|
551
|
+
as-url > default (${DEFAULT_AS_URL}).
|
|
552
|
+
|
|
553
|
+
A setting your organization's IT has set centrally (Windows registry policy,
|
|
554
|
+
or a policy file — see docs/managed-settings.md) is LOCKED: \`config get\`
|
|
555
|
+
shows "(set by your IT)" next to it, and \`config set\` refuses to change it.
|
|
556
|
+
|
|
557
|
+
proxy is a convenience for operators without shell access to set
|
|
558
|
+
HTTP_PROXY/HTTPS_PROXY themselves — those environment variables remain the
|
|
559
|
+
actual requirement (every process this gateway runs honours them directly)
|
|
560
|
+
and always win if already set; a saved proxy only fills in whichever of the
|
|
561
|
+
two is still unset. NO_PROXY is honoured too, read directly from the
|
|
562
|
+
environment (there is no saved equivalent). A loopback target (the control
|
|
563
|
+
plane and the MCP server talking to each other, or a local AI assistant) is
|
|
564
|
+
never proxied, independent of any of this.
|
|
565
|
+
|
|
566
|
+
An IT-set Proxy policy is the ONE locked setting that OVERRIDES an
|
|
567
|
+
already-set HTTP_PROXY/HTTPS_PROXY rather than merely out-ranking a saved
|
|
568
|
+
value — the Windows-company-laptop case, where the proxy lives in system
|
|
569
|
+
settings, not something an employee's shell exports. A NoProxy policy
|
|
570
|
+
likewise overrides NO_PROXY. See docs/managed-settings.md.
|
|
532
571
|
|
|
533
572
|
pin-tls (default off, self-hosted Authority Servers with a stable signing
|
|
534
573
|
key) requires https:// and pins the Authority Server's TLS certificate
|
|
@@ -564,21 +603,48 @@ running gateway keeps using what it already resolved at its own startup.
|
|
|
564
603
|
`);
|
|
565
604
|
}
|
|
566
605
|
|
|
606
|
+
/** Appended to `config get` output when IT policy has set this key — see
|
|
607
|
+
* lib/policy.mjs. Purely informational here; the refusal itself lives in
|
|
608
|
+
* `refuseIfLockedByPolicy`, called from `config set` / `simulation`. */
|
|
609
|
+
function policySuffix(key) {
|
|
610
|
+
return isPolicyLocked(key) ? ' (set by your IT)' : '';
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Refuse a `config set` / `simulation on|off` for a key IT policy already
|
|
615
|
+
* controls. A policy value is the top precedence tier (see policy.mjs) —
|
|
616
|
+
* writing a saved config.json value anyway would be actively misleading
|
|
617
|
+
* (`config get` would show something that is NOT what's actually running),
|
|
618
|
+
* so this exits before any validation or write happens, naming the policy
|
|
619
|
+
* value so the person doesn't have to go find it themselves.
|
|
620
|
+
*/
|
|
621
|
+
function refuseIfLockedByPolicy(key, humanName, display) {
|
|
622
|
+
if (!isPolicyLocked(key)) return;
|
|
623
|
+
const value = readPolicy().policy[key];
|
|
624
|
+
console.error(`${humanName} is set by your IT policy (${display ? display(value) : value}) and cannot be changed here.`);
|
|
625
|
+
console.error('Contact your IT administrator to change it.');
|
|
626
|
+
process.exit(1);
|
|
627
|
+
}
|
|
628
|
+
|
|
567
629
|
async function config(args) {
|
|
568
630
|
const sub = args[0];
|
|
569
631
|
|
|
570
632
|
if (sub === 'get') {
|
|
571
633
|
const key = args[1];
|
|
572
634
|
const saved = readConfig(DATA_DIR);
|
|
635
|
+
const policyCaFile = readPolicy().policy.caFile;
|
|
636
|
+
const policyProxy = readPolicy().policy.proxy;
|
|
573
637
|
if (!key) {
|
|
574
|
-
console.log(`as-url: ${resolveAsUrl(DATA_DIR)}`);
|
|
575
|
-
console.log(`ca-file: ${saved.caFile ?? '(not set)'}`);
|
|
576
|
-
console.log(`pin-tls: ${resolvePinTls(DATA_DIR) ? 'on' : 'off'}`);
|
|
638
|
+
console.log(`as-url: ${resolveAsUrl(DATA_DIR)}${policySuffix('asUrl')}`);
|
|
639
|
+
console.log(`ca-file: ${(policyCaFile ?? saved.caFile) ?? '(not set)'}${policySuffix('caFile')}`);
|
|
640
|
+
console.log(`pin-tls: ${resolvePinTls(DATA_DIR) ? 'on' : 'off'}${policySuffix('pinTls')}`);
|
|
641
|
+
console.log(`proxy: ${(policyProxy ?? saved.proxyUrl) ?? '(not set)'}${policySuffix('proxy')}`);
|
|
577
642
|
return;
|
|
578
643
|
}
|
|
579
|
-
if (key === 'as-url') { console.log(resolveAsUrl(DATA_DIR)); return; }
|
|
580
|
-
if (key === 'ca-file') { console.log(saved.caFile ?? ''); return; }
|
|
581
|
-
if (key === 'pin-tls') { console.log(resolvePinTls(DATA_DIR) ? 'on' : 'off'); return; }
|
|
644
|
+
if (key === 'as-url') { console.log(`${resolveAsUrl(DATA_DIR)}${policySuffix('asUrl')}`); return; }
|
|
645
|
+
if (key === 'ca-file') { console.log(`${(policyCaFile ?? saved.caFile) ?? ''}${policySuffix('caFile')}`); return; }
|
|
646
|
+
if (key === 'pin-tls') { console.log(`${resolvePinTls(DATA_DIR) ? 'on' : 'off'}${policySuffix('pinTls')}`); return; }
|
|
647
|
+
if (key === 'proxy') { console.log(`${(policyProxy ?? saved.proxyUrl) ?? ''}${policySuffix('proxy')}`); return; }
|
|
582
648
|
console.error(`Unknown config key: ${key}\n`);
|
|
583
649
|
printConfigHelp();
|
|
584
650
|
process.exit(2);
|
|
@@ -588,6 +654,7 @@ async function config(args) {
|
|
|
588
654
|
const key = args[1];
|
|
589
655
|
const value = args[2];
|
|
590
656
|
if (key === 'as-url') {
|
|
657
|
+
refuseIfLockedByPolicy('asUrl', 'as-url');
|
|
591
658
|
if (!value) {
|
|
592
659
|
console.error('Usage: suveren-gateway config set as-url <url>');
|
|
593
660
|
process.exit(2);
|
|
@@ -603,6 +670,7 @@ async function config(args) {
|
|
|
603
670
|
return;
|
|
604
671
|
}
|
|
605
672
|
if (key === 'ca-file') {
|
|
673
|
+
refuseIfLockedByPolicy('caFile', 'ca-file');
|
|
606
674
|
if (!value) {
|
|
607
675
|
console.error('Usage: suveren-gateway config set ca-file <path>');
|
|
608
676
|
process.exit(2);
|
|
@@ -617,7 +685,25 @@ async function config(args) {
|
|
|
617
685
|
console.log('Restart to pick it up: suveren-gateway restart');
|
|
618
686
|
return;
|
|
619
687
|
}
|
|
688
|
+
if (key === 'proxy') {
|
|
689
|
+
refuseIfLockedByPolicy('proxy', 'proxy');
|
|
690
|
+
if (!value) {
|
|
691
|
+
console.error('Usage: suveren-gateway config set proxy <url>');
|
|
692
|
+
process.exit(2);
|
|
693
|
+
}
|
|
694
|
+
const v = validateProxyUrl(value);
|
|
695
|
+
if (!v.ok) {
|
|
696
|
+
console.error(`Invalid proxy: ${v.error}`);
|
|
697
|
+
process.exit(1);
|
|
698
|
+
}
|
|
699
|
+
writeConfig(DATA_DIR, { proxyUrl: v.url });
|
|
700
|
+
console.log(`Saved proxy: ${v.url}`);
|
|
701
|
+
console.log('Sets HTTP_PROXY/HTTPS_PROXY for every process this gateway starts, unless already set in the environment.');
|
|
702
|
+
console.log('Restart to pick it up: suveren-gateway restart');
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
620
705
|
if (key === 'pin-tls') {
|
|
706
|
+
refuseIfLockedByPolicy('pinTls', 'pin-tls', (v) => (v ? 'on' : 'off'));
|
|
621
707
|
if (value !== 'on' && value !== 'off') {
|
|
622
708
|
console.error('Usage: suveren-gateway config set pin-tls on|off [--expect-fingerprint <sha256-hex>]');
|
|
623
709
|
process.exit(2);
|
|
@@ -679,12 +765,17 @@ Usage:
|
|
|
679
765
|
suveren-gateway simulation status Show the saved setting and (if running) the live one
|
|
680
766
|
|
|
681
767
|
Changes take effect on the next \`suveren-gateway start\` / \`restart\`.
|
|
768
|
+
|
|
769
|
+
If your organization's IT has set Simulation centrally (Windows registry
|
|
770
|
+
policy, or a policy file — see docs/managed-settings.md), it is LOCKED: both
|
|
771
|
+
\`on\` and \`off\` refuse, naming the policy value, and this cannot be
|
|
772
|
+
overridden locally — not even by setting SUVEREN_SIMULATION directly.
|
|
682
773
|
`);
|
|
683
774
|
}
|
|
684
775
|
|
|
685
776
|
async function printSimulationStatus() {
|
|
686
777
|
const saved = resolveSimulation(DATA_DIR);
|
|
687
|
-
console.log(`Saved: ${saved ? 'on' : 'off'}`);
|
|
778
|
+
console.log(`Saved: ${saved ? 'on' : 'off'}${policySuffix('simulation')}`);
|
|
688
779
|
try {
|
|
689
780
|
const res = await fetch(`http://localhost:${SUVEREN_PORT}/health`, { signal: AbortSignal.timeout(3000) });
|
|
690
781
|
if (res.ok) {
|
|
@@ -720,6 +811,7 @@ async function simulation(args) {
|
|
|
720
811
|
}
|
|
721
812
|
|
|
722
813
|
if (sub === 'on') {
|
|
814
|
+
refuseIfLockedByPolicy('simulation', 'Simulation mode', (v) => (v ? 'on' : 'off'));
|
|
723
815
|
// The safe direction — blocking real systems needs no confirmation.
|
|
724
816
|
writeConfig(DATA_DIR, { simulation: true });
|
|
725
817
|
console.log('Simulation mode: ON (saved) — every connector without a manifest "simulation" marker will be blocked.');
|
|
@@ -728,6 +820,7 @@ async function simulation(args) {
|
|
|
728
820
|
}
|
|
729
821
|
|
|
730
822
|
if (sub === 'off') {
|
|
823
|
+
refuseIfLockedByPolicy('simulation', 'Simulation mode', (v) => (v ? 'on' : 'off'));
|
|
731
824
|
console.error('Turning simulation mode OFF makes every real system reachable again: any connector');
|
|
732
825
|
console.error('without a manifest "simulation" marker (e.g. a live Gmail or ERP account) will spawn');
|
|
733
826
|
console.error('and execute for real the next time this gateway starts.');
|
|
@@ -995,6 +1088,19 @@ async function serviceInstallWindows() {
|
|
|
995
1088
|
// Deliberately does NOT stop the running gateway — see the macOS note.
|
|
996
1089
|
// Registering is enough; Task Scheduler starts it at the next logon.
|
|
997
1090
|
|
|
1091
|
+
// SUVEREN_LAUNCHER (set by the Windows installer's launcher.cmd, never by
|
|
1092
|
+
// a plain npm/dev install) means this `service install` was itself invoked
|
|
1093
|
+
// THROUGH that launcher — route the scheduled task through it too, instead
|
|
1094
|
+
// of straight at node.exe/server.js. The launcher sets SUVEREN_INSTALL_
|
|
1095
|
+
// METHOD/SUVEREN_OFFLINE/SUVEREN_INTEGRATIONS_DIR/PATH itself, scoped to
|
|
1096
|
+
// just the gateway process it starts; writing those into HKCU\Environment
|
|
1097
|
+
// (an earlier version of the installer did this) is ACCOUNT-WIDE — it
|
|
1098
|
+
// would shadow a developer's own Node for every other program on that
|
|
1099
|
+
// account and force every other gateway install under the same user into
|
|
1100
|
+
// offline+managed mode too. Absent (every non-managed install), this is a
|
|
1101
|
+
// no-op: buildWindowsTaskXml renders identically to before.
|
|
1102
|
+
const launcherPath = process.env.SUVEREN_LAUNCHER;
|
|
1103
|
+
|
|
998
1104
|
// schtasks reads the XML from a file and requires UTF-16 LE with a BOM —
|
|
999
1105
|
// it rejects UTF-8 with an unhelpful "The task XML is malformed".
|
|
1000
1106
|
const xml = buildWindowsTaskXml({
|
|
@@ -1003,6 +1109,7 @@ async function serviceInstallWindows() {
|
|
|
1003
1109
|
author: 'Suveren',
|
|
1004
1110
|
dataDir: process.env.SUVEREN_DATA_DIR ?? '',
|
|
1005
1111
|
userId: windowsUserId(),
|
|
1112
|
+
...(launcherPath ? { command: launcherPath, args: 'run' } : {}),
|
|
1006
1113
|
});
|
|
1007
1114
|
const xmlPath = join(DATA_DIR, 'suveren-task.xml');
|
|
1008
1115
|
writeFileSync(xmlPath, '\ufeff' + xml, { encoding: 'utf16le' });
|
|
@@ -1257,6 +1364,7 @@ Usage:
|
|
|
1257
1364
|
suveren-gateway start [--detach] Run the gateway (foreground by default)
|
|
1258
1365
|
[--as-url <url>] Authority Server URL (saved for next time)
|
|
1259
1366
|
[--ca-file <path>] Internal CA bundle (saved for next time)
|
|
1367
|
+
[--proxy <url>] HTTP(S) proxy (saved for next time — see below)
|
|
1260
1368
|
[--pin-tls --expect-fingerprint <hex>] Pin the AS TLS certificate (saved; https:// only — see below)
|
|
1261
1369
|
[--simulation] Block every real system (saved — see \`simulation help\`)
|
|
1262
1370
|
suveren-gateway stop Stop a detached gateway
|
|
@@ -1265,9 +1373,10 @@ Usage:
|
|
|
1265
1373
|
suveren-gateway logs [--tail] Print or tail ~/.suveren/gateway.log
|
|
1266
1374
|
suveren-gateway service <cmd> Run as a login service that survives reboot
|
|
1267
1375
|
(install | uninstall | status)
|
|
1268
|
-
suveren-gateway config get [as-url|ca-file|pin-tls] Print the resolved value(s)
|
|
1376
|
+
suveren-gateway config get [as-url|ca-file|pin-tls|proxy] Print the resolved value(s)
|
|
1269
1377
|
suveren-gateway config set as-url <url> Save the Authority Server URL
|
|
1270
1378
|
suveren-gateway config set ca-file <path> Save a CA bundle for internal TLS
|
|
1379
|
+
suveren-gateway config set proxy <url> Save an HTTP(S) proxy (see below)
|
|
1271
1380
|
suveren-gateway config set pin-tls on --expect-fingerprint <hex>
|
|
1272
1381
|
Pin the Authority Server's TLS certificate
|
|
1273
1382
|
(see \`suveren-gateway config help\` for the fingerprint check)
|
|
@@ -1282,6 +1391,13 @@ Environment:
|
|
|
1282
1391
|
SUVEREN_DATA_DIR Data directory (default ~/.suveren)
|
|
1283
1392
|
SUVEREN_AS_URL Authority Server URL — overrides the saved as-url
|
|
1284
1393
|
SUVEREN_SIMULATION 1 to force simulation mode for this run — overrides the saved setting
|
|
1394
|
+
HTTP_PROXY / HTTPS_PROXY / NO_PROXY (upper or lower case)
|
|
1395
|
+
Corporate proxy — honoured for every outbound call to the Authority
|
|
1396
|
+
Server, the update checker, and a remote AI assistant endpoint. A
|
|
1397
|
+
loopback target (127.0.0.1/localhost, incl. a local AI assistant) is
|
|
1398
|
+
never proxied. These win over a saved \`config set proxy\` — UNLESS
|
|
1399
|
+
your organization's IT has set a Proxy/NoProxy policy, which wins
|
|
1400
|
+
over both (see docs/managed-settings.md).
|
|
1285
1401
|
|
|
1286
1402
|
Authority Server resolution order: --as-url flag > SUVEREN_AS_URL env >
|
|
1287
1403
|
saved as-url (\`config set as-url\`) > default (${DEFAULT_AS_URL}).
|