@inclavare-containers/tng 2.6.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 ADDED
@@ -0,0 +1,354 @@
1
+ # TNG Client JavaScript SDK
2
+
3
+ ## Description
4
+
5
+ The TNG Client JavaScript SDK provides client functionality for use in browser environments, built with wasm-pack.
6
+
7
+ ## Getting the SDK
8
+
9
+ You can obtain the TNG SDK in two ways:
10
+
11
+ ### 1. Download from GitHub Packages
12
+
13
+ Download the precompiled npm package directly from the GitHub Packages page:
14
+ [https://github.com/inclavare-containers/TNG/pkgs/npm/tng](https://github.com/inclavare-containers/TNG/pkgs/npm/tng)
15
+
16
+ ### 2. Build from Source
17
+
18
+ #### Docker Environment Preparation
19
+
20
+ ```sh
21
+ docker run -it --name tng-dev --privileged --network=host alibaba-cloud-linux-3-registry.cn-hangzhou.cr.aliyuncs.com/alinux3/alinux3:latest bash
22
+ ```
23
+
24
+ The above command will create a container named tng-dev based on the Alibaba Cloud Linux distribution, which will serve as the TNG development environment. We will continue the following steps in this container.
25
+
26
+ Install dependencies:
27
+
28
+ ```sh
29
+ yum install -y git make clang protobuf-devel npm
30
+ ```
31
+
32
+ #### Pull the Source Code
33
+
34
+ ```sh
35
+ cd /
36
+ git clone https://github.com/inclavare-containers/tng.git
37
+ cd tng
38
+ git submodule update --init
39
+ ```
40
+
41
+ Now you have the tng repository source code in the `/tng` directory.
42
+
43
+ #### Install the Rust Toolchain
44
+
45
+ ```sh
46
+ cat <<EOF >> ~/.bashrc
47
+ export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
48
+ export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup
49
+ EOF
50
+
51
+ . ~/.bashrc
52
+
53
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
54
+
55
+ mkdir -p ~/.cargo/
56
+ cat <<EOF > ~/.cargo/config.toml
57
+ [source.crates-io]
58
+ replace-with = 'ustc'
59
+
60
+ [source.ustc]
61
+ registry = "git://mirrors.ustc.edu.cn/crates.io-index"
62
+ EOF
63
+
64
+ . "$HOME/.cargo/env"
65
+ ```
66
+
67
+ #### Build the TNG SDK npm Package
68
+
69
+ ```sh
70
+ make wasm-pack-debug
71
+ ```
72
+
73
+ > [!NOTE]
74
+ > If you want to build the final production version, please use `make wasm-pack-release`
75
+
76
+ The resulting `tar.gz` file will be placed in the `./tng-wasm/pkg/` directory, which you can install into your web project using `npm install`.
77
+
78
+ ## Using the SDK in Your Project
79
+
80
+ ### Install the SDK to Your Project
81
+
82
+ ```bash
83
+ npm install tng-<version>.tgz
84
+ ```
85
+
86
+ ### Integrate the SDK in Your HTML
87
+
88
+ Add the following code to your HTML page to use the TNG SDK:
89
+
90
+ ```html
91
+ <!DOCTYPE html>
92
+ <html>
93
+ <head> </head>
94
+ <body>
95
+ <!-- Your page content -->
96
+
97
+ <script type="module">
98
+ import tng_init, { fetch as tng_fetch } from "tng_wasm.js";
99
+
100
+ // Initialize the TNG WASM module
101
+ await tng_init();
102
+
103
+ // Configure attestation parameters
104
+ const asAddr = "http://127.0.0.1:8080/";
105
+ const policyIds = ["default"];
106
+
107
+ // Create a wrapped fetch function
108
+ const attested_fetch = (input, init) => {
109
+ const tng_config = {
110
+ ohttp: {},
111
+ verify: {
112
+ model: "background_check",
113
+ as_type: "restful",
114
+ as_addr: asAddr,
115
+ policy_ids: policyIds,
116
+ },
117
+ };
118
+ return tng_fetch(input, init, tng_config);
119
+ };
120
+
121
+ // Send a request using the wrapped fetch function
122
+ attested_fetch("http://127.0.0.1:30001/foo/bar?baz=qux", {
123
+ method: "GET",
124
+ headers: {},
125
+ })
126
+ .then((response) => {
127
+ const attest_info = response?.attest_info
128
+ ? response.attest_info
129
+ : null;
130
+ console.log("Attest Info:", attest_info);
131
+ // Access remote attestation report information
132
+
133
+ console.log("Got response:", response);
134
+ // Process response
135
+ })
136
+ .catch((error) => {
137
+ console.error("Error:", error);
138
+ // Handle errors
139
+ });
140
+ </script>
141
+ </body>
142
+ </html>
143
+ ```
144
+
145
+ The main steps include:
146
+
147
+ 1. Add necessary security policy meta tags to the HTML header
148
+ 2. Import and initialize the TNG WASM module
149
+ 3. Configure the attestation service address and policy ID
150
+ 4. Use the wrapped `tng_fetch` function to send encrypted requests
151
+
152
+ ### Deployment Configuration
153
+
154
+ #### Using in Web Pages
155
+
156
+ Since the TNG SDK uses Web Workers, in production deployment, you need to add the `Cross-Origin-Opener-Policy:same-origin` and `Cross-Origin-Embedder-Policy:require-corp` HTTP headers to the web page's HTTP response, otherwise it will not work properly.
157
+
158
+ > [!NOTE]
159
+ > Since the `.wasm` file generated by the build is usually quite large, we recommend enabling gzip compression during deployment to reduce transfer size, which can reduce the volume by approximately 50%.
160
+
161
+ #### Using in Chrome Extensions
162
+
163
+ If you want to integrate in a Chrome extension, due to manifest v3 restrictions, you need to add some additional content to the manifest.
164
+
165
+ 1. Modify the `background` configuration item in the `manifest.json` file, setting the `type` configuration item to `"module"`.
166
+
167
+ ```json
168
+ "background": {
169
+ "service_worker": "background.js",
170
+ "type": "module"
171
+ }
172
+ ```
173
+
174
+ 2. Modify the `content_security_policy` configuration item in the `manifest.json` file to the following content:
175
+
176
+ ```json
177
+ "content_security_policy": {
178
+ "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
179
+ }
180
+ ```
181
+
182
+
183
+ ## Running the Example Code
184
+
185
+ The pkg directory contains an example program that uses the TNG SDK to send encrypted requests. The example requires a confidential computing server instance and a local computer. The following describes how to run the example.
186
+
187
+ ### 1. Prepare the Server-side Service
188
+
189
+ Use [dummyhttp](https://github.com/svenstaro/dummyhttp), a simple HTTP server program, to simulate our backend service. We need to install and run it.
190
+
191
+ Installation
192
+
193
+ ```sh
194
+ cargo install dummyhttp --locked
195
+ ```
196
+
197
+ Run this HTTP server and make it listen on port 30001. Now we have a backend HTTP service listening on port 30001.
198
+
199
+ ```sh
200
+ dummyhttp -p 30001 -vvvv
201
+ ```
202
+
203
+ > [!NOTE]
204
+ > You can use the curl command on the local computer to test direct access to this HTTP server to check network connectivity.
205
+
206
+ ### 2. Compile and Install TNG on the Server Side
207
+
208
+ Build the RPM package
209
+
210
+ ```sh
211
+ make create-tarball
212
+ make rpm-build
213
+ ```
214
+
215
+ The artifacts will be placed in `~/rpmbuild/RPMS/*/trusted-network-gateway-*.rpm`, which you can install as follows:
216
+
217
+ ```sh
218
+ yum install ~/rpmbuild/RPMS/*/trusted-network-gateway-*.rpm -y
219
+ ```
220
+
221
+ If you want to build the container version of TNG:
222
+
223
+ ```sh
224
+ # First install podman
225
+ yum install podman podman-docker -y
226
+ # Build the container image
227
+ docker build -t tng:test .
228
+ ```
229
+
230
+ This will produce a container image named `tng:test`.
231
+
232
+ ### 3. Run Attestation-Agent on the Server Side
233
+
234
+ You can choose to install attestation-agent from the yum repository or compile and deploy your own attestation-agent.
235
+
236
+ ```sh
237
+ yum install -y attestation-agent
238
+ ```
239
+
240
+ Run
241
+
242
+ ```sh
243
+ RUST_LOG=debug attestation-agent --attestation_sock unix:///run/confidential-containers/attestation-agent/attestation-agent.sock
244
+ ```
245
+
246
+ ### 4. Run TNG on the Server Side
247
+
248
+ ```sh
249
+ tng launch --config-content='
250
+ {
251
+ "add_egress": [
252
+ {
253
+ "netfilter": {
254
+ "capture_dst": {
255
+ "port": 30001
256
+ },
257
+ "capture_local_traffic": true
258
+ },
259
+ "ohttp": {},
260
+ "attest": {
261
+ "aa_addr": "unix:///run/confidential-containers/attestation-agent/attestation-agent.sock"
262
+ }
263
+ }
264
+ ]
265
+ }'
266
+ ```
267
+
268
+ > [!NOTE]
269
+ >
270
+ > - Currently, the TNG SDK only supports server-side verification, so you must provide the `"attest"` option
271
+ > - As shown above, you need to add an `"ohttp": {}` entry in the TNG configuration to enable using OHTTP as the encryption protocol (instead of rats-tls) for bidirectional encrypted traffic transmission.
272
+
273
+ ### 5. Run the Attestation Service Instance
274
+
275
+ You need to prepare an Attestation Service instance that exposes a RESTful HTTP interface. This can be achieved by installing the `trustee` package from the yum repository or compiling and deploying your own `restful-as`.
276
+
277
+ A reference run command is as follows:
278
+
279
+ ```sh
280
+ cat <<EOF > /tmp/config_with_cert.json
281
+ {
282
+ "work_dir": "/var/lib/attestation-service/",
283
+ "rvps_config": {
284
+ "type": "BuiltIn",
285
+ "storage": {
286
+ "type": "LocalFs"
287
+ }
288
+ },
289
+ "attestation_token_broker": {
290
+ "type": "Simple",
291
+ "duration_min": 5
292
+ }
293
+ }
294
+ EOF
295
+
296
+ RUST_LOG=debug restful-as --socket 0.0.0.0:9080 --config-file /tmp/config_with_cert.json
297
+
298
+ # Since restful-as natively does not support CORS configuration, here we run a CORS proxy service (https://github.com/bulletmark/corsproxy) that forwards requests from port 8080 to the real Attestation Service.
299
+ podman run -it --rm --net=host docker.io/bulletmark/corsproxy:latest 8080=http://127.0.0.1:9080
300
+ ```
301
+
302
+ The above will expose an Attestation Service on port 8080.
303
+
304
+ > [!NOTE]
305
+ > Since the TNG SDK needs to initiate requests to the Attestation Service instance in the browser, please ensure you handle the CORS rules properly.
306
+
307
+ Here is an example:
308
+
309
+ ### 6. Compile the TNG SDK
310
+
311
+ ```sh
312
+ make wasm-build-debug
313
+ ```
314
+
315
+ This will produce the corresponding `.wasm` and `.js` files in the `tng-wasm/pkg/` directory.
316
+
317
+ ### 7. Modify the Frontend Page Code
318
+
319
+ Please modify the following content in [index.html](pkg/index.html) as needed:
320
+
321
+ URL of the backend service to access:
322
+
323
+ ```js
324
+ const url = "http://127.0.0.1:30001/foo/bar?baz=qux";
325
+ ```
326
+
327
+ Attestation Service URL and policy ID for verification:
328
+
329
+ ```js
330
+ const asAddr = "http://127.0.0.1:8080/";
331
+ const policyIds = ["default"];
332
+ ```
333
+
334
+ ### 8. Run the Frontend Service on the Server Side
335
+
336
+ First install miniserve
337
+
338
+ ```sh
339
+ cargo +nightly-2025-07-07 install miniserve --locked
340
+ ```
341
+
342
+ Run miniserve
343
+
344
+ ```sh
345
+ miniserve ./tng-wasm/pkg --index index.html --header "Cross-Origin-Opener-Policy:same-origin" --header "Cross-Origin-Embedder-Policy:require-corp" --port 8082
346
+ ```
347
+
348
+ > [!NOTE]
349
+ >
350
+ > - [`miniserve`](https://github.com/svenstaro/miniserve) is a pure static resource server. It's no different from Nginx or Python's http.server, and you can use other components as alternatives.
351
+
352
+ ### 9. Access in the Browser
353
+
354
+ Open a browser on the local computer and visit `http://<confidential computing service instance ip>:8082/`. You can view the request response logs in F12.
package/package.json ADDED
@@ -0,0 +1,27 @@
1
+ {
2
+ "name": "@inclavare-containers/tng",
3
+ "type": "module",
4
+ "collaborators": [
5
+ "Kun Lai <laikun@linux.alibaba.com>"
6
+ ],
7
+ "version": "2.6.0",
8
+ "license": "Apache-2.0",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "https://github.com/inclavare-containers/tng"
12
+ },
13
+ "files": [
14
+ "tng_wasm_bg.wasm",
15
+ "tng_wasm.js",
16
+ "tng_wasm.d.ts"
17
+ ],
18
+ "main": "tng_wasm.js",
19
+ "types": "tng_wasm.d.ts",
20
+ "sideEffects": [
21
+ "./snippets/*"
22
+ ],
23
+ "publishConfig": {
24
+ "registry": "https://npm.pkg.github.com/",
25
+ "access": "public"
26
+ }
27
+ }
package/tng_wasm.d.ts ADDED
@@ -0,0 +1,111 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+ /**
4
+ * The `ReadableStreamType` enum.
5
+ *
6
+ * *This API requires the following crate features to be activated: `ReadableStreamType`*
7
+ */
8
+
9
+ type ReadableStreamType = "bytes";
10
+
11
+ export class IntoUnderlyingByteSource {
12
+ private constructor();
13
+ free(): void;
14
+ [Symbol.dispose](): void;
15
+ cancel(): void;
16
+ pull(controller: ReadableByteStreamController): Promise<any>;
17
+ start(controller: ReadableByteStreamController): void;
18
+ readonly autoAllocateChunkSize: number;
19
+ readonly type: ReadableStreamType;
20
+ }
21
+
22
+ export class IntoUnderlyingSink {
23
+ private constructor();
24
+ free(): void;
25
+ [Symbol.dispose](): void;
26
+ abort(reason: any): Promise<any>;
27
+ close(): Promise<any>;
28
+ write(chunk: any): Promise<any>;
29
+ }
30
+
31
+ export class IntoUnderlyingSource {
32
+ private constructor();
33
+ free(): void;
34
+ [Symbol.dispose](): void;
35
+ cancel(): void;
36
+ pull(controller: ReadableStreamDefaultController): Promise<any>;
37
+ }
38
+
39
+ declare function fetch2(url: string, init: any, config: any): Promise<Response>;
40
+ export { fetch2 as fetch }
41
+
42
+ export function init_tng(): void;
43
+
44
+ /**
45
+ * Entry point invoked by JavaScript in a worker.
46
+ */
47
+ export function task_worker_entry_point(ptr: number): void;
48
+
49
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
50
+
51
+ export interface InitOutput {
52
+ readonly fetch: (a: number, b: number, c: any, d: any) => any;
53
+ readonly init_tng: () => void;
54
+ readonly task_worker_entry_point: (a: number) => [number, number];
55
+ readonly ring_core_0_17_11__bn_mul_mont: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
56
+ readonly __wbg_intounderlyingsink_free: (a: number, b: number) => void;
57
+ readonly intounderlyingsink_write: (a: number, b: any) => any;
58
+ readonly intounderlyingsink_close: (a: number) => any;
59
+ readonly intounderlyingsink_abort: (a: number, b: any) => any;
60
+ readonly __wbg_intounderlyingbytesource_free: (a: number, b: number) => void;
61
+ readonly intounderlyingbytesource_type: (a: number) => number;
62
+ readonly intounderlyingbytesource_autoAllocateChunkSize: (a: number) => number;
63
+ readonly intounderlyingbytesource_start: (a: number, b: any) => void;
64
+ readonly intounderlyingbytesource_pull: (a: number, b: any) => any;
65
+ readonly intounderlyingbytesource_cancel: (a: number) => void;
66
+ readonly __wbg_intounderlyingsource_free: (a: number, b: number) => void;
67
+ readonly intounderlyingsource_pull: (a: number, b: any) => any;
68
+ readonly intounderlyingsource_cancel: (a: number) => void;
69
+ readonly wasm_bindgen__closure__destroy__h608d62b8eccc8f6e: (a: number, b: number) => void;
70
+ readonly wasm_bindgen__closure__destroy__hbb5960641dfaf99a: (a: number, b: number) => void;
71
+ readonly wasm_bindgen__closure__destroy__h2925d4d1c19a6d50: (a: number, b: number) => void;
72
+ readonly wasm_bindgen__convert__closures_____invoke__h38253c4a1aa54e27: (a: number, b: number, c: any) => [number, number];
73
+ readonly wasm_bindgen__convert__closures_____invoke__h4e91db2f1b7350bd: (a: number, b: number, c: any, d: any) => void;
74
+ readonly wasm_bindgen__convert__closures_____invoke__hdfdaa0711fe9a60e: (a: number, b: number, c: any) => void;
75
+ readonly wasm_bindgen__convert__closures_____invoke__hfa390009d5ba6f84: (a: number, b: number, c: any) => void;
76
+ readonly wasm_bindgen__convert__closures_____invoke__h7938576e03ec4167: (a: number, b: number) => void;
77
+ readonly memory: WebAssembly.Memory;
78
+ readonly __wbindgen_malloc: (a: number, b: number) => number;
79
+ readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
80
+ readonly __wbindgen_exn_store: (a: number) => void;
81
+ readonly __externref_table_alloc: () => number;
82
+ readonly __wbindgen_externrefs: WebAssembly.Table;
83
+ readonly __wbindgen_free: (a: number, b: number, c: number) => void;
84
+ readonly __externref_table_dealloc: (a: number) => void;
85
+ readonly __wbindgen_thread_destroy: (a?: number, b?: number, c?: number) => void;
86
+ readonly __wbindgen_start: (a: number) => void;
87
+ }
88
+
89
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
90
+
91
+ /**
92
+ * Instantiates the given `module`, which can either be bytes or
93
+ * a precompiled `WebAssembly.Module`.
94
+ *
95
+ * @param {{ module: SyncInitInput, memory?: WebAssembly.Memory, thread_stack_size?: number }} module - Passing `SyncInitInput` directly is deprecated.
96
+ * @param {WebAssembly.Memory} memory - Deprecated.
97
+ *
98
+ * @returns {InitOutput}
99
+ */
100
+ export function initSync(module: { module: SyncInitInput, memory?: WebAssembly.Memory, thread_stack_size?: number } | SyncInitInput, memory?: WebAssembly.Memory): InitOutput;
101
+
102
+ /**
103
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
104
+ * for everything else, calls `WebAssembly.instantiate` directly.
105
+ *
106
+ * @param {{ module_or_path: InitInput | Promise<InitInput>, memory?: WebAssembly.Memory, thread_stack_size?: number }} module_or_path - Passing `InitInput` directly is deprecated.
107
+ * @param {WebAssembly.Memory} memory - Deprecated.
108
+ *
109
+ * @returns {Promise<InitOutput>}
110
+ */
111
+ export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput>, memory?: WebAssembly.Memory, thread_stack_size?: number } | InitInput | Promise<InitInput>, memory?: WebAssembly.Memory): Promise<InitOutput>;