borgmcp-server 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +105 -0
- package/NOTICE +8 -0
- package/README.md +119 -0
- package/SECURITY.md +38 -0
- package/THIRD_PARTY_NOTICES.md +35 -0
- package/dist/bootstrap.d.ts +18 -0
- package/dist/bootstrap.js +104 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.js +96 -0
- package/dist/cli.js.map +1 -0
- package/dist/coordination-api.d.ts +25 -0
- package/dist/coordination-api.js +457 -0
- package/dist/coordination-api.js.map +1 -0
- package/dist/credentials.d.ts +58 -0
- package/dist/credentials.js +244 -0
- package/dist/credentials.js.map +1 -0
- package/dist/enrollment.d.ts +17 -0
- package/dist/enrollment.js +122 -0
- package/dist/enrollment.js.map +1 -0
- package/dist/https-server.d.ts +94 -0
- package/dist/https-server.js +814 -0
- package/dist/https-server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/main.d.ts +3 -0
- package/dist/main.js +67 -0
- package/dist/main.js.map +1 -0
- package/dist/migrations.d.ts +8 -0
- package/dist/migrations.js +366 -0
- package/dist/migrations.js.map +1 -0
- package/dist/network-policy.d.ts +13 -0
- package/dist/network-policy.js +49 -0
- package/dist/network-policy.js.map +1 -0
- package/dist/operator-error.d.ts +3 -0
- package/dist/operator-error.js +63 -0
- package/dist/operator-error.js.map +1 -0
- package/dist/principal.d.ts +32 -0
- package/dist/principal.js +64 -0
- package/dist/principal.js.map +1 -0
- package/dist/protocol-draft.d.ts +2 -0
- package/dist/protocol-draft.js +31 -0
- package/dist/protocol-draft.js.map +1 -0
- package/dist/service.d.ts +61 -0
- package/dist/service.js +455 -0
- package/dist/service.js.map +1 -0
- package/dist/start-options.d.ts +2 -0
- package/dist/start-options.js +46 -0
- package/dist/start-options.js.map +1 -0
- package/dist/store.d.ts +327 -0
- package/dist/store.js +1729 -0
- package/dist/store.js.map +1 -0
- package/npm-shrinkwrap.json +1942 -0
- package/package.json +60 -0
- package/src/bootstrap.ts +127 -0
- package/src/cli.ts +102 -0
- package/src/coordination-api.ts +508 -0
- package/src/credentials.ts +319 -0
- package/src/enrollment.ts +156 -0
- package/src/https-server.ts +962 -0
- package/src/index.ts +3 -0
- package/src/main.ts +73 -0
- package/src/migrations.ts +394 -0
- package/src/network-policy.ts +65 -0
- package/src/operator-error.ts +97 -0
- package/src/principal.ts +106 -0
- package/src/protocol-draft.ts +32 -0
- package/src/service.ts +525 -0
- package/src/start-options.ts +46 -0
- package/src/store.ts +2316 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, ALv2 Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-ALv2
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Byte Ventures
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the Apache License, Version 2.0 that is effective on the second anniversary of
|
|
91
|
+
the date we make the Software available. On or after that date, you may use the
|
|
92
|
+
Software under the Apache License, Version 2.0, in which case the following
|
|
93
|
+
will apply:
|
|
94
|
+
|
|
95
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
96
|
+
this file except in compliance with the License.
|
|
97
|
+
|
|
98
|
+
You may obtain a copy of the License at
|
|
99
|
+
|
|
100
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
101
|
+
|
|
102
|
+
Unless required by applicable law or agreed to in writing, software distributed
|
|
103
|
+
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
104
|
+
CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
105
|
+
specific language governing permissions and limitations under the License.
|
package/NOTICE
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
borgmcp-server
|
|
2
|
+
Copyright 2026 Byte Ventures
|
|
3
|
+
|
|
4
|
+
This product is licensed under the Functional Source License, Version 1.1,
|
|
5
|
+
ALv2 Future License (FSL-1.1-ALv2). See LICENSE for the controlling terms.
|
|
6
|
+
|
|
7
|
+
This product includes third-party software. See THIRD_PARTY_NOTICES.md and the
|
|
8
|
+
CycloneDX SBOM distributed with each release workflow artifact.
|
package/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# borgmcp-server
|
|
2
|
+
|
|
3
|
+
`borgmcp-server` is the self-hosted coordination authority for Borg MCP. It
|
|
4
|
+
stores cube state locally and serves the Borg protocol over authenticated
|
|
5
|
+
HTTPS.
|
|
6
|
+
|
|
7
|
+
## Release status
|
|
8
|
+
|
|
9
|
+
The current source is the unpublished `0.1.1-preview` recovery release candidate.
|
|
10
|
+
Purpose-bound owner enrollment, idempotent multi-cube creation, and stable
|
|
11
|
+
prior-seat reattachment have completed coordinated client/server security
|
|
12
|
+
review and process dogfood against the audited exact `borgmcp-shared@0.3.0`
|
|
13
|
+
registry release.
|
|
14
|
+
|
|
15
|
+
Setup prepares local identity and storage and prints one-time recovery and
|
|
16
|
+
owner-enrollment secrets; it creates no cube. The package remains unreleased
|
|
17
|
+
until the exact release commit and tagged artifact complete the documented
|
|
18
|
+
review, authorization, and protected-publication gates.
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- Node.js 22.12 or later
|
|
23
|
+
- npm 10 or later
|
|
24
|
+
- A private local data directory with sufficient disk space
|
|
25
|
+
|
|
26
|
+
## Install after publication
|
|
27
|
+
|
|
28
|
+
The global package command becomes available only after the pending npm release
|
|
29
|
+
completes. Until then, source and preview reviewers should follow the release
|
|
30
|
+
status above and the [release runbook](docs/releasing.md), not expect this
|
|
31
|
+
registry install to succeed.
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
npm install --global borgmcp-server
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Set up a local server
|
|
38
|
+
|
|
39
|
+
The default data directory is `~/.borg/server`. Setup creates the local
|
|
40
|
+
database, credential-digest key, local certificate authority, server
|
|
41
|
+
certificate, one recovery credential, and one enrollment invitation. It creates
|
|
42
|
+
no cube. Run it in a private terminal because both secrets are printed only
|
|
43
|
+
once.
|
|
44
|
+
|
|
45
|
+
```sh
|
|
46
|
+
borg-mcp-server setup
|
|
47
|
+
borg-mcp-server start
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The server listens on `https://127.0.0.1:7091` by default. Use
|
|
51
|
+
`BORG_SERVER_DATA_DIR` to select another data directory.
|
|
52
|
+
|
|
53
|
+
## Network configuration
|
|
54
|
+
|
|
55
|
+
Loopback is the safe default. Binding to a private LAN address requires both an
|
|
56
|
+
explicit address and `--lan` consent:
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
borg-mcp-server start --host 192.168.1.20 --port 7091 --lan
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Before LAN startup, move `ca.key` out of the runtime data directory. Keep the
|
|
63
|
+
CA private key offline; the running service does not need it. Public, wildcard,
|
|
64
|
+
unspecified, multicast, and otherwise unsafe bind addresses are rejected.
|
|
65
|
+
|
|
66
|
+
TLS files may instead be supplied explicitly with
|
|
67
|
+
`BORG_SERVER_TLS_KEY_FILE`, `BORG_SERVER_TLS_CERT_FILE`, and
|
|
68
|
+
`BORG_SERVER_TLS_CA_FILE`. Run `borg-mcp-server help` for the complete command
|
|
69
|
+
summary.
|
|
70
|
+
|
|
71
|
+
## Offline credential administration
|
|
72
|
+
|
|
73
|
+
Stop the server before all offline client administration:
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
borg-mcp-server client-rotate <client-id>
|
|
77
|
+
borg-mcp-server client-revoke <client-id>
|
|
78
|
+
borg-mcp-server client-invite
|
|
79
|
+
borg-mcp-server owner-invite
|
|
80
|
+
borg-mcp-server client-grant <client-id> <cube-id> <read|write|manage>
|
|
81
|
+
borg-mcp-server client-ungrant <client-id> <cube-id>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Invitation commands read the recovery credential from a private hidden terminal
|
|
85
|
+
prompt, never argv or environment. Rotation and invitation commands print their
|
|
86
|
+
replacement secret once. Treat setup, enrollment, invitation, and rotation
|
|
87
|
+
output as secrets; do not paste it into issues, logs, or chat.
|
|
88
|
+
|
|
89
|
+
## Capacity controls
|
|
90
|
+
|
|
91
|
+
The server accepts positive integer values for these optional environment
|
|
92
|
+
variables:
|
|
93
|
+
|
|
94
|
+
- `BORG_SERVER_MAX_ACTIVITY_ENTRIES_PER_CUBE`
|
|
95
|
+
- `BORG_SERVER_MAX_DATABASE_BYTES`
|
|
96
|
+
- `BORG_SERVER_MIN_FREE_DISK_BYTES`
|
|
97
|
+
|
|
98
|
+
Invalid values fail closed before the server starts.
|
|
99
|
+
Cube creation is additionally bounded to 100 cubes per creating client and
|
|
100
|
+
1,000 cubes per server. Exact idempotent retries do not consume quota twice.
|
|
101
|
+
|
|
102
|
+
## Library entry point
|
|
103
|
+
|
|
104
|
+
The package exports `runCli`, `CliIo`, and `ServerService` for controlled
|
|
105
|
+
embedding. Most installations should use the `borg-mcp-server` executable.
|
|
106
|
+
|
|
107
|
+
## Security and support
|
|
108
|
+
|
|
109
|
+
Read [SECURITY.md](SECURITY.md) before exposing the service beyond loopback.
|
|
110
|
+
Use GitHub Issues for reproducible non-sensitive defects. Report
|
|
111
|
+
vulnerabilities privately as described in the security policy.
|
|
112
|
+
|
|
113
|
+
## License
|
|
114
|
+
|
|
115
|
+
This server is licensed under the Functional Source License, Version 1.1,
|
|
116
|
+
ALv2 Future License (`FSL-1.1-ALv2`). Each released version becomes available
|
|
117
|
+
under Apache License 2.0 on the second anniversary of the date that version was
|
|
118
|
+
made available. See [LICENSE](LICENSE) for the controlling terms and
|
|
119
|
+
[THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md) for dependency disclosures.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Security policy
|
|
2
|
+
|
|
3
|
+
## Supported versions
|
|
4
|
+
|
|
5
|
+
Security fixes are provided for the latest release of `borgmcp-server`. Upgrade
|
|
6
|
+
to the newest published version before reporting a problem that may already be
|
|
7
|
+
resolved.
|
|
8
|
+
|
|
9
|
+
## Reporting a vulnerability
|
|
10
|
+
|
|
11
|
+
Use GitHub's private vulnerability reporting for this repository:
|
|
12
|
+
|
|
13
|
+
https://github.com/Byte-Ventures/borg-mcp-server/security/advisories/new
|
|
14
|
+
|
|
15
|
+
Do not open a public issue for a suspected vulnerability. Include the affected
|
|
16
|
+
version, impact, prerequisites, and minimal reproduction steps. Remove all real
|
|
17
|
+
credentials, invitation tokens, private keys, database contents, and private
|
|
18
|
+
deployment details from the report.
|
|
19
|
+
|
|
20
|
+
We will acknowledge the report through the private advisory and coordinate
|
|
21
|
+
validation, remediation, and disclosure there. Please do not disclose the
|
|
22
|
+
issue publicly until a release or other mitigation is available and disclosure
|
|
23
|
+
has been coordinated.
|
|
24
|
+
|
|
25
|
+
## Deployment guidance
|
|
26
|
+
|
|
27
|
+
- Keep the default loopback binding unless private-LAN access is necessary.
|
|
28
|
+
- Treat `--lan` as explicit consent to network exposure, not as a firewall or
|
|
29
|
+
access-control substitute.
|
|
30
|
+
- Keep the local CA private key offline whenever the server is running on a
|
|
31
|
+
private LAN.
|
|
32
|
+
- Restrict the data directory and all generated credentials to the service
|
|
33
|
+
account.
|
|
34
|
+
- Capture one-time setup and rotation credentials only in a private terminal.
|
|
35
|
+
- Stop the server before offline credential rotation or revocation.
|
|
36
|
+
- Back up sensitive state using encrypted storage and test restoration in a
|
|
37
|
+
separate environment.
|
|
38
|
+
- Review dependency and release provenance before upgrading.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
`borgmcp-server` installs the following production dependency tree from the
|
|
4
|
+
public npm registry. Copyright remains with the respective authors. The
|
|
5
|
+
license identifiers below are taken from the exact locked package metadata;
|
|
6
|
+
refer to each installed package for its complete license text.
|
|
7
|
+
|
|
8
|
+
| Package | Version | License |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| `@noble/hashes` | 1.4.0 | MIT |
|
|
11
|
+
| `@peculiar/asn1-cms` | 2.8.0 | MIT |
|
|
12
|
+
| `@peculiar/asn1-csr` | 2.8.0 | MIT |
|
|
13
|
+
| `@peculiar/asn1-ecc` | 2.8.0 | MIT |
|
|
14
|
+
| `@peculiar/asn1-pfx` | 2.8.0 | MIT |
|
|
15
|
+
| `@peculiar/asn1-pkcs8` | 2.8.0 | MIT |
|
|
16
|
+
| `@peculiar/asn1-pkcs9` | 2.8.0 | MIT |
|
|
17
|
+
| `@peculiar/asn1-rsa` | 2.8.0 | MIT |
|
|
18
|
+
| `@peculiar/asn1-schema` | 2.8.0 | MIT |
|
|
19
|
+
| `@peculiar/asn1-x509` | 2.8.0 | MIT |
|
|
20
|
+
| `@peculiar/asn1-x509-attr` | 2.8.0 | MIT |
|
|
21
|
+
| `@peculiar/utils` | 2.0.3 | MIT |
|
|
22
|
+
| `@peculiar/x509` | 1.14.3 | MIT |
|
|
23
|
+
| `asn1js` | 3.0.10 | BSD-3-Clause |
|
|
24
|
+
| `bytestreamjs` | 2.0.1 | BSD-3-Clause |
|
|
25
|
+
| `pkijs` | 3.4.0 | BSD-3-Clause |
|
|
26
|
+
| `pvtsutils` | 1.3.6 | MIT |
|
|
27
|
+
| `pvutils` | 1.1.5 | MIT |
|
|
28
|
+
| `reflect-metadata` | 0.2.2 | Apache-2.0 |
|
|
29
|
+
| `selfsigned` | 5.5.0 | MIT |
|
|
30
|
+
| `tslib` | 1.14.1, 2.8.1 | 0BSD |
|
|
31
|
+
| `tsyringe` | 4.10.0 | MIT |
|
|
32
|
+
|
|
33
|
+
The release workflow generates a CycloneDX SBOM from `npm-shrinkwrap.json` for
|
|
34
|
+
the exact artifact under review. Development-only packages are recorded in the
|
|
35
|
+
source shrinkwrap and generated SBOM but are not installed for package users.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface BootstrapResult {
|
|
2
|
+
readonly serverId: string;
|
|
3
|
+
readonly caFingerprint: string;
|
|
4
|
+
readonly recoveryCredential: string;
|
|
5
|
+
readonly initialInvitation: string;
|
|
6
|
+
readonly paths: {
|
|
7
|
+
readonly database: string;
|
|
8
|
+
readonly digestKey: string;
|
|
9
|
+
readonly caKey: string;
|
|
10
|
+
readonly caCertificate: string;
|
|
11
|
+
readonly serverKey: string;
|
|
12
|
+
readonly serverCertificate: string;
|
|
13
|
+
readonly config: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function bootstrapServer(dataDirectory: string, bindHost?: string, clock?: () => Date): Promise<BootstrapResult>;
|
|
17
|
+
export declare function loadDigestKey(path: string): Promise<Buffer>;
|
|
18
|
+
export declare function loadTlsPrivateKey(path: string): Promise<Buffer>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createHash, randomBytes, randomUUID, X509Certificate } from "node:crypto";
|
|
2
|
+
import { lstat, readFile, stat, writeFile } from "node:fs/promises";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { generate } from "selfsigned";
|
|
5
|
+
import { CredentialAuthority, CredentialDigester } from "./credentials.js";
|
|
6
|
+
import { openStore } from "./store.js";
|
|
7
|
+
export async function bootstrapServer(dataDirectory, bindHost = "127.0.0.1", clock = () => new Date()) {
|
|
8
|
+
const directory = resolve(dataDirectory);
|
|
9
|
+
const paths = {
|
|
10
|
+
database: join(directory, "borg.db"),
|
|
11
|
+
digestKey: join(directory, "credential-digest.key"),
|
|
12
|
+
caKey: join(directory, "ca.key"),
|
|
13
|
+
caCertificate: join(directory, "ca.crt"),
|
|
14
|
+
serverKey: join(directory, "server.key"),
|
|
15
|
+
serverCertificate: join(directory, "server.crt"),
|
|
16
|
+
config: join(directory, "server.json"),
|
|
17
|
+
};
|
|
18
|
+
const ca = await generate([{ name: "commonName", value: "Borg Local CA" }], {
|
|
19
|
+
algorithm: "sha256",
|
|
20
|
+
keyType: "ec",
|
|
21
|
+
extensions: [
|
|
22
|
+
{ name: "basicConstraints", cA: true, pathLenConstraint: 0, critical: true },
|
|
23
|
+
{ name: "keyUsage", keyCertSign: true, cRLSign: true, critical: true },
|
|
24
|
+
],
|
|
25
|
+
});
|
|
26
|
+
const server = await generate([{ name: "commonName", value: "Borg Local Server" }], {
|
|
27
|
+
algorithm: "sha256",
|
|
28
|
+
keyType: "ec",
|
|
29
|
+
ca: { key: ca.private, cert: ca.cert },
|
|
30
|
+
extensions: [
|
|
31
|
+
{ name: "basicConstraints", cA: false, critical: true },
|
|
32
|
+
{ name: "keyUsage", digitalSignature: true, keyAgreement: true, critical: true },
|
|
33
|
+
{ name: "extKeyUsage", serverAuth: true },
|
|
34
|
+
{ name: "subjectAltName", altNames: [{ type: 7, ip: bindHost }] },
|
|
35
|
+
],
|
|
36
|
+
});
|
|
37
|
+
const serverId = randomUUID();
|
|
38
|
+
const caCertificate = new X509Certificate(ca.cert);
|
|
39
|
+
const caFingerprint = createHash("sha256")
|
|
40
|
+
.update(caCertificate.publicKey.export({ type: "spki", format: "der" }))
|
|
41
|
+
.digest("hex");
|
|
42
|
+
const digestKey = randomBytes(32);
|
|
43
|
+
const runtime = await openStore({ path: paths.database, clock });
|
|
44
|
+
try {
|
|
45
|
+
await Promise.all([
|
|
46
|
+
writePrivate(paths.digestKey, digestKey),
|
|
47
|
+
writePrivate(paths.caKey, ca.private),
|
|
48
|
+
writePrivate(paths.caCertificate, ca.cert),
|
|
49
|
+
writePrivate(paths.serverKey, server.private),
|
|
50
|
+
writePrivate(paths.serverCertificate, server.cert),
|
|
51
|
+
writePrivate(paths.config, JSON.stringify({
|
|
52
|
+
server_id: serverId,
|
|
53
|
+
ca_spki_sha256: caFingerprint,
|
|
54
|
+
bind_host: bindHost,
|
|
55
|
+
}, null, 2)),
|
|
56
|
+
]);
|
|
57
|
+
const digester = new CredentialDigester(digestKey);
|
|
58
|
+
digestKey.fill(0);
|
|
59
|
+
try {
|
|
60
|
+
const authority = new CredentialAuthority(runtime.credentials, digester, clock);
|
|
61
|
+
const recoveryCredential = authority.createRecoveryCredential();
|
|
62
|
+
const initialInvitation = authority.createBootstrapInvitation(15 * 60_000);
|
|
63
|
+
return {
|
|
64
|
+
serverId,
|
|
65
|
+
caFingerprint,
|
|
66
|
+
recoveryCredential,
|
|
67
|
+
initialInvitation,
|
|
68
|
+
paths,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
finally {
|
|
72
|
+
digester.destroy();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
digestKey.fill(0);
|
|
77
|
+
runtime.close();
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function writePrivate(path, value) {
|
|
81
|
+
await writeFile(path, value, { flag: "wx", mode: 0o600 });
|
|
82
|
+
if (((await stat(path)).mode & 0o777) !== 0o600) {
|
|
83
|
+
throw new Error("Bootstrap file permissions are not private.");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export async function loadDigestKey(path) {
|
|
87
|
+
const key = await loadPrivateFile(path, "Credential digest key");
|
|
88
|
+
if (key.length !== 32) {
|
|
89
|
+
key.fill(0);
|
|
90
|
+
throw new Error("Credential digest key is invalid or not private.");
|
|
91
|
+
}
|
|
92
|
+
return key;
|
|
93
|
+
}
|
|
94
|
+
export async function loadTlsPrivateKey(path) {
|
|
95
|
+
return loadPrivateFile(path, "TLS private key");
|
|
96
|
+
}
|
|
97
|
+
async function loadPrivateFile(path, label) {
|
|
98
|
+
const metadata = await lstat(path);
|
|
99
|
+
if (!metadata.isFile() || (metadata.mode & 0o077) !== 0) {
|
|
100
|
+
throw new Error(`${label} is invalid or not private.`);
|
|
101
|
+
}
|
|
102
|
+
return readFile(path);
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../src/bootstrap.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ServerService } from "./service.js";
|
|
2
|
+
export interface CliIo {
|
|
3
|
+
readonly stdout: (message: string) => void;
|
|
4
|
+
readonly stderr: (message: string) => void;
|
|
5
|
+
readonly readSecret?: (prompt: string) => Promise<string>;
|
|
6
|
+
}
|
|
7
|
+
export declare function runCli(args: readonly string[], service: ServerService, io: CliIo): Promise<number>;
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const usage = `Usage: borg-mcp-server <command> [options]
|
|
2
|
+
|
|
3
|
+
Commands:
|
|
4
|
+
setup Prepare an offline server installation
|
|
5
|
+
start Start the server process
|
|
6
|
+
client-rotate <client-id> Rotate one client credential offline
|
|
7
|
+
client-revoke <client-id> Revoke one client and its credentials offline
|
|
8
|
+
client-grant <client-id> <cube-id> <read|write|manage> Set one offline cube grant
|
|
9
|
+
client-ungrant <client-id> <cube-id> Remove one offline cube grant
|
|
10
|
+
client-invite Create one ordinary client invitation using a private recovery prompt
|
|
11
|
+
owner-invite Replace the unclaimed owner invitation using a private recovery prompt
|
|
12
|
+
help Show this help
|
|
13
|
+
|
|
14
|
+
Start options:
|
|
15
|
+
--host <ip> Explicit bind address (default: 127.0.0.1)
|
|
16
|
+
--port <number> Listen port (default: 7091)
|
|
17
|
+
--lan Consent to this start on a private LAN address
|
|
18
|
+
|
|
19
|
+
TLS files:
|
|
20
|
+
BORG_SERVER_DATA_DIR (default: ~/.borg/server), or explicit
|
|
21
|
+
BORG_SERVER_TLS_KEY_FILE, BORG_SERVER_TLS_CERT_FILE, and BORG_SERVER_TLS_CA_FILE
|
|
22
|
+
|
|
23
|
+
Stop the server before running offline client administration commands.`;
|
|
24
|
+
export async function runCli(args, service, io) {
|
|
25
|
+
const [command, ...extraArgs] = args;
|
|
26
|
+
switch (command) {
|
|
27
|
+
case "setup":
|
|
28
|
+
if (extraArgs.length !== 0)
|
|
29
|
+
return invalidArguments(io);
|
|
30
|
+
if (service.setup === undefined) {
|
|
31
|
+
io.stderr("Server setup is unavailable.");
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
const result = await service.setup();
|
|
35
|
+
io.stdout(`Server setup complete.\nRecovery credential (shown once): ${result.recoveryCredential}\nInitial enrollment invitation (shown once): ${result.initialInvitation}`);
|
|
36
|
+
return 0;
|
|
37
|
+
case "start":
|
|
38
|
+
await service.start(extraArgs);
|
|
39
|
+
return 0;
|
|
40
|
+
case "client-rotate":
|
|
41
|
+
if (extraArgs.length !== 1 || service.rotateClient === undefined)
|
|
42
|
+
return invalidArguments(io);
|
|
43
|
+
io.stdout(`Client credential rotated (shown once): ${await service.rotateClient(extraArgs[0])}`);
|
|
44
|
+
return 0;
|
|
45
|
+
case "client-revoke":
|
|
46
|
+
if (extraArgs.length !== 1 || service.revokeClient === undefined)
|
|
47
|
+
return invalidArguments(io);
|
|
48
|
+
await service.revokeClient(extraArgs[0]);
|
|
49
|
+
io.stdout("Client revoked.");
|
|
50
|
+
return 0;
|
|
51
|
+
case "client-grant": {
|
|
52
|
+
if (extraArgs.length !== 3 || service.grantClient === undefined)
|
|
53
|
+
return invalidArguments(io);
|
|
54
|
+
const access = extraArgs[2];
|
|
55
|
+
if (access !== "read" && access !== "write" && access !== "manage")
|
|
56
|
+
return invalidArguments(io);
|
|
57
|
+
await service.grantClient(extraArgs[0], extraArgs[1], access);
|
|
58
|
+
io.stdout("Client cube grant updated.");
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
case "client-ungrant":
|
|
62
|
+
if (extraArgs.length !== 2 || service.ungrantClient === undefined)
|
|
63
|
+
return invalidArguments(io);
|
|
64
|
+
await service.ungrantClient(extraArgs[0], extraArgs[1]);
|
|
65
|
+
io.stdout("Client cube grant removed.");
|
|
66
|
+
return 0;
|
|
67
|
+
case "client-invite":
|
|
68
|
+
case "owner-invite": {
|
|
69
|
+
if (extraArgs.length !== 0 || io.readSecret === undefined)
|
|
70
|
+
return invalidArguments(io);
|
|
71
|
+
const operation = command === "client-invite"
|
|
72
|
+
? service.createClientInvitation
|
|
73
|
+
: service.replaceOwnerInvitation;
|
|
74
|
+
if (operation === undefined)
|
|
75
|
+
return invalidArguments(io);
|
|
76
|
+
const recovery = await io.readSecret("Recovery credential: ");
|
|
77
|
+
const invitation = await operation(recovery);
|
|
78
|
+
io.stdout(`Enrollment invitation (shown once): ${invitation}`);
|
|
79
|
+
return 0;
|
|
80
|
+
}
|
|
81
|
+
case "help":
|
|
82
|
+
case "--help":
|
|
83
|
+
case "-h":
|
|
84
|
+
case undefined:
|
|
85
|
+
io.stdout(usage);
|
|
86
|
+
return 0;
|
|
87
|
+
default:
|
|
88
|
+
io.stderr("Unknown command.");
|
|
89
|
+
return 1;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function invalidArguments(io) {
|
|
93
|
+
io.stderr("Invalid command arguments.");
|
|
94
|
+
return 1;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Principal } from "./principal.js";
|
|
2
|
+
import type { CredentialAuthority } from "./credentials.js";
|
|
3
|
+
import { type StoreRuntime } from "./store.js";
|
|
4
|
+
export interface CoordinationRequest {
|
|
5
|
+
readonly method: string;
|
|
6
|
+
readonly path: string;
|
|
7
|
+
readonly principal: Principal;
|
|
8
|
+
readonly body?: unknown;
|
|
9
|
+
readonly cursor?: string;
|
|
10
|
+
readonly signal: AbortSignal;
|
|
11
|
+
}
|
|
12
|
+
export interface CoordinationResponse {
|
|
13
|
+
readonly status: number;
|
|
14
|
+
readonly body?: unknown;
|
|
15
|
+
readonly stream?: AsyncIterable<string>;
|
|
16
|
+
}
|
|
17
|
+
export declare class CoordinationApi {
|
|
18
|
+
#private;
|
|
19
|
+
constructor(runtime: StoreRuntime, authority: CredentialAuthority);
|
|
20
|
+
armReplayTransition(): {
|
|
21
|
+
readonly reached: Promise<void>;
|
|
22
|
+
readonly release: () => void;
|
|
23
|
+
};
|
|
24
|
+
handle(request: CoordinationRequest): Promise<CoordinationResponse>;
|
|
25
|
+
}
|