You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(auth): allow non-admin user role to use HTTP sink/IO nodes (#634)
* feat(auth): allow non-admin user role to use HTTP sink/IO nodes
The built-in user role excluded transport::http::* entirely and all
streamkit::* nodes, forcing HTTP-transport gateways to run with an admin
token. Allow the safe sink/IO nodes (transport::http::mse,
streamkit::http_input, streamkit::http_output) while keeping
transport::http::fetcher denied (SSRF risk), and document a
least-privilege gateway role.
Closes#632
Signed-off-by: streamkit-devin <devin@streamkit.dev>
* docs(auth): align sample skit.toml with safe HTTP node defaults
Tighten the sample user role to deny transport::http::fetcher (was
allowed via the transport::* wildcard) and add a least-privilege
gateway role example.
Signed-off-by: streamkit-devin <devin@streamkit.dev>
* fix(auth): align sample user role with built-in secure default
Mirror Permissions::user() in samples/skit.toml: drop blanket core::*
(which exposed core::file_writer) for the safe core subset, add video::*
and plugin usage, keeping transport::http::fetcher denied. Extend the
sample config test to assert the user/gateway node allowlists.
Signed-off-by: streamkit-devin <devin@streamkit.dev>
* fix(auth): tighten gateway role core nodes and align user samples
Drop core::* from the gateway example (it exposed core::file_writer,
contradicting the least-privilege intent) for the safe core plumbing
subset, and remove demo/* from the sample user role's allowed_samples
to match the built-in Permissions::user().
Signed-off-by: streamkit-devin <devin@streamkit.dev>
* fix(auth): make gateway role usable and align user role with built-in
The gateway example could never run its own pipeline: is_node_allowed()
runs before the plugin check, so plugin::native::servo (absent from
allowed_nodes) was rejected, and the role lacked the video/containers nodes
the servo->encode->mux->serve pipeline needs. Grant exactly those kinds.
Also align the sample user role with Permissions::user(): add the
list/read/write/delete_samples flags (without which allowed_samples is
unreachable) and core::param_bridge (a safe in-graph node). Drop the
streamkit::http_input/http_output allowlist entries from both the built-in
and sample roles - they are oneshot-only markers never gated by
is_node_allowed, so listing them was dead config.
Signed-off-by: streamkit-devin <devin@streamkit.dev>
* docs(auth): note audio encoder needed for gateway audio capture
The documented gateway role serves a video-only WebM cast. Page audio
would also need audio::opus::encoder in allowed_nodes, since the mse node
advertises codecs="vp9,opus". Noted as a future extension.
Signed-off-by: streamkit-devin <devin@streamkit.dev>
* fix(auth): mirror built-in user asset policy in sample config
The sample user role's allowed_assets only listed audio, while
Permissions::user() also grants image and font assets. Add the image/font
patterns so the sample matches the built-in default the comments claim to
mirror, and assert the asset policy in sample_config_test.
Signed-off-by: streamkit-devin <devin@streamkit.dev>
* docs(auth): scope gateway role comment to web-capture example
The comment claimed the role serves the speech-gateway too, but the
node/plugin lists only cover web-capture. Clarify that the lists are
web-capture-scoped and other gateways swap in their own nodes/plugins.
Signed-off-by: streamkit-devin <devin@streamkit.dev>
---------
Signed-off-by: streamkit-devin <devin@streamkit.dev>
Co-authored-by: streamkit-devin <devin@streamkit.dev>
Copy file name to clipboardExpand all lines: docs/src/content/docs/guides/authorization.md
+41Lines changed: 41 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -109,6 +109,47 @@ allowed_assets = ["*"]
109
109
> [!NOTE]
110
110
> Role permissions are deny-by-default. If you define a custom role in `skit.toml`, any permission you omit defaults to `false`.
111
111
112
+
> [!NOTE]
113
+
> The built-in `user` role allows `transport::http::mse` (live-cast playback over the caller's own request) but **not**`transport::http::fetcher`, which can fetch arbitrary URLs (SSRF risk). The oneshot `streamkit::http_input` / `streamkit::http_output` markers are always permitted on the oneshot path regardless of `allowed_nodes`, so they need no allowlist entry. A trusted gateway that only serves or receives over the caller's own request therefore does not need `admin`.
114
+
115
+
## Example: Least-privilege gateway role
116
+
117
+
Trusted intermediaries (e.g. the `web-capture` or `speech-gateway` examples) build a small set of fixed pipelines and should run with a scoped token instead of `admin`. The role below grants exactly the node kinds the web-capture pipeline (`servo → encode → mux → serve`) needs and nothing more.
118
+
119
+
> [!IMPORTANT]
120
+
> A plugin must appear in **both**`allowed_nodes` and `allowed_plugins`. Enforcement calls `is_node_allowed(kind)`*before* the plugin check, so a plugin kind missing from `allowed_nodes` is rejected before `allowed_plugins` is ever consulted.
121
+
122
+
```toml
123
+
[permissions.roles.gateway]
124
+
create_sessions = true
125
+
destroy_sessions = true
126
+
modify_sessions = true
127
+
tune_nodes = true
128
+
list_sessions = true
129
+
list_nodes = true
130
+
access_all_sessions = false# Only its own sessions
131
+
load_plugins = false
132
+
delete_plugins = false
133
+
upload_assets = false
134
+
delete_assets = false
135
+
allowed_nodes = [
136
+
"plugin::native::servo", # render the page (web-capture)
137
+
"video::pixel_convert", # servo RGBA -> encoder input format
138
+
"video::vp9::encoder", # encode to VP9
139
+
"containers::webm::muxer", # mux into WebM for MSE / http_output
140
+
"transport::http::mse", # serve the live cast to the browser (MSE)
141
+
"core::pacer",
142
+
"core::sink",
143
+
# No core::file_writer (arbitrary-write risk) and no transport::http::fetcher (SSRF).
144
+
# The oneshot streamkit::http_output marker is implicitly allowed.
145
+
]
146
+
allowed_plugins = ["plugin::native::servo"] # must also be listed in allowed_nodes (see note above)
147
+
```
148
+
149
+
This role serves a **video-only** WebM cast. To also carry page audio (the `mse`
150
+
node advertises `codecs="vp9,opus"`), add the audio encoder — e.g.
0 commit comments