Skip to content

Commit 815e4ae

Browse files
committed
feat: implement built-in auth
1 parent bf3e099 commit 815e4ae

File tree

96 files changed

+7496
-247
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+7496
-247
lines changed

.github/workflows/e2e.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ jobs:
6565
working-directory: ./e2e
6666
run: bun run test
6767

68+
- name: Run E2E tests (auth enabled)
69+
working-directory: ./e2e
70+
run: E2E_AUTH=1 bun run test
71+
6872
- name: Upload Playwright report
6973
uses: actions/upload-artifact@v4
7074
if: failure()

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ samples/pipelines/user
5050
samples/audio/user/*
5151
!samples/audio/user/.gitkeep
5252

53+
# StreamKit runtime state (keys/tokens/config caches)
54+
.streamkit
55+
5356
# Audio samples - only keep opus/ogg formats
5457
samples/audio/system/*.wav
5558
samples/audio/system/*.flac

Cargo.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

DOCKER.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,30 @@ This guide covers building and running StreamKit Docker images. The official “
2626
```bash
2727
docker build -f Dockerfile.demo -t streamkit:demo .
2828

29-
docker run \
29+
docker run --rm --name streamkit-demo \
3030
-p 127.0.0.1:4545:4545/tcp \
3131
-p 127.0.0.1:4545:4545/udp \
3232
streamkit:demo
3333
```
3434

35+
> [!NOTE]
36+
> The demo image binds to `0.0.0.0:4545` inside the container so published ports work. With `auth.mode=auto`, built-in auth is enabled by default.
37+
> To log in, print the bootstrap admin token and paste it into `http://localhost:4545/login`:
38+
>
39+
> ```bash
40+
> docker exec streamkit-demo skit auth print-admin-token --raw
41+
> ```
42+
43+
> [!NOTE]
44+
> Linux-only (no login): run with host networking and bind to loopback inside the container to keep auth disabled in `auth.mode=auto`:
45+
>
46+
> ```bash
47+
> docker run --rm --name streamkit-demo \
48+
> --network host \
49+
> -e SK_SERVER__ADDRESS=127.0.0.1:4545 \
50+
> streamkit:demo
51+
> ```
52+
3553
If you want the OpenAI-powered sample pipelines, pass `OPENAI_API_KEY` without putting it directly in the command:
3654
3755
```bash
@@ -106,6 +124,28 @@ docker run --rm -d --name streamkit \
106124

107125
# Note: the image defaults to `skit serve` (you can also pass it explicitly).
108126

127+
> [!CAUTION]
128+
> StreamKit ships with built-in authentication (auto-enabled on non-loopback binds, including Docker’s `0.0.0.0`).
129+
> If you see the login page, fetch the bootstrap admin token with:
130+
>
131+
> ```bash
132+
> docker exec streamkit skit auth print-admin-token
133+
> ```
134+
>
135+
> The default token path inside the container is `/opt/streamkit/.streamkit/auth/admin.token`.
136+
> Mount `/opt/streamkit/.streamkit` (or set `[auth].state_dir`) if you want the auth state persisted across restarts.
137+
>
138+
> Linux-only (frictionless demo): run with host networking and bind to loopback inside the container to keep auth disabled in `auth.mode=auto`:
139+
>
140+
> ```bash
141+
> docker run --rm -d --name streamkit \
142+
> --network host \
143+
> -e SK_SERVER__ADDRESS=127.0.0.1:4545 \
144+
> -v $(pwd)/models:/opt/streamkit/models:ro \
145+
> -v $(pwd)/.plugins:/opt/streamkit/plugins:ro \
146+
> streamkit:latest
147+
> ```
148+
109149
# Open http://localhost:4545 in your browser
110150
# To stop: docker stop streamkit
111151
```

README.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ If you try it and something feels off, please open an issue (or a small PR). For
8888
The fastest way to get started is using pre-built Docker images from GitHub Container Registry (GHCR). The image serves the web UI and includes sample pipelines.
8989

9090
> [!CAUTION]
91-
> StreamKit does not currently implement authentication. Do not expose it directly to the public internet. Bind to localhost (recommended) or put it behind an authenticating reverse proxy and a trusted role header. See <https://streamkit.dev/guides/security/>.
91+
> StreamKit ships with built-in authentication (auto-enabled on non-loopback binds). If you see the login page, run `skit auth print-admin-token` and paste the token; admins can mint additional tokens in **Admin → Access Tokens**. Do not disable auth when exposing it beyond localhost; see <https://streamkit.dev/guides/authentication/> and <https://streamkit.dev/guides/security/>.
9292
9393
> [!NOTE]
9494
> Official Docker images are published for `linux/amd64` (x86_64). On ARM hosts (Raspberry Pi, Apple Silicon, etc.), use “Build from Source” or run with amd64 emulation.
@@ -111,12 +111,30 @@ docker run --rm \
111111
The `:latest-demo` image bundles core plugins plus the models needed by the shipped sample pipelines (much larger image; intended for demos/evaluation, not production).
112112

113113
```bash
114-
docker run --rm \
114+
docker run --rm --name streamkit-demo \
115115
-p 127.0.0.1:4545:4545/tcp \
116116
-p 127.0.0.1:4545:4545/udp \
117117
ghcr.io/streamer45/streamkit:latest-demo
118118
```
119119

120+
> [!NOTE]
121+
> In Docker, StreamKit binds to `0.0.0.0` inside the container so published ports work. With `auth.mode=auto`, this means built-in auth is enabled by default.
122+
> To log in, print the bootstrap admin token and paste it into `http://localhost:4545/login`:
123+
>
124+
> ```bash
125+
> docker exec streamkit-demo skit auth print-admin-token --raw
126+
> ```
127+
128+
> [!NOTE]
129+
> Linux-only (no login): run with host networking and bind to loopback inside the container to keep auth disabled in `auth.mode=auto`:
130+
>
131+
> ```bash
132+
> docker run --rm --name streamkit-demo \
133+
> --network host \
134+
> -e SK_SERVER__ADDRESS=127.0.0.1:4545 \
135+
> ghcr.io/streamer45/streamkit:latest-demo
136+
> ```
137+
120138
If you want the OpenAI-powered sample pipelines, pass `OPENAI_API_KEY` without putting it directly in the command:
121139
122140
```bash

REUSE.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ SPDX-License-Identifier = "MPL-2.0"
8686
[[annotations]]
8787
path = [
8888
"target/**",
89+
".streamkit/**",
8990
"node_modules/**",
9091
"dist/**",
9192
"build/**",

ROADMAP.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ These are in place today and will be iterated on (not “added from scratch”):
3838
- **Playwright E2E** + CI workflow (expand coverage over time)
3939
- **Load testing runner + presets** (curate canonical scenarios + track budgets)
4040
- **Observability baseline** (logs + OTLP metrics/traces + profiling helpers)
41-
- **RBAC permissions model** (roles + allowlists), even though authentication is not yet implemented
41+
- **RBAC + built-in auth foundation** (roles/allowlists + JWT auth), with secure-by-default behavior on non-loopback binds
4242

4343
## Near-Term (v0.1 → v0.5)
4444

apps/skit/Cargo.toml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ tokio-stream = "0.1"
5454
hyper = { version = "1.8", features = ["full"] }
5555
axum-server = { version = "0.8", features = ["tls-rustls"] }
5656
rustls = { version = "0.23", features = ["ring"] }
57+
reqwest = { version = "0.12", features = ["multipart", "json"] }
5758
bytes = { workspace = true }
5859
futures = { workspace = true }
5960
uuid = { version = "1.19", features = ["v4", "serde"] }
@@ -113,6 +114,17 @@ async-trait = { workspace = true }
113114
# For glob pattern matching in permissions
114115
glob = "0.3"
115116

117+
# For built-in authentication
118+
jsonwebtoken = { version = "10.2.0", default-features = false, features = ["aws_lc_rs"] }
119+
sha2 = "0.10"
120+
hex = "0.4"
121+
base64 = "0.22"
122+
thiserror = "2.0"
123+
getrandom = "0.3"
124+
aws-lc-rs = "1"
125+
126+
# For MoQ auth path matching (optional, with moq feature)
127+
moq-lite = { version = "0.10", optional = true }
116128

117129
[features]
118130
default = ["script"]
@@ -121,12 +133,11 @@ profiling = ["dep:pprof", "dep:tikv-jemallocator", "dep:jemalloc_pprof"]
121133
# DHAT allocation profiling - tracks allocation counts/rates (mutually exclusive with profiling)
122134
# Use this to find hot allocation sites. Output is written on graceful shutdown.
123135
dhat-heap = ["dep:dhat"]
124-
moq = ["dep:moq-native"]
136+
moq = ["dep:moq-native", "dep:moq-lite"]
125137
script = ["streamkit-nodes/script", "streamkit-engine/script"]
126138

127139
[dev-dependencies]
128140
tokio-test = "0.4"
129-
reqwest = { version = "0.12", features = ["multipart", "json"] }
130141
tokio-tungstenite = "0.28"
131142
futures-util = "0.3"
132143
ogg = "0.9.2"

0 commit comments

Comments
 (0)