Skip to content

Commit 52f882e

Browse files
committed
feat: transfer and adapt come lavamoat-node docs, fill in runtime page, minor edits to index
1 parent 65d45ae commit 52f882e

File tree

6 files changed

+454
-6
lines changed

6 files changed

+454
-6
lines changed

src/content/docs/about/runtime-environment.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,51 @@ sidebar:
55
order: 3
66
---
77

8-
Not gonna ask ChatGPT to write this
8+
## Runtime protections
9+
10+
You can use lavamoat to prevent malicious code introduced into a package from running.
11+
12+
The LavaMoat runtime reduces the supply chain risk by:
13+
14+
1. Preventing modification of JavaScript's built-in data types (`Object`, `String`, `Number`, `Array`, etc.)
15+
2. Providing granular control over access to the global platform API (`document`, `process`, `WebSocket`, etc.)
16+
17+
18+
Both are provided by [SES][SesGithub] containers. Platform API access is granted by a policy file that LavaMoat can generate and allow the project to selectively customize. All details of policy file structure are documented in the [Policy file explained][PolicyDoc] doc.
19+
20+
#### Hardened Javascript (SES)
21+
22+
[SES][SesGithub] is the sandbox used in LavaMoat. See SES's [secure computing guide][SesComputingGuide] to learn more about the risks of untrusted javascript.
23+
24+
SES provides `Compartment` and `lockdown` which LavaMoat uses to provide two distinct protections:
25+
26+
- `lockdown` hardens the runtime environment, preventing the JavaScript intrinsics from being tampered with. It therefore stops prototype poisoning attacks from affecting the security of `Compartment` and the rest of the application
27+
- `Compartment` is used internally to allow isolating each dependency and awarding it access to only the globals and imports allowed by the policy.
28+
29+
#### Scuttling
30+
31+
Since LavaMoat is selectively giving copies of global references to confined parts of the application, there no longer is a need for the actual global references to exist.
32+
33+
We apply a step we call "Scuttling" early on in the initialization of the app to destroy all the global references we can possibly destroy after we've captured them. So even if the app code accidentally gives a dependency some powers that lead to it reaching the globalThis - there's not much left there to use.
34+
35+
### LavaMoat runtime protection in Node.js
36+
37+
Run your server or app building code with protections via [LavaMoat Node][lavamoat-node]
38+
39+
TODO: mention endomoat maybe
40+
41+
### LavaMoat runtime protection in the browser
42+
43+
LavaMoat is designed to work in the browser in tandem with a strict Content Security Policy. As a result, the confinement provided by Compartments is not created at runtime, but inserted into the JavaScript bundle at build time, thus avoiding the use of `eval` or `new Function` which are prohibited under CSP.
44+
45+
As a result, to secure your code in the browser, you need to use one of the supported bundlers.
46+
47+
[LavaMoat plugin for Webpack5][lavamoat-webpack] (beta)
48+
49+
[LavaMoat for Browserify][lavamoat-browserify]
50+
51+
52+
53+
[lavamoat-node] /guides/lavamoat-node
54+
[lavamoat-browserify] /guides/browserify
55+
[lavamoat-webpack] /guides/webpack

src/content/docs/guide/allow-scripts.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ description: 'A user guide for @lavamoat/allow-scripts'
1111
- One of the following package managers:
1212
- [npm](https://www.npmjs.com/) v8.0.0+
1313
- [Yarn](https://yarnpkg.com/) v1.22.0+
14+
- [Yarn Berry](https://yarnpkg.com/) v3 or above
1415

1516
## Install
1617

src/content/docs/guide/getting-started.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,21 @@ LavaMoat is distributed as a [Node.js](https://nodejs.org) command-line tool. Yo
1717
Don't have Node.js installed? [Download and install Node.js from the official site.](https://nodejs.org/en/download)
1818

1919
:::
20+
21+
22+
## How to secure your app against supply-chain attacks
23+
24+
1. Control dependency lifecycle scripts (eg. "postinstall") via [@lavamoat/allow-scripts][lavamoat-allowscripts]
25+
2. run your server or build process in [lavamoat-node][lavamoat-node]
26+
3. build your ui with our [Webpack5 plugin (beta)][lavamoat-webpack] or use LavaMoat for [Browserify][lavamoat-browserify]
27+
28+
:::tip
29+
30+
Even starting with adding just step 1 - the `allow-scripts`, is a great improvement to your supply chain security. Majority of supply-chain attacks are delivered via lifecycle scripts.
31+
32+
:::
33+
34+
[lavamoat-allowscripts] /guides/allow-scripts
35+
[lavamoat-node] /guides/lavamoat-node
36+
[lavamoat-browserify] /guides/browserify
37+
[lavamoat-webpack] /guides/webpack
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
---
2+
title: "User's Guide: lavamoat node runtime"
3+
description: 'A user guide for running LavaMoat-protected NodeJS applications'
4+
---
5+
6+
`lavamoat` is a Node.js runtime where modules are defined in [SES][ses-github-ext] Compartments. It aims to reduce the risk of malicious code in the app dependency graph, known as "software supply chain attacks".
7+
8+
:::caution
9+
10+
This runtime does not support ESM modules. A new runtime that's ESM-first is a work in progress.
11+
12+
:::
13+
14+
## LavaMoat Runtime
15+
16+
LavaMoat differs from the standard node runtime in that it:
17+
18+
1. Uses `lockdown()` from [SES][ses-github-ext] to prevent tampering with the execution environment.
19+
Thanks to lockdown, prototype-pollution attacks are neutralized. It's also a prerequisite to code isolation.
20+
2. Uses SES Compartments to isolate each package's execution.
21+
Packages don't share references to anything unless explicitly passed in or allowed by policy. Custom `require` and linking implementation is provided for the purpose of loading allowed dependencies.
22+
3. Enforces the app-specified LavaMoat policy.
23+
The policy specifies what execution environment each package should run with, which means: what global/built-in APIs should it be exposed to, and what other packages can it require.
24+
25+
The result is a runtime that should work just as before, but provides some protection against supply chain attacks.
26+
27+
## Install
28+
29+
:::tip[Protect your installation]
30+
Before you use lavamoat runtime protections, make sure you've set up allow-scripts and install dependencies using that setup.
31+
:::
32+
33+
Use one of:
34+
35+
```
36+
npm i lavamoat
37+
yarn add lavamoat
38+
```
39+
40+
## Usage
41+
42+
### Recommended usage
43+
44+
1. Install
45+
2. Run your application once with `lavamoat app.js --autopolicy`
46+
3. Inspect the `./lavamoat/node/policy.json` file it generated
47+
4. Run your application with `lavamoat app.js`
48+
5. If you find you need to change the policy in step 2 or 3 create a `./lavamoat/node/policy-override.json` file and introduce changes there. You can both expand and trim the permissions.
49+
50+
For more information on the lavamoat policy file, check [Policy file explained][policy-file] in documentation.
51+
52+
:::tip[Policy maintenance]
53+
54+
You can regenerate the main policy file on updates (and review for unexpected new permissions) while the modifications you needed to make remain in a separate overrides file. It makes reviewing and maintaining both files easier.
55+
56+
:::
57+
58+
### All options
59+
60+
```
61+
lavamoat <entryPath> [Options]
62+
63+
Positionals:
64+
entryPath the path to the entry file for your application. same as node.js
65+
[string]
66+
67+
Options:
68+
--version Show version number [boolean]
69+
--help Show help [boolean]
70+
-p, --policy, --policyPath Pass in policy. Accepts a filepath
71+
string to the existing policy. When
72+
used in conjunction with
73+
--autopolicy, specifies where to
74+
write the policy. Default:
75+
./lavamoat/node/policy.json
76+
[string] [default: "lavamoat/node/policy.json"]
77+
-o, --policyOverride, --override, Pass in override policy. Accepts a
78+
--policyOverridePath filepath string to the existing
79+
override policy. Default:
80+
./lavamoat/node/policy-override.json
81+
[string] [default: "lavamoat/node/policy-override.json"]
82+
--policyDebug, --pd, --policydebug, Pass in debug policy. Accepts a
83+
--policyDebugPath filepath string to the existing
84+
debug policy. Default:
85+
./lavamoat/node/policy-debug.json
86+
[string] [default: "lavamoat/node/policy-debug.json"]
87+
-a, --writeAutoPolicy, --autopolicy Generate a "policy.json" and
88+
"policy-override.json" in the
89+
current working directory.
90+
Overwrites any existing policy
91+
files. The override policy is for
92+
making manual policy changes and
93+
always takes precedence over the
94+
automatically generated policy.
95+
[boolean] [default: false]
96+
--writeAutoPolicyAndRun, --ar, parse + generate a LavaMoat policy
97+
--autorun file then execute with the new
98+
policy. [boolean] [default: false]
99+
--writeAutoPolicyDebug, --dp, when writeAutoPolicy is enabled,
100+
--debugpolicy write policy debug info to specified
101+
or default path
102+
[boolean] [default: false]
103+
--projectRoot specify the director from where
104+
packages should be resolved
105+
[string] [default: "/home/naugtur/work/metamask/metamask-extension"]
106+
-d, --debugMode, --debug Disable some protections and extra
107+
logging for easier debugging.
108+
[boolean] [default: false]
109+
--statsMode, --stats enable writing and logging of stats
110+
[boolean] [default: false]
111+
112+
```
113+
114+
## Examples
115+
116+
### Run with Policy in default location
117+
118+
This uses the existing policy and policy-override files to run your app.
119+
120+
```bash
121+
lavamoat index.js
122+
```
123+
124+
Automatically searches for policy files inside `./lavamoat/node/`.
125+
126+
### Policy Override with Relative Path
127+
128+
This uses the override policy specified at `./policies/policy-override.json`.
129+
130+
```
131+
$ lavamoat index.js --override './policies/policy-override.json'
132+
```
133+
134+
## Troubleshooting
135+
136+
- Having trouble reading thrown Errors? try running with the `--debugMode` flag. **Warning:** not safe for production runs.
137+
138+
- Got a dependency that wont quite work under LavaMoat? try [patch-package](https://www.npmjs.com/package/patch-package)
139+
140+
For more details go to the [troubleshooting section][troubleshooting]
141+
142+
## Programmatic usage
143+
144+
Programmatic usage is almost identical to the commandline and its arguments.
145+
146+
```js
147+
const { runLava } = require('lavamoat')
148+
149+
runLava({
150+
entryPath: './app.js',
151+
// Optional:
152+
writeAutoPolicy: false,
153+
writeAutoPolicyDebug: false,
154+
writeAutoPolicyAndRun: false,
155+
policyPath: 'path to file',
156+
policyDebugPath: 'path to file',
157+
policyOverridePath: 'path to file',
158+
projectRoot: process.cwd(),
159+
debugMode: false,
160+
statsMode: false,
161+
})
162+
```
163+
164+
[ses-github-ext]: https://github.com/endojs/endo/tree/master/packages/ses
165+
[policy-file]: ./policy
166+
[troubleshooting]: ./troubleshooting

0 commit comments

Comments
 (0)