chore: public-readiness P0 — CORS/WS lockdown, NTC rename, action pinning, badge casing#6
Open
chore: public-readiness P0 — CORS/WS lockdown, NTC rename, action pinning, badge casing#6
Conversation
3 tasks
Replace `@master` references with immutable tags to eliminate the supply-chain risk of an upstream branch getting rewritten between runs. - aquasecurity/trivy-action: master → v0.35.0 - tim-actions/dco: master → v1.1.0 Both were flagged by the public-readiness audit as the only unpinned third-party actions in the workflow tree. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: RCC Bot <rcc@localhost>
The Flutter app still carried identifiers from the project's earlier name
(NTC). These are the last rename leftovers — a first-time public visitor
sees the root widget class, the package description, and terminal theme
on `grep` within seconds, and an inconsistent name reads as abandoned.
Renamed:
- NtcApp / _NtcAppState → OpendrayApp / _OpendrayAppState (app.dart, main.dart)
- ntcTerminalTheme → opendrayTerminalTheme (terminal_theme.dart + usage in session_page.dart)
- window.__ntcFontInstalled → window.__opendrayFontInstalled (preview_page.dart JS interop)
Also replaced the placeholder pubspec description ("A new Flutter project.")
with the actual product tagline.
No behavioural change. Purely cosmetic.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: RCC Bot <rcc@localhost>
GitHub redirects lower-case org slugs to the canonical form, but the README had a mix of `opendray/opendray` (badges, clone URL, discussions link) and `Opendray/opendray` (install script, releases links). Badges in particular render more reliably when they hit the canonical slug on the first request. Purely a docs/url change — no Go import paths touched (the module path `github.com/opendray/opendray` is intentionally lowercase and stays so). Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: RCC Bot <rcc@localhost>
Both `corsMiddleware` (in gateway/server.go) and the package-level
gorilla/websocket `upgrader` (gateway/ws.go) were wide open — `Access-
Control-Allow-Origin: *` unconditionally, and `CheckOrigin` always
returning true. For a self-hosted tool whose PTY endpoints are root-
equivalent, the safe default is the other way round: block cross-origin
by default, opt in explicitly.
The fix introduces a single `originPolicy` (gateway/origins.go) that
drives both CORS header stamping and WebSocket origin validation off
the same allowlist. Populated from the new `ALLOWED_ORIGINS` env var
(comma-separated) in cmd/opendray/main.go.
Behaviour:
- empty → same-origin only. No Allow-Origin header stamped;
WS CheckOrigin falls back to Origin.host == Host.
Native mobile clients (no Origin header) always
pass, unchanged.
- "*" → wildcard. Logged loudly at startup so operators
see they've opted out.
- a,b,c → exact-match allowlist. Allow-Origin echoes the
matched value; WS CheckOrigin accepts the entry.
The four WS call sites (ws.go, logs.go, tasks_handlers.go,
simulator_stream.go) now share the Server-scoped upgrader so policy is
consistently enforced across every PTY, tail, task, and simulator
stream.
Setup mode (gateway.NewSetup) uses its own empty policy — the wizard is
served from the same binary and never speaks cross-origin.
Tests: gateway/origins_test.go covers allowlist matching (including
trailing-slash normalisation and blank-entry tolerance), wildcard
behaviour, same-origin fallback for WS, OPTIONS preflight short-
circuit, and the "browser, not server, enforces CORS" contract —
disallowed origins still reach the handler, they just miss the
Allow-Origin header and get blocked in the browser.
README.md documents `ALLOWED_ORIGINS` in the Key variables table;
.env.example explains the three forms with concrete examples,
including the `make dev` snippet.
Pre-existing kernel/config test failures in this environment are
unrelated (host shell has DB_HOST / LISTEN_ADDR exported from an
adjacent sandbox) — they also fail on main without these changes.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: RCC Bot <rcc@localhost>
….1.0 v1.1.0 of the action ships a breaking input-schema change — it requires `commits:` and no longer accepts `token:`, which is what this workflow was written against. The previous `@master` reference happened to work because master is still on the older API. Pin to the current master SHA (f2279e6) so we get reproducible, supply-chain-hardened behaviour without the tag-swap surprise. If and when the maintainer cuts a v1.2.x that re-adds `token:` we can migrate. Introduced in c0ff78f. Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: RCC Bot <rcc@localhost>
Adds three organised badge rows plus a live star-history chart so
visitors landing on the repo see a real-time picture of project
health, community traction, and adoption.
Rows:
- Build & release: CI, CodeQL, Coverage, Release, License
- Community: Stars, Forks, Watchers (social-style for prominence)
- Project health: Downloads, Contributors, Last commit, Open issues,
Open PRs, Discussions
The Star History section uses star-history.com's SVG embed with a
`<picture>` element so it respects the viewer's light/dark-mode
preference. All badge images are served via shields.io / star-history —
no tracking pixels, no third-party JS, safe for GitHub's markdown
sandbox.
Pure README change. No code, no behaviour, no dependencies touched.
Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: RCC Bot <rcc@localhost>
5dc8a4c to
d085bb2
Compare
7 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Batch of four small, independent changes from the public-readiness audit (P0 items from the enterprise-architect review). All four are what I'd want to land before flipping the repo public — they either close a security footgun, fix a cosmetic "weekend project" signal, or shore up supply-chain hygiene.
Commits (reviewable top-down, each stands alone)
chore(ci): pin trivy-action and tim-actions/dco to tagged releases— eliminates the@mastersupply-chain risk. trivy-action →v0.35.0, dco → SHA-pinned to master (see fix commite72a5dd, v1.1.0 was incompatible).refactor(app): rename leftover NTC identifiers to OpenDray—NtcApp→OpendrayApp,ntcTerminalTheme→opendrayTerminalTheme,__ntcFontInstalled→__opendrayFontInstalled, andpubspec.yamldescription swapped from the default"A new Flutter project."to the real product tagline. No behavioural change.docs(readme): normalize org casing to Opendray/opendray— badges, clone URL, discussions link now all use the canonical org slug. Go module path (github.com/opendray/opendray) is untouched.feat(security): configurable CORS + WebSocket origin allowlist— the substantive one. Replaces wide-openAccess-Control-Allow-Origin: *andCheckOrigin: return truewith a singleoriginPolicydriven byALLOWED_ORIGINSenv var. Safe default is same-origin only;*still available but logged loudly; comma-separated allowlist supported. Five unit tests ingateway/origins_test.gocover matching, wildcard, same-origin fallback, OPTIONS preflight, and the browser-enforces-not-server contract.fix(ci): pin tim-actions/dco to master SHA instead of incompatible v1.1.0— follow-up fix; v1.1.0 broke the DCO workflow because its input schema diverged from master's.Behaviour change & migration
Only #4 has externally observable behaviour:
Origin; they pass every code path.make dev(Flutter devserver on:5000→ Go on:8640): now needsALLOWED_ORIGINS=http://localhost:5000. Documented in.env.example.Originto match the user-facing host; otherwise setALLOWED_ORIGINS=https://your.public.host.*: setALLOWED_ORIGINS=*to keep existing behaviour (server logs a warning at startup).Known failing checks (pre-existing on
main, NOT caused by this PR)Two checks will continue to fail on this PR regardless of changes because they're broken on
main:Backend (Go)—TestRunner_EchoSucceeds: flaky test with a race ingateway/tasks/runner_test.gooutput-drain logic. Same failure appears on thefeat: enterprise hardeningcommit on main. Worth a separategood first issue— the fix is ~10 lines.Analyze Go(CodeQL): has failed on every recent CI run across all branches (5/5 recent). The autobuild step hitsRunning /usr/bin/make failed, continuing anyway; something downstream produces "configuration error" with zero diagnostics. Needs separate investigation.Verified by checking
gh run listhistory — both were red before this PR was opened. Happy to open follow-up issues for both if you want.Test plan
go build ./...cleango vet ./...cleango test -race -count=1 ./gateway/...clean (new origin-policy tests pass;TestRunner_EchoSucceedspasses 3/3 locally — it's a CI-specific race)make devwithALLOWED_ORIGINS=http://localhost:5000— Flutter devserver can still reach the Go backendcurl -H "Origin: https://evil.example"against a running instance should receive noAccess-Control-Allow-OriginheaderNot in this PR (deferred)
kernel/store,kernel/terminal,kernel/auth,cmd/opendray.docs/plugin-authoring.md,docs/architecture.md,docs/deployment.md..golangci.yml,.editorconfig.Merge strategy recommendation
Rebase and merge — each commit has a distinct conventional-commit prefix that release-please parses into CHANGELOG entries. Squashing would flatten five meaningful entries into one.
🤖 Generated with Claude Code