mirror of
https://github.com/sotashimozono/obsidian-remote-ssh.git
synced 2026-07-22 06:52:07 +00:00
chore: add LICENSE + SECURITY.md + CONTRIBUTING.md (0.4.58)
OSS hygiene baseline. Three new repo-root files; no source code touched. - **LICENSE** (MIT) — declared in package.json since day one but the file itself was missing. Required for community-store registry submission (#126 Phase H), required by GitHub's "is this project licensed?" detection, required by Dependabot's license-compatibility check. - **SECURITY.md** — vulnerability disclosure policy. The plugin handles SSH credentials and auto-deploys a remote daemon, so the attack surface is non-trivial and a clear "open a private Security Advisory, not a public issue" instruction matters. Documents the existing cosign verification command (D-δ.2 / F24 / #122) and the runtime sha256 verify (D-δ.1 / F23 / #121). - **CONTRIBUTING.md** — dev setup, branch naming, Conventional Commits format (already enforced by commitlint #111), version- bump dance, where each kind of decision lives in `docs/`. Mirrors the conventions every recent merged PR has followed, so the doc captures lived practice rather than aspirational rules. Code of Conduct intentionally omitted at this stage — single- author repo, will revisit if external contributions accumulate. README is touched in a separate uncommitted edit (souta is working on it in the IDE) and stays out of this PR. Verification: - All three files render on GitHub's repo-root rendering conventions (LICENSE picked up automatically by the "License: MIT" header; SECURITY.md surfaces a "Report a vulnerability" button; CONTRIBUTING.md surfaces in the PR template). - No code change → no test surface impacted; existing 569 tests still green by virtue of not touching anything. manifest/package/versions bumped 0.4.57 → 0.4.58. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
cdc66d27b7
commit
b6a5d735d0
7 changed files with 236 additions and 5 deletions
134
CONTRIBUTING.md
Normal file
134
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
# Contributing
|
||||
|
||||
Thanks for your interest. The project is built around a few hard
|
||||
conventions that make the contribution loop predictable. Please read
|
||||
this once before opening your first PR.
|
||||
|
||||
## Repository layout
|
||||
|
||||
```
|
||||
plugin/ Obsidian plugin (TypeScript, esbuild, vitest)
|
||||
server/ obsidian-remote-server daemon (Go, fsnotify)
|
||||
proto/ Shared JSON-RPC method + error definitions (TS + Go in lockstep)
|
||||
docs/ Architecture notes (shadow vault, perf, testing strategy, …)
|
||||
deploy/ Turn-key sshd container (Docker compose) for trying the plugin
|
||||
docker/ Test-only sshd container for the integration suite
|
||||
```
|
||||
|
||||
See [README.md](README.md) for the user-facing story.
|
||||
|
||||
## Dev setup
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- **Node.js 20+** for the plugin (`plugin/package.json`)
|
||||
- **Go 1.25+** for the daemon (`server/go.mod`'s `go` directive)
|
||||
- **Docker** for the integration test suite (optional for plugin-only changes)
|
||||
|
||||
```bash
|
||||
# Plugin
|
||||
cd plugin
|
||||
npm ci
|
||||
npm test # ~570 unit tests, ~3 s
|
||||
npx tsc --noEmit # type-check
|
||||
npm run dev # esbuild watch into <plugin>/main.js
|
||||
|
||||
# Server
|
||||
cd server
|
||||
make build # builds bin/obsidian-remote-server (host platform)
|
||||
make cross # builds 4 platforms into dist/
|
||||
go test ./...
|
||||
|
||||
# Full integration (Docker required)
|
||||
cd plugin
|
||||
npm run sshd:start
|
||||
npm run test:integration
|
||||
npm run sshd:stop
|
||||
|
||||
# Plugin-side perf bench (separate from `test:integration`)
|
||||
npm run test:integration:bench
|
||||
```
|
||||
|
||||
A working dev vault path can be configured via `REMOTE_SSH_DEV_VAULT`
|
||||
env var; `npm run build:full` then ships the plugin into that vault.
|
||||
|
||||
## Branch + commit convention
|
||||
|
||||
### Branches
|
||||
|
||||
- `feat/<short-name>` — new feature
|
||||
- `fix/<short-name>` — bug fix
|
||||
- `chore/<short-name>` — repo hygiene, dependency bumps, refactors with no user-visible change
|
||||
- `docs/<short-name>` — documentation-only changes
|
||||
|
||||
One branch = one PR = one logical change. We squash-merge from main, so the branch's commits don't need to be pristine — but the PR title and body **do**.
|
||||
|
||||
### Commit messages — Conventional Commits, enforced
|
||||
|
||||
Format: `type(scope): subject`
|
||||
|
||||
```
|
||||
feat(plugin): Phase D-γ / F18 — error toast taxonomy + Notice / log integration (0.4.51)
|
||||
fix(server): unbreak Go + Dockerfile after Dependabot rollups (0.4.52)
|
||||
ci(release): grouped CHANGELOG via git-cliff (0.4.57)
|
||||
```
|
||||
|
||||
- `type` ∈ `build` `chore` `ci` `docs` `feat` `fix` `perf` `refactor` `revert` `style` `test` `release`
|
||||
- `scope` is free-form; common scopes: `plugin`, `server`, `proto`, `deploy`, `ci`, `release`, `security`.
|
||||
- Subject can mix cases (`Phase D-γ` is fine; commitlint's `subject-case` is intentionally relaxed — see [`commitlint.config.mjs`](commitlint.config.mjs)).
|
||||
- Header cap is **144 characters** (the standard 100 doesn't fit our `Phase X.Y — long subject (0.4.NN)` style).
|
||||
- The `(0.4.NN)` suffix matches the version bump (see below).
|
||||
- A trailing `Co-Authored-By:` line is fine; it's stripped from the auto-generated changelog (`cliff.toml` `commit_preprocessors`).
|
||||
|
||||
The `commitlint.yml` workflow checks every commit in the PR. A typo in commit #3 of a 5-commit PR fails the gate; please fix in-place + force-push rather than tacking on a `fix typo` commit.
|
||||
|
||||
### Version bumps
|
||||
|
||||
`plugin/manifest.json`, `plugin/package.json`, and `plugin/versions.json` move together. Use the project's npm `version` script to bump all three at once:
|
||||
|
||||
```bash
|
||||
cd plugin
|
||||
npm version patch --no-git-tag-version # 0.4.57 → 0.4.58
|
||||
# (or `minor` / `major` / a literal `0.5.0`)
|
||||
```
|
||||
|
||||
Then commit the four files alongside your code change in a single commit.
|
||||
|
||||
`version-check.yml` rejects any PR whose `manifest.json` version isn't strictly greater than the base branch's. If your PR sits open while another bumps main, rebase + bump again.
|
||||
|
||||
## Pull request etiquette
|
||||
|
||||
- Reuse [`.github/pull_request_template.md`](.github/pull_request_template.md) — the prompts are there for a reason.
|
||||
- Add a **Test plan** checklist; mark each item once it actually passed locally.
|
||||
- Run `npx tsc --noEmit -p tsconfig.json` and `npx vitest run` before pushing — CI runs them anyway, but the feedback loop is faster locally.
|
||||
- For server changes, also run `go test ./...` from `server/`.
|
||||
- Stack PRs are welcome — open the dependent PR with `--base <prior-branch>`. Once the prior merges, GitHub auto-rebases the dependent PR's base to `main`.
|
||||
|
||||
## Where things live
|
||||
|
||||
- **Architecture decisions** → `docs/architecture-*.md`. The shadow-vault rationale (and why the prior `reconcileFile` route was abandoned) is in `docs/architecture-shadow-vault.md`.
|
||||
- **Test strategy** → `docs/testing-strategy.md`. Phase A (multi-client convergence), B (multi-OS), C (sync-latency + UI reflect) are codified there.
|
||||
- **Performance numbers** → the `perf-baseline` orphan branch's `baseline.ndjson`, refreshed nightly by `bench.yml`.
|
||||
- **Issue tracker** → for bug reports, feature requests, design questions.
|
||||
- **Security issues** → see [SECURITY.md](SECURITY.md), **not** the public issue tracker.
|
||||
|
||||
## Code style
|
||||
|
||||
- TypeScript: `strictNullChecks: true`, `isolatedModules: true`. No ESLint config required for now (was scoped out as low-value during early development).
|
||||
- Go: `gofmt -w .` (the `gosec` job in `security.yml` will flag obvious issues).
|
||||
- Comments: explain **why**, not what. The codebase prefers a few generous block comments at module / class boundaries over per-line noise.
|
||||
- New tests should mirror the surface they cover: `src/util/Foo.ts` ↔ `tests/Foo.test.ts`.
|
||||
|
||||
## Releases
|
||||
|
||||
Tagged releases (`X.Y.Z` format) trigger `.github/workflows/release.yml`:
|
||||
|
||||
1. Test gate (typecheck + vitest)
|
||||
2. Server-binary build × 4 platforms + cosign keyless sign
|
||||
3. Plugin bundle build + bundle-size check
|
||||
4. Grouped changelog generated by `git-cliff` (`cliff.toml`)
|
||||
5. GitHub Release created with all artefacts attached
|
||||
|
||||
You don't usually create releases by hand; `release-on-merge.yml` watches main for `manifest.json` version changes and auto-tags.
|
||||
|
||||
Thanks again — and welcome.
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2026 Souta Shimozono
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
75
SECURITY.md
Normal file
75
SECURITY.md
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
# Security Policy
|
||||
|
||||
## Reporting a vulnerability
|
||||
|
||||
**Please do not open a public GitHub issue for security bugs.**
|
||||
|
||||
This project handles SSH credentials and ships an auto-deployed
|
||||
remote daemon — the attack surface is non-trivial. Responsible
|
||||
disclosure helps us patch + release before the issue is public.
|
||||
|
||||
To report a vulnerability:
|
||||
|
||||
1. Open a **private GitHub Security Advisory** at
|
||||
<https://github.com/sotashimozono/obsidian-remote-ssh/security/advisories/new>.
|
||||
2. Include: a minimal reproduction, the affected version, your
|
||||
suggested severity (low / medium / high / critical), and any
|
||||
suggested fix or mitigation.
|
||||
|
||||
## Response timeline
|
||||
|
||||
- **Acknowledgement**: within 7 days.
|
||||
- **Triage + initial assessment**: within 14 days of acknowledgement.
|
||||
- **Fix availability** (in main + the next release): depends on
|
||||
severity and complexity. Critical issues we aim for ≤ 14 days
|
||||
after triage; lower-severity issues land on the normal release
|
||||
cadence.
|
||||
- **Public disclosure**: coordinated with the reporter, typically
|
||||
after a fixed release ships.
|
||||
|
||||
## What's in scope
|
||||
|
||||
- The Obsidian plugin code (`plugin/src/**`).
|
||||
- The Go daemon (`server/**`) running on the user's remote SSH host.
|
||||
- The shared protocol (`plugin/src/proto/types.ts` ↔
|
||||
`server/internal/proto/types.go`).
|
||||
- Release artefacts (signed daemon binaries, plugin bundle).
|
||||
- CI workflows, especially anything touching `secrets.*`.
|
||||
|
||||
## What's out of scope
|
||||
|
||||
- Vulnerabilities in upstream dependencies (`ssh2`, `fsnotify`,
|
||||
Obsidian itself, etc.) — please report those upstream and CC us
|
||||
if our usage is implicated.
|
||||
- Configuration mistakes by the operator (e.g. running the daemon
|
||||
as root, exposing the SSH host on a public IP without auth) —
|
||||
unless the plugin actively encourages or facilitates the misuse.
|
||||
- Social-engineering scenarios where the user explicitly accepts a
|
||||
prompt that surfaces the risk (e.g. trusting a host-key change
|
||||
in the upcoming `HostKeyMismatchModal` — we surface the diff and
|
||||
the security implication; the user's choice to trust is theirs).
|
||||
|
||||
## Verifying release artefacts
|
||||
|
||||
Daemon binaries shipped via GitHub Releases are signed with
|
||||
[Sigstore cosign](https://www.sigstore.dev/) keyless OIDC against
|
||||
this repository's GitHub Actions identity. Verify any release
|
||||
binary independently with:
|
||||
|
||||
```bash
|
||||
cosign verify-blob \
|
||||
--bundle obsidian-remote-server-linux-amd64.bundle \
|
||||
--certificate-identity-regexp 'https://github.com/sotashimozono/obsidian-remote-ssh/.github/workflows/release.yml@.*' \
|
||||
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
|
||||
obsidian-remote-server-linux-amd64
|
||||
```
|
||||
|
||||
The plugin's `ServerDeployer` performs a sha256 round-trip
|
||||
verification on every deploy (`plugin/src/transport/ServerDeployer.ts`
|
||||
`verifyRemoteSha256`). A mismatch refuses to start the daemon.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
We appreciate every responsible disclosure. Reporters are credited
|
||||
in the security advisory once the issue is publicly disclosed,
|
||||
unless they prefer to remain anonymous.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "remote-ssh",
|
||||
"name": "Remote SSH",
|
||||
"version": "0.4.57",
|
||||
"version": "0.4.58",
|
||||
"minAppVersion": "1.4.0",
|
||||
"description": "Edit remote vaults over SSH/SFTP — VS Code Remote SSH for Obsidian",
|
||||
"author": "",
|
||||
|
|
|
|||
4
plugin/package-lock.json
generated
4
plugin/package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "obsidian-remote-ssh",
|
||||
"version": "0.4.57",
|
||||
"version": "0.4.58",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "obsidian-remote-ssh",
|
||||
"version": "0.4.57",
|
||||
"version": "0.4.58",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ssh2": "^1.17.0"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "obsidian-remote-ssh",
|
||||
"version": "0.4.57",
|
||||
"version": "0.4.58",
|
||||
"description": "VS Code Remote SSH-like experience for Obsidian",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -61,5 +61,6 @@
|
|||
"0.4.54": "1.4.0",
|
||||
"0.4.55": "1.4.0",
|
||||
"0.4.56": "1.4.0",
|
||||
"0.4.57": "1.4.0"
|
||||
"0.4.57": "1.4.0",
|
||||
"0.4.58": "1.4.0"
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue