Skip to content

Commit 4b7006d

Browse files
Merge branch 'main' into node-page-updates
2 parents 2430a84 + fe23ef3 commit 4b7006d

File tree

3 files changed

+107
-65
lines changed

3 files changed

+107
-65
lines changed

_includes/doc.tsx

Lines changed: 39 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2,64 +2,54 @@ import renderCommand from "./renderCommand.tsx";
22

33
export const layout = "layout.tsx";
44

5-
export const ogImage = (data: Lume.Data) => {
6-
return data.url + "/index.png";
7-
};
5+
export const ogImage = (data: Lume.Data) => `${data.url}/index.png`;
86

97
export default function Doc(data: Lume.Data, helpers: Lume.Helpers) {
10-
let file = data.page.sourcePath;
11-
const sidebar = data.sidebar;
12-
let renderedCommand = null;
13-
14-
if (data.command) {
15-
const { rendered, toc } = renderCommand(data.command, helpers);
16-
renderedCommand = rendered;
17-
data.toc = toc.concat(...data.toc);
18-
}
19-
8+
// Flags and simple derivations
9+
const API_LANDING = new Set(["/api/deno/", "/api/web/", "/api/node/"]);
2010
const isReference = data.url.startsWith("/api/");
21-
const isApiLandingPage = ["/api/deno/", "/api/web/", "/api/node/"].includes(
22-
data.url,
11+
const isApiLandingPage = API_LANDING.has(data.url);
12+
const isExampleScript = Boolean(
13+
(data.page.data.content as { type?: string })?.type,
2314
);
24-
const isExamples = data.url.startsWith("/examples/");
25-
const isExampleScript = (data.page.data.content as { type?: string })?.type;
2615
const isLintRule = data.url.startsWith("/lint/rules/");
27-
const isHome = data.url === "/";
2816

29-
const hasBreadcrumbs = !isExamples && !isHome &&
30-
!(isReference && !isApiLandingPage);
17+
// Compute file path used by Feedback component
18+
const file = isLintRule
19+
? `/lint/rules/${encodeURIComponent(data.title ?? "")}.md`
20+
: data.page.sourcePath;
3121

32-
if (isLintRule) {
33-
file = `/lint/rules/${encodeURIComponent(data.title ?? "")}.md`;
22+
// Render command block and merge its TOC if present
23+
let renderedCommand: unknown = null;
24+
if (data.command) {
25+
const { rendered, toc } = renderCommand(data.command, helpers);
26+
renderedCommand = rendered;
27+
data.toc = toc.concat(...data.toc);
3428
}
3529

3630
function getTocCtx(
37-
d: Lume.Data,
31+
d: unknown,
3832
): { document_navigation: unknown; document_navigation_str: string } | null {
39-
const ch: unknown = (d as unknown as { children?: unknown })?.children;
40-
if (ch && typeof ch === "object" && "props" in ch) {
41-
const props: unknown = (ch as { props?: unknown }).props;
42-
if (props && typeof props === "object" && "data" in props) {
43-
const pdata: unknown = (props as { data?: unknown }).data;
44-
if (pdata && typeof pdata === "object" && "toc_ctx" in pdata) {
45-
const toc: unknown = (pdata as { toc_ctx?: unknown }).toc_ctx;
46-
if (
47-
toc && typeof toc === "object" &&
48-
"document_navigation" in toc &&
49-
"document_navigation_str" in toc
50-
) {
51-
const t = toc as {
52-
document_navigation: unknown;
53-
document_navigation_str: string;
54-
};
55-
return t;
56-
}
57-
}
58-
}
33+
type Toc = {
34+
document_navigation: unknown;
35+
document_navigation_str: string;
36+
};
37+
const tocCtx: unknown = (d as {
38+
children?: { props?: { data?: { toc_ctx?: unknown } } };
39+
})?.children?.props?.data?.toc_ctx;
40+
if (
41+
tocCtx &&
42+
typeof tocCtx === "object" &&
43+
"document_navigation" in tocCtx &&
44+
"document_navigation_str" in tocCtx
45+
) {
46+
return tocCtx as Toc;
5947
}
6048
return null;
6149
}
6250

51+
const tocCtx = getTocCtx(data);
52+
6353
return (
6454
<>
6555
<main
@@ -107,17 +97,12 @@ export default function Doc(data: Lume.Data, helpers: Lume.Helpers) {
10797
<data.comp.Feedback file={file} />
10898
</div>
10999
</main>
110-
{(() => {
111-
const tocCtx = getTocCtx(data);
112-
return isReference && tocCtx
113-
? (
114-
<data.comp.RefToc
115-
documentNavigation={tocCtx.document_navigation}
116-
documentNavigationStr={tocCtx.document_navigation_str}
117-
/>
118-
)
119-
: null;
120-
})()}
100+
{isReference && tocCtx && (
101+
<data.comp.RefToc
102+
documentNavigation={tocCtx.document_navigation}
103+
documentNavigationStr={tocCtx.document_navigation_str}
104+
/>
105+
)}
121106
</>
122107
);
123108
}

deploy/classic/api/runtime-node.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ const server = createServer((req, res) => {
3232
server.listen(8080);
3333
```
3434

35-
_You can see this example live here:
36-
https://dash.deno.com/playground/node-specifiers_
37-
3835
When using `node:` specifiers, all other features of Deno Deploy Classic are
3936
still available. For example, you can use `Deno.env` to access environment
4037
variables even when using Node.js modules. You can also import other ESM modules

runtime/fundamentals/security.md

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ format, where each line is an object with the following keys:
106106
- `value`: the value that the permission was accessed with, or `null` if it was
107107
accessed with no value
108108

109-
A schema for this can be found
110-
[here](https://github.com/denoland/deno/blob/main/cli/schemas/permission-audit.v1.json).
109+
A schema for this can be found in
110+
[permission-audit.v1.json](https://github.com/denoland/deno/blob/main/cli/schemas/permission-audit.v1.json).
111111

112112
In addition, this env var can be combined with the above-mentioned
113113
`DENO_TRACE_PERMISSIONS`, which then adds a new `stack` field to the entries
@@ -458,11 +458,11 @@ code from. This is true for both static and dynamic imports.
458458

459459
If you want to dynamically import code, either using the `import()` or the
460460
`new Worker()` APIs, additional permissions need to be granted. Importing from
461-
the local file system [requires `--allow-read`](#file-system-read-access), but
462-
Deno also allows to import from `http:` and `https:` URLs. In such case you will
463-
need to specify an explicit `--allow-import` flag:
461+
the local file system [requires `--allow-read`](#file-system-access), but Deno
462+
also allows to import from `http:` and `https:` URLs. In such case you will need
463+
to specify an explicit `--allow-import` flag:
464464

465-
```
465+
```sh
466466
# allow importing code from `https://example.com`
467467
$ deno run --allow-import=example.com main.ts
468468
```
@@ -476,12 +476,12 @@ By default Deno allows importing sources from following hosts:
476476
- `raw.githubusercontent.com`
477477
- `gist.githubusercontent.com`
478478

479-
**Imports are only allowed using HTTPS**
479+
Imports are only allowed using HTTPS.
480480

481481
This allow list is applied by default for static imports, and by default to
482482
dynamic imports if the `--allow-import` flag is specified.
483483

484-
```
484+
```sh
485485
# allow dynamically importing code from `https://deno.land`
486486
$ deno run --allow-import main.ts
487487
```
@@ -515,3 +515,63 @@ using all of these when executing arbitrary untrusted code:
515515
- Use OS provided sandboxing mechanisms like `chroot`, `cgroups`, `seccomp`,
516516
etc.
517517
- Use a sandboxed environment like a VM or MicroVM (gVisor, Firecracker, etc).
518+
519+
## Permission broker
520+
521+
For centralized and policy-driven permission decisions, Deno can delegate all
522+
permission checks to an external broker process. Enable this by setting the
523+
`DENO_PERMISSION_BROKER_PATH` environment variable to a path that Deno will use
524+
to connect to the broker:
525+
526+
- On Unix-like systems: a Unix domain socket path (for example,
527+
`/tmp/deno-perm.sock`).
528+
- On Windows: a named pipe (for example, `\\.\pipe\deno-perm-broker`).
529+
530+
When a permission broker is active:
531+
532+
- All `--allow-*` and `--deny-*` flags are ignored.
533+
- Interactive permission prompts are not shown (equivalent to non-interactive
534+
mode).
535+
- Every permission check is sent to the broker; the broker must reply with a
536+
decision for each request.
537+
538+
If anything goes wrong during brokering (for example: Deno cannot connect to the
539+
socket/pipe, messages are malformed, arrive out of order, IDs do not match, or
540+
the connection closes unexpectedly), Deno immediately terminates the process to
541+
preserve integrity and prevent permission escalation.
542+
543+
The request/response message shapes are versioned and defined by JSON Schemas:
544+
545+
- Request schema:
546+
[permission-broker-request.v1.json](https://github.com/denoland/deno/blob/main/cli/schemas/permission-broker-request.v1.json)
547+
- Response schema:
548+
[permission-broker-response.v1.json](https://github.com/denoland/deno/blob/main/cli/schemas/permission-broker-response.v1.json)
549+
550+
Each request contains a version (`v`), the Deno process ID (`pid`), a unique
551+
monotonic request `id`, a timestamp (`datetime`, RFC 3339), the `permission`
552+
name, and an optional `value` depending on permission type. The response must
553+
echo the `id` and include a `result` of either `"grant"` or `"deny"`. When
554+
denied, a human-readable `reason` may be included.
555+
556+
Example message flow:
557+
558+
```text
559+
-> req {"v":1,"pid":10234,"id":1,"datetime":"2025-01-01T00:00:00.000Z","permission":"read","value":"./run/permission_broker/scratch.txt"}
560+
<- res {"id":1,"result":"grant"}
561+
-> req {"v":1,"pid":10234,"id":2,"datetime":"2025-01-01T00:00:01.000Z","permission":"read","value":"./run/permission_broker/scratch.txt"}
562+
<- res {"id":2,"result":"grant"}
563+
-> req {"v":1,"pid":10234,"id":3,"datetime":"2025-01-01T00:00:02.000Z","permission":"read","value":"./run/permission_broker/log.txt"}
564+
<- res {"id":3,"result":"grant"}
565+
-> req {"v":1,"pid":10234,"id":4,"datetime":"2025-01-01T00:00:03.000Z","permission":"write","value":"./run/permission_broker/log.txt"}
566+
<- res {"id":4,"result":"grant"}
567+
-> req {"v":1,"pid":10234,"id":5,"datetime":"2025-01-01T00:00:04.000Z","permission":"env","value":null}
568+
<- res {"id":5,"result":"deny","reason":"Environment access is denied."}
569+
```
570+
571+
:::caution Advanced use only
572+
573+
Using a permission broker changes Deno’s decision authority: CLI flags and
574+
prompts no longer apply. Ensure your broker process is resilient, audited, and
575+
available before enabling `DENO_PERMISSION_BROKER_PATH`.
576+
577+
:::

0 commit comments

Comments
 (0)